博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
qemu 文件系统制作:自己制作根目录和应用程序 + busybox
阅读量:4206 次
发布时间:2019-05-26

本文共 4575 字,大约阅读时间需要 15 分钟。

参考陈香兰老师Linux源码分析的课件,编译完linux源码之后,准备制作一个文件系统。

本文介绍了两种文件系统的生成方式,包括:

    1. 自己制作init和/dev/ram和/dev/console(遇到了文件系统的错误,花了很长时间才解决)
    2. 利用busybox生成文件系统。

0x01首先创建一个应用程序

这个程序作为init程序,是linux启动后准备执行的程序。

#include 
#include
void main(){ while(1){ printf("Hello!\n"); sleep(1); }}

静态编译:gcc test.c --static -o init (没有lib,必须静态编译)

0x02 建立文件系统 镜像

dd if=/dev/zero of=myinitrd4M.img bs=4096 count=1024mke2fs myinitrd4M.imgmkdir rootfssudo mount -o loop myinitrd4M.img rootfs

将init拷贝到目标根目录下(linux启动后期会在根目录中寻找一个应用程序来运行,在根目录下提供init是一种可选方案)

sudo cp init rootfs/

准备dev目录

sudo mkdir rootfs/dev#linux启动过程中会启用console设备sudo mknod rootfs/dev/console c 5 1#另外需要提供一个linux根设备,我们使用ramsudo mknod rootfs/dev/ram b 1 0sudo umount rootfs

至此,一个包含简单应用程序的根目录映像myinitrd4M.img就准备好了。

0x03 qemu启动

qemu-system-x86_64  -kernel ./linux-2.6.32.1/arch/x86/boot/bzImage -initrd ./testimg/myinitrd4M.img  -append "root=/dev/ram init=/init"

报错:

No filesystem could mount root, tried: ext3 vfat msdos iso9660

kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0 )

搜索了很久很久之后,终于意识到这个问题本质是,qemu启动镜像的时候尝试了ext3 vfat msdos iso9660这些文件格式,却没有尝试ext2。查看一下我们之前创建的镜像文件格式:

解决办法一:在rootfs中使用cpio生成新的镜像文件 

find . | cpio -o --format=newc > ../initrd.img# 重新运行qemu-system-x86_64  -kernel ./linux-2.6.32.1/arch/x86/boot/bzImage -initrd  testimg/initrd.img  -append "root=/dev/ram init=/init"

退出qemu : ctrl+a x

解决办法二(推荐):既然qemu使用了ext3,那么创建img时创建ext3不就可以了吗。

# 重新生成ext3格式的img文件,确保这时rootfs已经unmount了dd if=/dev/zero of=myinitrd4M.img bs=4096 count=1024mkfs.ext3 myinitrd4M.img

 

mkdir rootfssudo mount -o loop myinitrd4M.img rootfssudo cp init rootfs/sudo mkdir rootfs/devsudo mknod rootfs/dev/console c 5 1sudo mknod rootfs/dev/ram b 1 0sudo umount rootfs

启动qemu:

qemu-system-x86_64  -kernel ./linux-2.6.32.1/arch/x86/boot/bzImage -initrd  testimg/myinitrd4M.img  -append "root=/dev/ram init=/init"

 

0x04 利用busybox生成文件系统

上面是在文件系统中放入了init文件个/dev 设备文件,如果需要用busybox创建文件系统,下面从busybox中创建文件系统的方法,第一种最简洁但是换了内核之后会遇到一些问题,第二种比较稳定。

方法一:

 

参考下面简陋的bash脚本。把busybox中默认install生成的文件安装到rootfs,并创建/dev/console和/dev/ram即可。

条件:运行目录下有编译好的linux-2.6.32.1/arch/x86/boot/bzImage和busybox-1.28.4/_install,如果没有需要从源码重新编译。

参考

#!/bin/bash# 1 create myinitrd40M.imgmkdir testimgcd testimgdd if=/dev/zero of=myinitrd40M.img bs=40960 count=1024mkfs.ext3  myinitrd40M.img                                # 文件格式按需修改# 2 mount myinitrd40M.img to rootfs  foldermkdir rootfssudo mount -o loop myinitrd40M.img  rootfs# 3 install busybox to rootfscd ../busybox-1.28.4sudo make  CONFIG_PREFIX=../testimg/rootfs install# 4 rootfs mknod and create initrd.imgcd ../testimg/rootfssudo rm -rf lost+foundsudo mkdir devsudo mknod dev/console c 5 1sudo mknod dev/ram b 1 0  # find . | cpio -o --format=newc > ../myinitrd40M.img   #已经是ext3文件格式,不需要再生成了sleep 1# 5 umount cd ../sudo umount rootfscd ../# 6 start qemuqemu-system-x86_64 -kernel ./linux-2.6.32.1/arch/x86/boot/bzImage  -initrd  testimg/myinitrd40M.img    -append "console=ttyS0 ramdisk_size=409600 root=/dev/ram init=/bin/sh rw" -nographic

方法二:(推荐用这个)

利用busybox创建文件系统参考 https://www.anquanke.com/post/id/85837 里面介的两种方式来创建,测试可以成功。

方案一:

$ cd _install$ mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}}$ cat init#!/bin/shecho "INIT SCRIPT"mount -t proc none /procmount -t sysfs none /sysmount -t debugfs none /sys/kernel/debugmkdir /tmpmount -t tmpfs none /tmpmdev -s # We need this to find /dev/sda laterecho -e "nBoot took $(cut -d' ' -f1 /proc/uptime) secondsn"exec /bin/sh$ chmod +x init$ find . -print0 | cpio --null -ov --format=newc  | gzip -9 > /tmp/initramfs-busybox-x86.cpio.gz

方案二:

#在install目录中添加inittab文件:$ cat etc/inittab ::sysinit:/etc/init.d/rcS::askfirst:/bin/ash::ctrlaltdel:/sbin/reboot::shutdown:/sbin/swapoff -a::shutdown:/bin/umount -a -r::restart:/sbin/init添加rcS文件$ cat etc/init.d/rcS #!/bin/sh#!/bin/shmount -t proc none /procmount -t sys none /sys/bin/mount -n -t sysfs none /sys/bin/mount -t ramfs none /dev/sbin/mdev -$ chmod +x ./etc/init.d/rcS配置下dev目录mkdir devsudo mknod dev/ttyAMA0 c 204 64sudo mknod dev/null c 1 3sudo mknod dev/console c 5 1$ find . | cpio -o --format=newc > ../rootfs.img

每次修改了busybox下的文件后,执行find . | cpio -o --format=newc > ../rootfs.img重新创建img即可。

PS: 遇到一个小问题,暂时没解决,记录一下。编译linux源码的时候,用的是make defconfig,看了.config配置是x64位的。可是镜像确是在x86目录下创建的,file看了一下是x86镜像,可是qemu起的时候却说需要用64位来启动,很奇怪。希望路过的同学指教....

 

0x05 参考

[1] find . | cpio -o --format=newc > ../initrd.img

https://balau82.wordpress.com/2010/03/22/compiling-linux-kernel-for-qemu-arm-emulator/
[2] 陈香兰老师ppt 
http://staff.ustc.edu.cn/~xlanchen/ULK2011Spring/slides/2_2build+run+gdb%20linux-2.6.26.pdf

 

你可能感兴趣的文章
稀疏矩阵之python sparse实现
查看>>
pandas.DataFrame
查看>>
KMeans与深度学习自编码AutoEncoder结合提高聚类效果
查看>>
Linux下安装anaconda
查看>>
windows Anaconda lightgbm 安装
查看>>
Linux 系统下查看硬件信息命令大全
查看>>
python中的ord函数
查看>>
大小端
查看>>
Python struct模块的pack、unpack示例
查看>>
如何判断Linux是32位还是64位?
查看>>
12306火车票抢票Python代码
查看>>
Pandas 获取列名
查看>>
Hyperopt TypeError: 'generator' object is not subscriptable
查看>>
numpy 一维数组的切片与索引
查看>>
numpy 矩阵形状调整:拉伸、变成一位数组
查看>>
numpy 数组叠加
查看>>
numpy 花式索引,ix_
查看>>
python numpy 数组如何对每个元素进行操作
查看>>
numpy sorted对字典进行排列
查看>>
matplotlib 制作原始数据的散点图
查看>>