qemu搭建和运行起来一个linux内核环境。
参考了博客:
搭建linux调试环境 (一)-- qemu环境搭建vexpress开发平台 - Edver - 博客园
【嵌入式Linux之QEMU模拟器】4、使用busybox制作根文件系统_ReCclay的博客-CSDN博客_busybox编译根文件系统 qemu
qemu模拟vexpress开发板 - bigsissy - 博客园
qemu 模拟arm - 小水同学 - 博客园
QEMU简述:
因此,上述QEMU所做的工作,相当于:
1. 编译Linux Kernel镜像
#!/bin/sh
# 预期工具准备:
# Ubuntu 22.04 安装qemu全套
sudo apt install qemu
sudo apt install qemu-system
sudo apt install qemu-user
sudo apt install qemu-efi
sudo apt install qemu-web-desktop
sudo apt install qemu-guest-agent
sudo apt install qemu-block-extra
sudo apt install qemu-utils
sudo apt install qemubuilder
# gcc-arm-linux-gnueabi工具
sudo apt install gcc-arm-linux-gnueabi
# 后续的编译过程还需要的工具
sudo apt install u-boot-tools
sudo apt install flex
sudo apt install bison
sudo apt install libncurses5-dev
sudo apt install libncurses-dev
# 开发时常用工具
sudo apt install cmake
sudo apt install git
sudo apt install vim
sudo apt install build-essential
# 注意编译的Linux内核版本, 如内核版本过低, 而工具链和主机Ubuntu过旧, 则可能会带来大量编译错误
# 1.
# 修改linux kernel的Makefile的两个变量为:
# ARCH ?= arm
# CROSS_COMPILE ?= arm-linux-gnueabi-
#
cd linux-4.19.269/
vim Makefile
# 编译配置
make vexpress_defconfig
make menuconfig # 这个只要没有报错, 直接推出出现的窗口即可
# 2.
# 编译linux kernel代码, 为了加速编译, 开启多线程编译
#
make zImage -j 4
make modules -j 4
make dtbs -j 4
make LOADADDR=0x60003000 uImage -j 4
# 3.
# 把镜像文件zImage和uImage, 设备树文件dtbs, 复制到工程目录testboot里, 进行测试一下
cd ..
mkdir testboot
cp arch/arm/boot/zImage ../testboot/
cp arch/arm/boot/uImage ../testboot/
cp arch/arm/boot/dts/vexpress-v2p-ca9.dtb ../testboot/
# 4.
# 测试
sh testboot/test_boot.sh
# test_boot.sh内容:
# #!/bin/sh
# # 测试uboot
# # 上级路径
# 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-system-arm \
# -M vexpress-a9 \
# -m 512M \
# -kernel ${kernel_path} \
# -dtb ${dtb_path} \
# -append "console=ttyAMA0" \
# -nographic \
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镜像
#!/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=tty0" \
-sd rootfs.ext3 \
# -nographic \
# console=ttyAMA0