qemu搭建和运行起来一个linux内核环境
qemu搭建和运行起来一个linux内核环境。
参考了博客:
https://www.cnblogs.com/edver/p/6001786.html
https://blog.csdn.net/ReCclay/article/details/102319392
https://www.cnblogs.com/bigsissy/p/11134802.html
https://www.cnblogs.com/zml-forever/p/6277092.html
1. 编译Linux Kernel镜像
1 #!/bin/sh 2 3 4 # 预期工具准备: 5 # Ubuntu 22.04 安装qemu全套 6 sudo apt install qemu 7 sudo apt install qemu-system 8 sudo apt install qemu-user 9 sudo apt install qemu-efi 10 sudo apt install qemu-web-desktop 11 sudo apt install qemu-guest-agent 12 sudo apt install qemu-block-extra 13 sudo apt install qemu-utils 14 sudo apt install qemubuilder 15 # gcc-arm-linux-gnueabi工具 16 sudo apt install gcc-arm-linux-gnueabi 17 # 后续的编译过程还需要的工具 18 sudo apt install u-boot-tools 19 sudo apt install flex 20 sudo apt install bison 21 sudo apt install libncurses5-dev 22 sudo apt install libncurses-dev 23 # 开发时常用工具 24 sudo apt install cmake 25 sudo apt install git 26 sudo apt install vim 27 sudo apt install build-essential 28 29 30 31 # 注意编译的Linux内核版本, 如内核版本过低, 而工具链和主机Ubuntu过旧, 则可能会带来大量编译错误 32 33 34 35 # 1. 36 # 修改linux kernel的Makefile的两个变量为: 37 # ARCH ?= arm 38 # CROSS_COMPILE ?= arm-linux-gnueabi- 39 # 40 cd linux-4.19.269/ 41 vim Makefile 42 43 # 编译配置 44 make vexpress_defconfig 45 make menuconfig # 这个只要没有报错, 直接推出出现的窗口即可 46 47 48 49 # 2. 50 # 编译linux kernel代码, 为了加速编译, 开启多线程编译 51 # 52 make zImage -j 4 53 make modules -j 4 54 make dtbs -j 4 55 make LOADADDR=0x60003000 uImage -j 4 56 57 58 59 # 3. 60 # 把镜像文件zImage和uImage, 设备树文件dtbs, 复制到工程目录testboot里, 进行测试一下 61 cd .. 62 mkdir testboot 63 cp arch/arm/boot/zImage ../testboot/ 64 cp arch/arm/boot/uImage ../testboot/ 65 cp arch/arm/boot/dts/vexpress-v2p-ca9.dtb ../testboot/ 66 67 68 69 # 4. 70 # 测试 71 sh testboot/test_boot.sh 72 # test_boot.sh内容: 73 # #!/bin/sh 74 # # 测试uboot 75 # # 上级路径 76 # top_path="/home/thinks2/ProgramProject/qemu_study/" 77 # src_path="linux-4.14.302/arch/arm/boot/" 78 # # 内核文件与dtb文件的路径 79 # kernel_path=${top_path}${src_path}"zImage" 80 # dtb_path=${top_path}${src_path}"dts/vexpress-v2p-ca9.dtb" 81 # qemu-system-arm \ 82 # -M vexpress-a9 \ 83 # -m 512M \ 84 # -kernel ${kernel_path} \ 85 # -dtb ${dtb_path} \ 86 # -append "console=ttyAMA0" \ 87 # -nographic \ 88
2. 使用busybox制作最小文件系统
#!/bin/sh # 1. # 修改busybox的Makefile的两个变量为: # ARCH ?= arm # CROSS_COMPILE ?= arm-linux-gnueabi- # cd busybox-1.35.0/ vim Makefile # 设置编译为静态库: # Settings ---> # Build Options ---> # [*] Build as a static binary (no shared libs) make menuconfig # 2. # 编译: # 编译完成后会在busybox目录下生成一个_install的目录, # 该目录是编译好的文件系统需要使用的一些命令集合 make defconfig make -j 4 make install # 3. # 新建一个根文件系统的文件夹 cd .. mkdir rootfs cd rootfs/ # 拷贝_install目录的命令集到rootfs中 cp -rf ../busybox-1.35.0/_install/* ./ # 在rootfs中, 新建lib目录,从工具链中拷贝arm执行库到该lib中 mkdir lib cp -p /usr/arm-linux-gnueabi/lib/* lib/ # 4. # 创建字符设备: 设备文件, 跟用户和底层进行交互的接口, 这些接口以文件节点的形式存在, 读写文件, 直接读写对应的结点即可 # 在rootfs中, 创建dev文件夹, 存放各种目录结点 mkdir dev cd dev # 创建4个串口结点 # # 命令和其参数的意义: # mknod: 创建结点 # -m 666: 设置权限为666 # ttyX: 表示串口 # c: 表示字符设备 # 4: 表示主设备号 # 1: 表示次设备号 sudo mknod -m 666 tty1 c 4 1 sudo mknod -m 666 tty2 c 4 2 sudo mknod -m 666 tty3 c 4 3 sudo mknod -m 666 tty4 c 4 4 # 创建1个工作台结点 sudo mknod -m 666 console c 5 1 # 创建null结点 sudo mknod -m 666 null c 1 3 # 5. # 制作SD根文件系统镜像: 根文件系统放到SD卡里, 内核启动后, 从SD卡挂载根文件系统 cd ../.. # 生成根文件系统镜像rootfs.ext3, 直接把rootfs.ext3看成一个SD卡即可 # bs: 缓冲区大小, count: 表示块大小 dd if=/dev/zero of=rootfs.ext3 bs=1M count=64 # 格式化rootfs.ext3 mkfs.ext3 rootfs.ext3 # 6. # 将各种文件拷贝到文件系统镜像中 mkdir tmpfs # 将虚拟sd卡挂载到/tmpfs # -t ext3: 表示文件系统是ext3格式 # -o loop: 使用loop模式用来将一个档案当成硬盘分割挂上系统 sudo mount -t ext3 rootfs.ext3 tmpfs/ -o loop # 拷贝rootfs的所有文件到sd卡中 sudo cp -r rootfs/* tmpfs/ # 卸载sd(块设备不能直接读写) sudo umount tmpfs # 7. # 使用qemu在这个最小文件系统上运行linux kernel sh step_qemu_run_os.sh # step_qemu_run_os.sh内容: # #!/bin/sh # # 使用qemu启动内核 # # 上级路径 # top_path="/home/thinks2/ProgramProject/qemu_study/" # src_path="linux-4.14.302/arch/arm/boot/" # # 内核文件与dtb文件的路径 # kernel_path=${top_path}${src_path}"zImage" # dtb_path=${top_path}${src_path}"dts/vexpress-v2p-ca9.dtb" # # 用qemu运行Linux内核, 其中: # # # # 1. -M vexpress-a9: 模拟vexpress-a9单板, 能够使用-M ?參数来获取该qemu版本号支持的全部单板 # # 2. -m 512M: 单板执行物理内存512M # # 3. -kernel xxx/zImage: 告诉qemu单板执行内核镜像路径 # # 4. -nographic: 不使用图形化界面, 仅仅使用串口 # # # # 5. -append "root=/dev/mmcblk0 rw console=tty0": # # 内核启动參数这里告诉内核vexpress单板执行. 其中: # # 5.1 root=/dev/mmcblk0: 文件系统的加载Root位置 # # 5.2 rw: 以读写的方式打开文件系统, 以便能够创建, 修改, 删除文件 # # 5.3 console=tty0: 控制台 # # # # 6. -sd rootfs.ext3: 从SD卡加载系统 # qemu-system-arm \ # -M vexpress-a9 \ # -m 512M \ # -kernel ${kernel_path} \ # -dtb ${dtb_path} \ # -append "root=/dev/mmcblk0 rw console=ttyAMA0" \ # -sd rootfs.ext3 \ # -nographic \ # # console=ttyAMA0
3. 使用qemu在最小系统上运行编译好的Linux Kernel镜像
1 #!/bin/sh 2 3 4 # 使用qemu启动内核 5 6 7 8 # 上级路径 9 top_path="/home/thinks2/ProgramProject/qemu_study/" 10 src_path="linux-4.14.302/arch/arm/boot/" 11 12 # 内核文件与dtb文件的路径 13 kernel_path=${top_path}${src_path}"zImage" 14 dtb_path=${top_path}${src_path}"dts/vexpress-v2p-ca9.dtb" 15 16 17 18 # 用qemu运行Linux内核, 其中: 19 # 20 # 1. -M vexpress-a9: 模拟vexpress-a9单板, 能够使用-M ?參数来获取该qemu版本号支持的全部单板 21 # 2. -m 512M: 单板执行物理内存512M 22 # 3. -kernel xxx/zImage: 告诉qemu单板执行内核镜像路径 23 # 4. -nographic: 不使用图形化界面, 仅仅使用串口 24 # 25 # 5. -append "root=/dev/mmcblk0 rw console=tty0": 26 # 内核启动參数这里告诉内核vexpress单板执行. 其中: 27 # 5.1 root=/dev/mmcblk0: 文件系统的加载Root位置 28 # 5.2 rw: 以读写的方式打开文件系统, 以便能够创建, 修改, 删除文件 29 # 5.3 console=tty0: 控制台 30 # 31 # 6. -sd rootfs.ext3: 从SD卡加载系统 32 qemu-system-arm \ 33 -M vexpress-a9 \ 34 -m 512M \ 35 -kernel ${kernel_path} \ 36 -dtb ${dtb_path} \ 37 -append "root=/dev/mmcblk0 rw console=tty0" \ 38 -sd rootfs.ext3 \ 39 # -nographic \ 40 41 # console=ttyAMA0 42