1.安裝qemu
apt install qemu-system
2.編譯內核
設置gcc軟鏈接sudo ln -s arm-linux-gnueabihf-gcc arm-linux-gccsudo ln -s arm-linux-gnueabihf-ld arm-linux-ldsudo ln -s arm-linux-gnueabihf-nm arm-linux-nmsudo ln -s arm-linux-gnueabihf-objcopy arm-linux-objcopysudo ln -s arm-linux-gnueabihf-ar arm-linux-arsudo ln -s arm-linux-gnueabihf-strip arm-linux-strip下載內核linux-5.6.14.tar.xz// 解壓tar xvf linux-5.6.14.tar.xz// 編譯默認配置make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig// 編譯安裝,-j參數后面可以跟一個數字,表示并行任務的數量// make -j4表示同時運行四個編譯任務。make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm -j8
3.編譯文件系統
下載文件系統busybox-1.37.0.tar.bz2 // 解壓tar xvf busybox-1.37.0.tar.bz2 // 編譯默認配置make defconfig// 編譯make CROSS_COMPILE=arm-linux-gnueabi- -j8錯誤:1. ‘sha1_process_block64_shaNI’ undeclared 解決1. nano .config注釋下面配置#define ENABLE_SHA1_HWACCEL解決2. nano libbb/hash_md5_sha.c添加條件判斷修改前:/* Used also for sha256 */unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf){unsigned hash_size;/* SHA stores total in BE, need to swap on LE arches: */common64_end(ctx, /*swap_needed:*/ BB_LITTLE_ENDIAN);hash_size = 8;if (ctx->process_block == sha1_process_block64#if ENABLE_SHA1_HWACCEL|| ctx->process_block == sha1_process_block64_shaNI#endif) {hash_size = 5;}/* This way we do not impose alignment constraints on resbuf: */if (BB_LITTLE_ENDIAN) {unsigned i;for (i = 0; i < hash_size; ++i)ctx->hash[i] = SWAP_BE32(ctx->hash[i]);}hash_size *= sizeof(ctx->hash[0]);memcpy(resbuf, ctx->hash, hash_size);return hash_size;}修改后:/* Used also for sha256 */unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf){unsigned hash_size;/* SHA stores total in BE, need to swap on LE arches: */common64_end(ctx, /*swap_needed:*/ BB_LITTLE_ENDIAN);hash_size = 8;if (ctx->process_block == sha1_process_block64#if ENABLE_SHA1_HWACCEL/* 添加條件判斷 */#if defined(__GNUC__) && (defined(__i386__) || defined(__x86__64__))|| ctx->process_block == sha1_process_block64_shaNI#endif#endif) {hash_size = 5;}/* This way we do not impose alignment constraints on resbuf: */if (BB_LITTLE_ENDIAN) {unsigned i;for (i = 0; i < hash_size; ++i)ctx->hash[i] = SWAP_BE32(ctx->hash[i]);}hash_size *= sizeof(ctx->hash[0]);memcpy(resbuf, ctx->hash, hash_size);return hash_size;}2. ‘IFLA_CAN_TERMINATION’ undeclared修改networking/libiproute/iplink.c添加條件判斷修改前:case ARG_termination: {uint16_t val;NEXT_ARG();val = get_u16(*argv, keyword);addattr_l(&req.n, sizeof(req), IFLA_CAN_TERMINATION, &val, sizeof(val));break;}修改后:case ARG_termination: {uint16_t val;NEXT_ARG();val = get_u16(*argv, keyword);/* 添加條件判斷 */#ifdef IFLA_CAN_TERMINATIONaddattr_l(&req.n, sizeof(req), IFLA_CAN_TERMINATION, &val, sizeof(val));#elsefprintf(stderr, "IFLA_CAN_TERMINATION is not supported on this system.\n");#endifbreak;}// 編譯安裝make install CROSS_COMPILE=arm-linux-gnueabi- -j8編譯生成的bin文件在busybox-1.37.0/_install/目錄下
4.制作根文件系統鏡像
切換到busybox的上級目錄,并使用如下腳本制作鏡像
#!/bin/bashmkdir -p rootfs/{dev,etc/init.d,lib}
touch rootfs/etc/init.d/rcS
#這里用雙引號可能會報錯
echo -e '#!/bin/sh\n' > rootfs/etc/init.d/rcS
cp busybox-1.37.0/_install/* -r rootfs/
sudo cp -P /usr/arm-linux-gnueabihf/libc/lib/* rootfs/lib/ln -s bin/busybox rootfs/init sudo mknod rootfs/dev/tty1 c 4 1
sudo mknod rootfs/dev/tty2 c 4 2
sudo mknod rootfs/dev/tty3 c 4 3
sudo mknod rootfs/dev/tty4 c 4 4sudo chown root:root -R rootfs/*
sudo chmod 777 rootfs/etc/init.d/rcSqemu-img create -f raw disk.img 512M
mkfs -t ext4 ./disk.img
mkdir -p tmpfs
sudo mount -o loop ./disk.img tmpfs/
sudo cp -r rootfs/* tmpfs/
sudo umount tmpfs
file disk.img
5.啟動虛擬機開發板
sudo qemu-system-arm \-M vexpress-a9 \-m 512M \-kernel linux-5.6.14/arch/arm/boot/zImage \-dtb linux-5.6.14/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \-nographic \-append "root=/dev/mmcblk0 rw console=ttyAMA0" \-sd disk.img運行成功,如下圖
錯誤:EXT4-fs (mmcblk0): recovery complete
EXT4-fs (mmcblk0): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext4 filesystem) on device 179:0.
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
Run /etc/init as init process
Run /bin/init as init process
Run /bin/sh as init process
Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.6.14 #2
Hardware name: ARM-Versatile Express
[<80110804>] (unwind_backtrace) from [<8010c6a8>] (show_stack+0x10/0x14)
[<8010c6a8>] (show_stack) from [<807867b0>] (dump_stack+0xa0/0xb4)
[<807867b0>] (dump_stack) from [<80120f90>] (panic+0x118/0x320)
[<80120f90>] (panic) from [<807a0374>] (kernel_init+0x104/0x114)
[<807a0374>] (kernel_init) from [<801010e8>] (ret_from_fork+0x14/0x2c)
Exception stack(0x9e493fb0 to 0x9e493ff8)
3fa0: 00000000 00000000 00000000 00000000
3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
---[ end Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.1. <span style="color: red;">文件系統重init文件缺失</span>,檢查我的文件系統中init文件正常。故排除2.busybox編譯時未進行交叉編譯導致文件為不是arm架構文件,file rootfs/bin/busybox命令查看并無問題。故排除參考博客:CentOS 7 利用qemu模擬ARM vexpress A9開發板3.交叉編譯庫未正常拷貝。檢查rootfs/lib文件發現其下面沒有交叉編譯庫的內容,而是一個軟鏈接,指向一個不存在的路徑。問題定位到了,修復如下:修改制作根文件系統鏡像中sudo cp -P /usr/arm-linux-gnueabihf/lib/* rootfs/lib/為sudo cp /usr/arm-linux-gnueabihf/lib/sf/* rootfs/lib/,重新制作根文件系統鏡像后正常了。可能不同版本ubuntu安裝的 gcc-arm-linux-gnueabi 庫路徑不同,需要自己檢查一下。
Kernel panic No working init found 可能原因:
1.文件系統重init文件缺失,檢查我的文件系統中init文件正常。故排除
參考博客:buildroot編譯內核啟動報錯:Kernel panic - not syncing: No working init found問題解決
2.busybox編譯時未進行交叉編譯導致文件為不是arm架構文件,file rootfs/bin/busybox命令查看并無問題,故排除
參考博客:CentOS 7 利用qemu模擬ARM vexpress A9開發板
3.交叉編譯庫未正常拷貝。,檢查rootfs/lib文件發現其下面沒有交叉編譯庫的內容,而是一個軟鏈接,指向一個不存在的路徑。問題定位到了,修復如下:
修改制作根文件系統鏡像中sudo cp -P /usr/arm-linux-gnueabihf/lib/* rootfs/lib/為sudo cp /usr/arm-linux-gnueabihf/libc/lib/* rootfs/lib/,重新制作根文件系統鏡像后正常了。
可能不同版本ubuntu安裝的 gcc-arm-linux-gnueabi 庫路徑不同,需要自己檢查一下。
參考博客:啟動報錯:Kernel panic - not syncing: No working init found. Try passing init= option to kernel.