-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.sh
More file actions
executable file
·277 lines (221 loc) · 8.89 KB
/
main.sh
File metadata and controls
executable file
·277 lines (221 loc) · 8.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#!/usr/bin/env bash
# Build Debian RISC-V image (Single Partition Scheme: /boot inside root filesystem)
# Suitable for devices supporting ext4 boot (e.g., Orange Pi RV2 + U-Boot)
set -euo pipefail
# --- User Configurable Variables ---
MODEL=${MODEL:-orangepi-rv2}
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
ROOT_IMG=debian-${MODEL}-${TIMESTAMP}.img
DIST="trixie"
BOARD="orangepi-rv2"
BASE_TOOLS="binutils file tree sudo bash-completion u-boot-menu initramfs-tools openssh-server network-manager dnsmasq-base libpam-systemd ppp wireless-regdb wpasupplicant libengine-pkcs11-openssl iptables systemd-timesyncd vim usbutils libgles2 parted pciutils wget"
CHROOT_TARGET="rootfs"
# --- Function Definitions ---
machine_info() {
echo "--- Display Build Environment Information ---"
uname -a
echo "CPU Cores: $(nproc)"
lscpu
whoami
env | head -n 10
fdisk -l | head -n 20
df -h
echo "--------------------------"
}
init() {
echo "--- 1. Initialize Environment and Image File ---"
mkdir -p rootfs
apt update
echo "Creating 8GB image file: $ROOT_IMG"
fallocate -l 8G "$ROOT_IMG"
}
install_deps() {
echo "--- 2. Install Build Dependencies ---"
# Add debootstrap and e2fsprogs to ensure blkid is available
apt install -y gdisk dosfstools g++-12-riscv64-linux-gnu build-essential \
libncurses-dev gawk flex bison openssl libssl-dev \
dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf mkbootimg \
fakeroot genext2fs genisoimage libconfuse-dev mtd-utils mtools qemu-utils squashfs-tools \
device-tree-compiler rauc u-boot-tools f2fs-tools swig mmdebstrap parted \
binfmt-support qemu-user-static curl wget kpartx debootstrap e2fsprogs
}
qemu_setup() {
echo "--- 3. Set up QEMU (for chroot into riscv64 environment) ---"
update-binfmts --display
}
# --- Revised img_setup: Get and save partition UUID ---
img_setup() {
echo "--- 4. Create Single Partition (ext4) and Mount ---"
# Dynamically assign loop device
DEVICE=$(losetup --find --show "$ROOT_IMG")
echo "Image linked to loop device: $DEVICE"
# Create a single ext4 partition (filling 100%)
parted -s -a optimal -- "$DEVICE" mktable msdos
parted -s -a optimal -- "$DEVICE" mkpart primary ext4 0% 100%
# Reread partition table
partprobe "$DEVICE" || blockdev --rereadpt "$DEVICE" || true
sleep 2
# Use kpartx to create partition mappings
kpartx -av "$DEVICE" >/dev/null
DEVBASE=$(basename "$DEVICE")
ROOT_PART="/dev/mapper/${DEVBASE}p1"
# Wait for device to appear
for i in {1..10}; do
if [ -b "$ROOT_PART" ]; then
break
fi
sleep 1
done
if [ ! -b "$ROOT_PART" ]; then
echo "Error: Failed to create root partition device!" >&2
kpartx -dv "$DEVICE" >/dev/null || true
losetup -d "$DEVICE" 2>/dev/null || true
exit 1
fi
# Format as ext4 with label debian-root
mkfs.ext4 -F -L debian-root "$ROOT_PART"
# Crucial modification: Get partition UUID
ROOT_UUID=$(blkid -s UUID -o value "$ROOT_PART")
if [ -z "$ROOT_UUID" ]; then
echo "Error: Failed to get root partition UUID!" >&2
exit 1
fi
echo "Root Partition UUID: $ROOT_UUID"
echo "$ROOT_UUID" > /tmp/.root_uuid
# Mount to rootfs
mount "$ROOT_PART" rootfs
if ! mountpoint -q rootfs; then
echo "Error: Failed to mount root partition!" >&2
kpartx -dv "$DEVICE" >/dev/null || true
losetup -d "$DEVICE" 2>/dev/null || true
exit 1
fi
echo "Root partition mounted successfully: $ROOT_PART"
echo "$DEVICE" > /tmp/.build_device
}
make_rootfs() {
echo "--- 5. Build Root Filesystem using debootstrap ---"
sudo debootstrap --arch=riscv64 --no-check-gpg "${DIST}" "$CHROOT_TARGET" http://mirrors.tuna.tsinghua.edu.cn/debian
}
# --- Final revised after_mkrootfs: Handle UUID and orangepiEnv.txt ---
after_mkrootfs() {
echo "--- 6. Configure System via chroot ---"
if ! mountpoint -q "$CHROOT_TARGET"; then
echo "Error: Root partition is not mounted!" >&2
exit 1
fi
ROOT_UUID=$(cat /tmp/.root_uuid)
# Key fix 1: fstab uses UUID
cat > "$CHROOT_TARGET/etc/fstab" << EOF
UUID=${ROOT_UUID} / ext4 defaults,noatime 0 1
EOF
# Copy qemu-riscv64-static to the chroot environment
cp /usr/bin/qemu-riscv64-static "$CHROOT_TARGET/usr/bin/"
# chroot configuration
sudo chroot "$CHROOT_TARGET" /bin/bash << 'EOF_CHROOT'
set -euo pipefail
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
apt update
# Ensure e2fsprogs (includes blkid) and u-boot-menu are installed
apt install -y --no-install-recommends binutils file tree sudo bash-completion u-boot-menu initramfs-tools openssh-server network-manager dnsmasq-base libpam-systemd ppp wireless-regdb wpasupplicant libengine-pkcs11-openssl iptables systemd-timesyncd vim usbutils libgles2 parted pciutils wget initramfs-tools e2fsprogs
# Key fix 2: Run u-boot-update
u-boot-update
# --- User Configuration ---
useradd -m -s /bin/bash -G adm,sudo,audio debian
echo 'debian:debian' | chpasswd
echo debian > /etc/hostname
echo 127.0.1.1 debian >> /etc/hosts
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone
exit
EOF_CHROOT
# Clean up qemu-riscv64-static
rm -f "$CHROOT_TARGET/usr/bin/qemu-riscv64-static"
echo "$TIMESTAMP" > "$CHROOT_TARGET/etc/debian-release"
cat > "$CHROOT_TARGET/etc/apt/sources.list" << EOF
deb https://ports.debian.org/debian-ports/ trixie main contrib non-free non-free-firmware
EOF
# Clean up SSH keys
rm -f "$CHROOT_TARGET"/etc/ssh/ssh_host_*
# Create /boot directory (if it doesn't exist)
mkdir -p "$CHROOT_TARGET/boot"
# Copy boot files (kernel, dtb, etc.)
if [ -d ./boot ]; then
echo "Copying boot files to /boot..."
# Use -a to preserve permissions and symlinks
cp -arv ./boot/* "$CHROOT_TARGET/boot/"
else
echo "Warning: ./boot directory not found, skipping bootloader/kernel copy."
fi
# --- Key fix 3: Replace UUID in orangepiEnv.txt ---
ORANGEPI_ENV_FILE="$CHROOT_TARGET/boot/orangepiEnv.txt"
if [ -f "$ORANGEPI_ENV_FILE" ]; then
echo "--- Fixing rootdev UUID in orangepiEnv.txt ---"
# Use sed to replace any UUID format string after rootdev=UUID=
sed -i "s/rootdev=UUID=[0-9a-fA-F-]*/rootdev=UUID=${ROOT_UUID}/g" "$ORANGEPI_ENV_FILE"
# Verify if replacement was successful
echo "Verifying rootdev in orangepiEnv.txt:"
grep "rootdev" "$ORANGEPI_ENV_FILE"
else
echo "Warning: Orange Pi U-Boot environment file (${ORANGEPI_ENV_FILE}) not found, skipping UUID replacement."
fi
# --------------------------------------------------
# Clean up apt cache
rm -rf "$CHROOT_TARGET"/var/lib/apt/lists/*
# Sync and unmount
sync
sleep 2
umount "$CHROOT_TARGET" || true
# Clean up kpartx and UUID file
DEVICE=$(cat /tmp/.build_device)
kpartx -dv "$DEVICE" >/dev/null || true
rm -f /tmp/.build_device /tmp/.root_uuid
}
# --- Main Execution Flow ---
machine_info
init
install_deps
qemu_setup
img_setup
make_rootfs
after_mkrootfs
# --- 7. Mount Image and Print U-Boot Boot Configuration ---
echo "--- 7. Mount Image and Print U-Boot Boot Configuration ---"
DEVICE=$(losetup -f --show "$ROOT_IMG")
kpartx -av "$DEVICE" >/dev/null
DEVBASE=$(basename "$DEVICE")
ROOT_PART="/dev/mapper/${DEVBASE}p1"
# Re-mount root partition
mkdir -p /mnt/temp_root
mount "$ROOT_PART" /mnt/temp_root
BOOT_SCRIPT_FILE="/mnt/temp_root/boot/boot.scr"
if [ -f "$BOOT_SCRIPT_FILE" ]; then
echo "✅ Found U-Boot boot script file: ${BOOT_SCRIPT_FILE}"
# u-boot-menu usually generates a text file /boot/boot.cmd, then compiles it into boot.scr
BOOT_CMD_FILE="/mnt/temp_root/boot/boot.cmd"
if [ -f "$BOOT_CMD_FILE" ]; then
echo "--- Original U-Boot Boot Command File (${BOOT_CMD_FILE}) ---"
cat "$BOOT_CMD_FILE"
else
echo "Warning: Original U-Boot boot command file (/boot/boot.cmd) not found."
fi
# Print orangepiEnv.txt (file containing the new UUID)
ORANGEPI_ENV_FILE="/mnt/temp_root/boot/orangepiEnv.txt"
if [ -f "$ORANGEPI_ENV_FILE" ]; then
echo "--- orangepiEnv.txt (Orange Pi U-Boot Environment Configuration) ---"
cat "$ORANGEPI_ENV_FILE"
fi
echo "---------------------------------------------------------"
else
echo "Warning: U-Boot boot script file (boot.scr) not found in /boot directory."
fi
# Final Cleanup
sync
umount /mnt/temp_root || true
kpartx -dv "$DEVICE" >/dev/null || true
losetup -d "$DEVICE" 2>/dev/null || true
rmdir /mnt/temp_root 2>/dev/null || true
rm -f /tmp/.build_device 2>/dev/null || true
rm -f /tmp/.root_uuid 2>/dev/null || true
echo "✅ Image creation complete: ${ROOT_IMG}"
echo "💡 Please check the configurations printed above, ensure the 'rootdev' parameter correctly uses your new partition UUID."