一、编译内核
内核源码:linux-5.10.3
root@linux:/home/gsf/linux-5.10.3# export ARCH="x86_64"
root@linux:/home/gsf/linux-5.10.3# make x86_64_defconfig
root@linux:/home/gsf/linux-5.10.3# make menuconfig
Processor type and features ---> [ ] Randomize the address of the kernel image (KASLR) 不要选 Drevice Drivers ---> NVME Support <*> NVM Express block device [*] NVMe multipath support [*] NVMe hardware monitoring <*> NVM Express over Fabrics FC host driver <*> NVM Express over Fabrics TCP host driver File systems ---> <*> F2FS filesystem support [*] F2FS Status Information (NEW) [*] F2FS extended attributes (NEW) [*] F2FS Access Control Lists (NEW) Network File Systems---> Kernel hacking ---> Compile-time checks and compiler options ---> [*] Compile the kernel with debug info [*] Provide GDB scripts for kernel debugging 注:高版本改成了 Kernel hacking ---> Compile-time checks and compiler options ---> Debug information (Disable debug information) ---> (X)Generate DWARF Version 5 debuginfo [*] Provide GDB scripts for kernel debugging |
root@linux:/home/gsf/linux-5.10.3#make -j4 bzImage
二、启动内核
qemu启动内核后,如果想退出,可以在qemu中执行Ctlr+A,然后按x键。
也可以在ubuntu另一个终端 killall qemu-system-x86_64(不建议)。
1,仅rootfs启动
最简单的启动,资源很少,无disk,无网络。
qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -drive file=rootfs.f2fs,if=ide,format=raw -nographic -append "root=/dev/sda console=ttyS0" |
启动完成后,用户名输入root,登录系统查看信息,f2fs已经挂载:
# cat /proc/mounts /dev/root / f2fs rw,lazytime,relatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,exte0 devtmpfs /dev devtmpfs rw,relatime,size=48612k,nr_inodes=12153,mode=755 |
2,挂载 scsi disk(格式化成ext4)启动
1)制作ext4镜像
root@linux:/home/gsf/linux-5.10.3#dd if=/dev/zero of=ext4.img bs=1M count=256 root@linux:/home/gsf/linux-5.10.3# mkfs.ext4 ext4.img |
2)执行qemu命令
qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -drive file=rootfs.f2fs,if=ide,format=raw,id=myid0 --nographic -append "root=/dev/sda console=ttyS0" -hdb ext4.img |
系统启动后,输入root用户名登录系统。
3)修改挂载表
创建目录 # mkdir /mnt/scsimp 并在/etc/fstab文件中增加一行: /dev/sdb /mnt/scsimp ext4 defaults 0 0 |
4)reboot重新模拟出来的系统(不是自己的电脑系统),可以看到ext4已经挂载
# cat /proc/mounts …… sysfs /sys sysfs rw,relatime 0 0 /dev/sdb /mnt/scsimp ext4 rw,relatime 0 0 |
3,挂载 scsi disk(格式化成ext4)+ nvme disk(格式化成f2fs)
1)制作ext4镜像
root@linux:/home/gsf/linux-5.10.3#dd if=/dev/zero of=ext4.img bs=1M count=25 root@linux:/home/gsf/linux-5.10.3# mkfs.ext4 ext4.img |
2)制作nvme的模拟磁盘
root@linux:/home/gsf/linux-5.10.3#qemu-img create -f raw disk.qcow 1G |
3)执行qemu命令
qemu启动后,红字部分在/dev/目录下生成了nmve0,nvme0n1两个文件(如果没有生成,按第二节设置kenel编译config文件,打开nvme相关配置)。
qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -drive file=rootfs.f2fs,if=ide,format=raw,id=myid0 --nographic -append "root=/dev/sda console=ttyS0" -hdb ext4.img -device nvme,drive=nvme1,serial=deadbeaf,num_queues=8 -drive file=disk.qcow,if=none,id=nvme1 -smp 4 |
4)登录启动的linux系统
创建目录 # mkdir /mnt/scsimp # mkdir /mnt/nvmemp 并在/etc/fstab文件中增加两行: /dev/sdb /mnt/scsimp ext4 defaults 0 0 /dev/nvme0n1p1 /mnt/nvmemp f2fs defaults 0 0 -------后面会将disk.qcow格式化成f2fs,所以这里按f2fs挂载 |
格式化nvme disk # fdisk /dev/nvme0n1 Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT disklabel Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that the previous content won't be recoverable. Command (m for help): n Partition type p primary partition (1-4) e extended p Partition number (1-4): 1 First sector (32-2097151, default 32): ------------回车,默认即可 Using default value 32 Last sector or +size{,K,M,G,T} (32-2097151, desfault 2097151): ------------回车,默认即可 Using default value 2097151 Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table [ 131.575409] nvme0n1: p1 格式化成功后,出现/dev/nvme0n1p1设备,这就是刚fdisk新建的分区 |
格式化新建的nvme分区 # mkfs.f2fs -l nvmedisk /dev/nvme0n1p1 (-l,是label的首字母) (这里也可以格式化成其他文件系统) 注:如果没有mkfs.f2fs工具,请参考ubuntu20.04 搭建kernel调试环境第二篇--制作rootfs |
5)reboot重启qemu模拟出来的系统(不是自己的电脑系统),登录后,可以看到scsi、nvme disk已经挂载
# cat /proc/mounts …… sysfs /sys sysfs rw,relatime 0 0 /dev/sdb /mnt/scsimp ext4 rw,relatime 0 0 /dev/nvme0n1p1 /mnt/nvmemp f2fs rw,relatime 0 0 |
另外,还可以看到系统中有5个nvme队列。nvme0q0是管理队列。nvme0q1~4是IO队列每个核一个(我们的qemu命令指定了num_queues=8、smp 4参数)。
# cat /proc/interrupts # cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 0: 183 0 0 0 IO-APIC 2-edge timer 1: 0 0 9 0 IO-APIC 1-edge i8042 …… 24: 6 0 0 0 PCI-MSI 65536-edge nvme0q0 25: 0 0 0 11 PCI-MSI 65537-edge nvme0q1 26: 0 0 0 0 PCI-MSI 65538-edge nvme0q2 27: 0 0 0 0 PCI-MSI 65539-edge nvme0q3 28: 0 0 0 0 PCI-MSI 65540-edge nvme0q4 |
附一,qemu参数说明
qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -drive file=rootfs.f2fs,if=ide,format=raw,id=myid0 --nographic -append "root=/dev/sda console=ttyS0" -hdb ext4.img -device nvme,drive=nvme1,serial=deadbeaf,num_queues=8 -drive file=disk.qcow2,if=none,id=nvme1 -smp 4
-kernel 要运行的内核镜像 -drive 理解成一个虚拟的disk。 drive option之 file:代表该disk的文件,由“qemu-img create -f 格式”生成。 drive option之 if:interface,指定disk的接口,有ide, scsi, sd, mtd, floppy, pflash, virtio, none这些类型。 drive option之 format:format:代码disk的file的格式,创建文件时由qemu-img create -f指定。 drive option之 id:一个字符串标识。有多个dirve时,通过id来识别用哪个drive。 --nographic:关闭图形调试,将打印信息输出到串口。 -append :kernel的命令行参数。 append之root:rootfs存储设备。 append之console:串口名称。 -hdb:创建一个hard disk。注意,字符串hdb不是/dev/hdb(这个个IDE disk),这里的hdb启动后,是/dev/sdb(scsi disk)。hdb image可以通过mkfs格式化成需要的文件系统。 -device:创建一个总线设备。将子参数drive=id指定的disk挂在总线下。 devie值num_queues:nvme的队列深度。 -smp:多核数量。 |
附二,中文符号导致qemu启动失败
错误命令: qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -drive file=rootfs.ext2,if=ide,format=raw -nographic -append “root=/dev/sda console=ttyS0” 出错信息: 原因: 命令是预先在LibreOfferce writer编辑器中写的,虽然输入法是英文键盘,但输入的双引号依然是中文属性,这个编辑器在我的环境中竟然不能输入英文双引号。 正确命令(注意红字部分): qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -drive file=rootfs.ext2,if=ide,format=raw -nographic -append "root=/dev/sda console=ttyS0" |