Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fdc540f

Browse files
authored
Merge pull request #81 from shengwen-tw/switch_root
Support mounting rootfs from virtio-blk via initrd
2 parents 81e61bc + 762e4ed commit fdc540f

File tree

4 files changed

+224
-8
lines changed

4 files changed

+224
-8
lines changed

‎README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,56 @@ You can exit the emulator using: \<Ctrl-a x\>. (press Ctrl+A, leave it, afterwar
9090
An automated build script is provided to compile the RISC-V cross-compiler, Busybox, and Linux kernel from source.
9191
Please note that it only supports the Linux host environment.
9292

93+
To build everything, simply run:
94+
9395
```shell
9496
$ make build-image
9597
```
9698

99+
This command invokes the underlying script: `scripts/build-image.sh`, which also offers more flexible usage options.
100+
101+
### Script Usage
102+
103+
```
104+
./scripts/build-image.sh [--buildroot] [--linux] [--all] [--external-root] [--clean-build] [--help]
105+
106+
Options:
107+
--buildroot Build Buildroot rootfs
108+
--linux Build Linux kernel
109+
--all Build both Buildroot and Linux
110+
--external-root Use external rootfs instead of initramfs
111+
--clean-build Remove entire buildroot/ and/or linux/ directories before build
112+
--help Show this message
113+
```
114+
115+
### Examples
116+
117+
Build the Linux kernel only:
118+
119+
```
120+
$ scripts/build-image.sh --linux
121+
```
122+
123+
Build Buildroot only:
124+
125+
```
126+
$ scripts/build-image.sh --buildroot
127+
```
128+
129+
Build Buildroot and generate an external root file system (ext4 image):
130+
131+
```
132+
$ scripts/build-image.sh --buildroot --external-root
133+
```
134+
135+
Force a clean build:
136+
137+
```
138+
$ scripts/build-image.sh --all --clean-build
139+
$ scripts/build-image.sh --linux --clean-build
140+
$ scripts/build-image.sh --buildroot --clean-build
141+
```
142+
97143
## License
98144

99145
`semu` is released under the MIT License.

‎scripts/build-image.sh

Lines changed: 112 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,31 @@ function OK
1919

2020
PARALLEL="-j$(nproc)"
2121

22+
function safe_copy {
23+
local src="1ドル"
24+
local dst="2ドル"
25+
26+
if [ ! -f "$dst" ]; then
27+
echo "Copying $src -> $dst"
28+
cp -f "$src" "$dst"
29+
else
30+
echo "$dst already exists, skipping copy"
31+
fi
32+
}
33+
2234
function do_buildroot
2335
{
24-
ASSERT git clone https://github.com/buildroot/buildroot -b 2024年11月1日 --depth=1
25-
cp -f configs/buildroot.config buildroot/.config
26-
cp -f configs/busybox.config buildroot/busybox.config
36+
if [ ! -d buildroot ]; then
37+
echo "Cloning Buildroot..."
38+
ASSERT git clone https://github.com/buildroot/buildroot -b 2024年11月1日 --depth=1
39+
else
40+
echo "buildroot/ already exists, skipping clone"
41+
fi
42+
43+
safe_copy configs/buildroot.config buildroot/.config
44+
safe_copy configs/busybox.config buildroot/busybox.config
45+
cp -f target/init buildroot/fs/cpio/init
46+
2747
# Otherwise, the error below raises:
2848
# You seem to have the current working directory in your
2949
# LD_LIBRARY_PATH environment variable. This doesn't work.
@@ -32,13 +52,28 @@ function do_buildroot
3252
ASSERT make olddefconfig
3353
ASSERT make $PARALLEL
3454
popd
35-
cp -f buildroot/output/images/rootfs.cpio ./
55+
56+
if [[ $EXTERNAL_ROOT -eq 1 ]]; then
57+
echo "Copying rootfs.cpio to rootfs_full.cpio (external root mode)"
58+
cp -f buildroot/output/images/rootfs.cpio ./rootfs_full.cpio
59+
ASSERT ./scripts/rootfs_ext4.sh
60+
else
61+
echo "Copying rootfs.cpio to rootfs.cpio (initramfs mode)"
62+
cp -f buildroot/output/images/rootfs.cpio ./rootfs.cpio
63+
fi
3664
}
3765

3866
function do_linux
3967
{
40-
ASSERT git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b linux-6.12.y --depth=1
41-
cp -f configs/linux.config linux/.config
68+
if [ ! -d linux ]; then
69+
echo "Cloning Linux kernel..."
70+
ASSERT git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b linux-6.12.y --depth=1
71+
else
72+
echo "linux/ already exists, skipping clone"
73+
fi
74+
75+
safe_copy configs/linux.config linux/.config
76+
4277
export PATH="$PWD/buildroot/output/host/bin:$PATH"
4378
export CROSS_COMPILE=riscv32-buildroot-linux-gnu-
4479
export ARCH=riscv
@@ -49,5 +84,74 @@ function do_linux
4984
popd
5085
}
5186

52-
do_buildroot && OK
53-
do_linux && OK
87+
function show_help {
88+
cat << EOF
89+
Usage: 0ドル [--buildroot] [--linux] [--all] [--external-root] [--clean-build] [--help]
90+
91+
Options:
92+
--buildroot Build Buildroot rootfs
93+
--linux Build Linux kernel
94+
--all Build both Buildroot and Linux
95+
--external-root Use external rootfs instead of initramfs
96+
--clean-build Remove entire buildroot/ and/or linux/ directories before build
97+
--help Show this message
98+
EOF
99+
exit 1
100+
}
101+
102+
BUILD_BUILDROOT=0
103+
BUILD_LINUX=0
104+
EXTERNAL_ROOT=0
105+
CLEAN_BUILD=0
106+
107+
while [[ $# -gt 0 ]]; do
108+
case "1ドル" in
109+
--buildroot)
110+
BUILD_BUILDROOT=1
111+
;;
112+
--linux)
113+
BUILD_LINUX=1
114+
;;
115+
--all)
116+
BUILD_BUILDROOT=1
117+
BUILD_LINUX=1
118+
;;
119+
--external-root)
120+
EXTERNAL_ROOT=1
121+
;;
122+
--clean-build)
123+
CLEAN_BUILD=1
124+
;;
125+
--help|-h)
126+
show_help
127+
;;
128+
*)
129+
echo "Unknown option: 1ドル"
130+
show_help
131+
;;
132+
esac
133+
shift
134+
done
135+
136+
if [[ $BUILD_BUILDROOT -eq 0 && $BUILD_LINUX -eq 0 ]]; then
137+
echo "Error: No build target specified. Use --buildroot, --linux, or --all."
138+
show_help
139+
fi
140+
141+
if [[ $CLEAN_BUILD -eq 1 && $BUILD_BUILDROOT -eq 1 && -d buildroot ]]; then
142+
echo "Removing buildroot/ for clean build..."
143+
rm -rf buildroot
144+
fi
145+
146+
if [[ $CLEAN_BUILD -eq 1 && $BUILD_LINUX -eq 1 && -d linux ]]; then
147+
echo "Removing linux/ for clean build..."
148+
rm -rf linux
149+
fi
150+
151+
if [[ $BUILD_BUILDROOT -eq 1 ]]; then
152+
do_buildroot && OK
153+
fi
154+
155+
if [[ $BUILD_LINUX -eq 1 ]]; then
156+
do_linux && OK
157+
fi

‎scripts/rootfs_ext4.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/bash
2+
3+
ROOTFS_CPIO="rootfs_full.cpio"
4+
IMG="ext4.img"
5+
IMG_SIZE=$((1024 * 1024 * 1024)) # 1GB
6+
IMG_SIZE_BLOCKS=$((${IMG_SIZE} / 4096)) # IMG_SIZE / 4k
7+
8+
DIR=rootfs
9+
10+
echo "[*] Remove old rootfs directory..."
11+
rm -rf $DIR
12+
mkdir -p $DIR
13+
14+
echo "[*] Extract CPIO"
15+
pushd $DIR
16+
cpio -idmv < ../$ROOTFS_CPIO
17+
popd
18+
19+
echo "[*] Create empty image"
20+
dd if=/dev/zero of=${IMG} bs=4k count=${IMG_SIZE_BLOCKS}
21+
22+
echo "[*] Create ext4 rootfs image"
23+
fakeroot mkfs.ext4 -F ${IMG} -d $DIR
24+
25+
# Show image size
26+
du -h ${IMG}

‎target/init

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/sh
2+
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
3+
4+
ROOTFS_DEV=/dev/vda
5+
6+
mount -t devtmpfs devtmpfs /dev
7+
mount -t proc none /proc
8+
mount -t sysfs none /sys
9+
10+
# use the /dev/console device node from devtmpfs if possible to not
11+
# confuse glibc's ttyname_r().
12+
# This may fail (e.g., booted with console=), and errors from exec will
13+
# terminate the shell, so use a subshell for the test
14+
if (exec 0</dev/console) 2>/dev/null; then
15+
exec 0</dev/console
16+
exec 1>/dev/console
17+
exec 2>/dev/console
18+
fi
19+
20+
echo "[*] Attempting to mount $ROOTFS_DEV"
21+
mkdir -p /mnt
22+
23+
mount -t ext4 $ROOTFS_DEV /mnt
24+
if [ $? -ne 0 ]; then
25+
echo "[!] Failed to mount $ROOTFS_DEV. Using initramfs."
26+
exec /sbin/init "$@"
27+
fi
28+
29+
echo "[*] $ROOTFS_DEV mounted successfully. Checking for root filesystem..."
30+
if [ -x /mnt/sbin/init ]; then
31+
echo "[*] Valid root filesystem found. Switching root to $ROOTFS_DEV"
32+
mount --move /sys /mnt/sys
33+
mount --move /proc /mnt/proc
34+
mount --move /dev /mnt/dev
35+
exec switch_root -c /dev/console /mnt /sbin/init "$@"
36+
else
37+
echo "[!] No valid root filesystem found on $ROOTFS_DEV. Using initramfs."
38+
umount /mnt
39+
exec /sbin/init "$@"
40+
fi

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /