Qemu搭建Linux环境
背景目的
在虚拟机中学习linux驱动开发,降低对硬件的依赖。这里使用qemu模拟工具,搭建linux运行环境。在搭建虚拟机中,同时学习如何编译Linux内核、制作根文件系统等。
以下操作均在ubuntu20.04下进行
一、准备Qemu
下载安装qemu
第一种方式:直接安装
apt-get install qemu
注意:apt-get 安装可能不是最新的版本。
第二种方式:源码编译安装
(1)下载源码
https://download.qemu.org/
这里使用6.0版本
https://download.qemu.org/qemu-6.0.0.tar.xz
(2)编译安装
安装依赖包
sudo apt install libpixman-1-dev
sudo apt-get install build-essential zlib1g-dev pkg-config libglib2.0-dev binutils-dev libboost-all-dev autoconf libtool libssl-dev libpixman-1-dev libpython-dev python-pip python-capstone virtualenv
解压、配置、编译、安装
cd qemu-6.0.0
./configure --prefix=/home/only/linux_driver/env/qemu
make -j32
make install
--prefix=为指定安装目录,编译安装成功后,即可在此目录下的/bin中找到执行文件,根据自己的环境指定即可。
二、准备内核
我们使用Linux的内核版本为4.19.95。
(1)下载源码
https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.95.tar.gz
(2)编译
tar -vxf linux-4.19.95.tar.gz
cd linux-4.19.95
make menuconfig
make -j32
编译完成后,可以在linux-4.19.95/arch/x86_64/boot目录下看到内核镜像bzImage文件
遇到的问题:
No rule to make target ‘debian/canonical-certs.pem‘, needed by ‘certs/x509_certificate_list‘. Stop.
解决,修改目录下./config文件,将CONFIG_SYSTEM_TRUSTED_KEYS置空
修改为
三、准备文件系统
我们使用busybox工具来制作一个最小文件系统。
(1)下载源码
https://busybox.net/downloads/busybox-1.33.1.tar.bz2
(2)编译安装
解压、配置
cd busybox-1.33.1
make defconfig
make menuconfig
make -j32
make install
默认安装路径为源码目录_install文件夹下。
这里我们使能静态编译选项,不用拷贝动态库。
# 使能静态编译
Settings
->Builds static binary (no shared libs)
其他配置选项:
# 启动 vi风格命令行
Settings
->vi-style line editing commands
# 使能简洁指令风格
Linux module Utilities
->Simplified modutils
# 使能mdev模块
Linux System Utilities
->mdev (16 kb)
(3)准备根文件系统
创建rootfs,将busybox编译出来的文件复制过去
cd busybox-1.33.1
cp -rd _install/* ../rootfs/
创建其他文件夹
mkdir dev etc lib proc root tmp sys mnt opt var
dev:设备文件存储目录,应用程序通过对这些文件的读写和控制以访问实际的设备
etc:系统配置文件的所在地,一些服务器的配置文件\用户账号以及密码配置文件\busybox启动脚本等
lib:系统库文件存放目录
proc:操作系统运行时,进程及内核信息存放在这里。/proc目录为伪文件系统proc的挂载目录,不是真正的文件系统,它存在与内存中。
root:超级用户的目录
tmp:存放临时文件
sys:sysfs文件系统挂载目录
mnt:用于存放挂载存储设备的挂载目录
opt:可选目录
var:交换分区,或者系统日志/var/log
以下可以参考:busybox-1.33.1/examples & busybox-1.33.1/examples/bootfloppy/etc
(4)创建inittab文件
inittab为init初始化程序用到的配置文件。
创建文件:
vim etc/inittab
添加:
#etc /inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
2:指定系统启动后运行的脚本
3:将console作为控制台终端
4:重启则运行/sbin/init
5:按下ctrl+alt+del组合键的话,则运行/sbin/reboot,即设置重启键
6:关机卸载各个文件系统
7:关机时关闭交换分区
(3)创建rcS启动脚本
创建文件:
mkdir etc/init.d
vim etc/init.d/rcS
添加:
#! /bin/sh
/bin/mount -a
/sbin/mdev -s
3:挂载所有文件系统,由/etc/fstab来指定
5:自动创建文件节点
mdev扫描/sys/class和sys/block中所有的类设备目录,如果在目录中含有名为”dev“的文件,且文件中包含的是设备号,则mdev就利用这些信息为这个设备在/dev下创建设备节点文件。一般只在启动时才执行一次”mdev -s“。
创建完成后,添加执行权限
chmod 755 rcS
(4)创建fstab文件
/etc/fstab是用来存放文件系统信息的文件;当系统启动的时候,系统会从这个文件读取信息,并且将此文件中指定的文件系统挂载到指定的目录。
创建文件:
vim etc/fstab
添加:
#<file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
2:挂载proc文件系统
3:挂载tmpfs
4:挂载sysfs文件系统
(5)打包image文件
将rootfs文件夹打包成image文件
cd rootfs
find . | cpio -o --format=newc > ../initrd.img
打包完成后,即可在rootfs同级目录中找到文件系统镜像initrd.img
四、创建qemu启动脚本
vim start.sh
添加启动参数
/home/only/linux_driver/env/qemu/bin/qemu-system-x86_64 -m 4096 -smp 4 -M q35 \
-nographic \
-kernel /home/only/linux_driver/linux-4.19.95/arch/x86_64/boot/bzImage \
-initrd /home/only/linux_driver/env/initrd.img \
-append "root=/dev/ram rw rdinit=/linuxrc console=ttyS0"
-kernel:指定内核文件
-initrd:指定根系统文件
-append:启动参数
root=/dev/ram rw:使用ramdisk虚拟文件系统
rdinit=/linuxrc:指定init启动程序
添加运行权限,运行脚本
chmod +x ./start.sh
./start.sh
系统启动成功