qemu模拟arm最小化文件系统测试记录

11 篇文章 0 订阅
3 篇文章 0 订阅

-------编译arm内核--------

xy@xydpc:/usr/local/src/linux-4.19.48$ 
export PATH=$PATH:.:/opt/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi/bin
curl -O http://mirror.lzu.edu.cn/kernel/v4.x/linux-4.19.48.tar.xz
tar Jxf linux-4.19.48.tar.xz 

make ARCH=arm help 可以查看支持
make menuconfig ARCH=arm 启动界面配置
如果手工修改了.config文件,可以执行 make ARCH=arm oldconfig加载配置,config.cache缓存文件可以跳过一些验证
make ARCH=arm vexpress_defconfig 利用配置好的模板
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- 编译内核,注意不能省略最后的减号。
xy@xydpc:/usr/local/src/linux-4.19.48$ make modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- 编译模块
CALL scripts/checksyscalls.sh
Building modules, stage 2.
MODPOST 6 modules
应该是已经编译过了。
清理 make ARCH=arm clean 或者 make ARCH=arm distclean

-------编译arm文件系统busybox--------

下载文件并编译,用默认配置即可完成编译。

curl -O https://busybox.net/downloads/busybox-1.29.3.tar.bz2  比wget慢
xy@xydpc:/usr/local/src$ tar jxf busybox-1.29.3.tar.bz2 
xy@xydpc:/usr/local/src$ cd busybox-1.29.3/
$ make menuconfig  默认几乎没有选中小程序
$ make defconfig    一般选择此命令
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-  
make install 直接生成的_install/bin/busybox是宿主机的ELF文件
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install

检查了目录,busybox的arch下并不存在arm目录,也看了其他资料,上面的ARCH参数应该是多余的。

下面开始手工创建文件系统

xy@xydpc:~$ dd if=/dev/zero of=~/rfs2.ext bs=1M count=40
xy@xydpc:~$ mkdir ~/rfs
xy@xydpc:~$ mkfs.ext3 ~/rfs.ext
xy@xydpc:~$ sudo mount ~/rfs.ext ~/rfs
xy@xydpc:~$ sudo cp -r /usr/local/src/busybox-1.29.3/_install/* ~/rfs
xy@xydpc:~$ cd ~/rfs
xy@xydpc:~/rfs$ ls 
bin  linuxrc  lost+found  sbin  usr
xy@xydpc:~/rfs$ sudo mkdir dev etc proc  sys tmp
xy@xydpc:~/rfs$ cd dev
xy@xydpc:~/rfs/dev$ sudo mknod -m 660 console c 5 1
xy@xydpc:~/rfs/dev$ sudo mknod -m 660 null c 1 3
xy@xydpc:~/rfs/dev$ cd ../
xy@xydpc:~/rfs$ sudo mkdir etc/init.d
xy@xydpc:~/rfs$ sudo vi etc/init.d/rcS
#! /bin/sh
/bin/mount -a
xy@xydpc:~/rfs$ sudo vi etc/fstab
proc    /proc   proc    defaults    0   0
none    /tmp    ramfs   defaults    0   0
mdev    /dev    ramfs   defaults    0   0
sysfs   /sys    sysfs   defaults    0   0
xy@xydpc:~/rfs$ sudo vi etc/inittab  当时实际未创建该文件
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/bin/umount -a -r
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff –a

xy@xydpc:~/rfs$ sudo vi etc/group
root:*:0:
xy@xydpc:~/rfs$ sudo vi etc/passwd
root::0:0:root:/:/bin/sh
xy@xydpc:~/rfs$ sudo chown -R root:root .

问题1:找不到init文件

VFS: Mounted root (ext3 filesystem) on device 179:0.
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
Run /etc/init as init process
Run /bin/init as init process
Run /bin/sh as init process
Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.

检查发现是动态链接的

xy@xydpc:~/rfs/bin$ arm-linux-gnueabi-readelf -d ./busybox 

Dynamic section at offset 0xaaf08 contains 26 entries:
  标记        类型                         名称/值
 0x00000001 (NEEDED)                     共享库:[libm.so.6]
 0x00000001 (NEEDED)                     共享库:[libresolv.so.2]
 0x00000001 (NEEDED)                     共享库:[libc.so.6]

xy@xydpc:~/rfs$ cd /opt/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi/lib/
xy@xydpc:/opt/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi$ sudo cp ./arm-linux-gnueabi/libc/lib/libm-2.25.so ~/rfs/lib
xy@xydpc:~/rfs/lib$ sudo ln -s libm-2.25.so libm.so.6

空间不足了,继续折腾,库文件比较大,测试了放在目录/lib或者/bin都是不可行的,因为此时init也是到busybox的链接,init本身都还没有加载,无法具备加载链接库文件的功能。

$ dd if=/dev/zero of=~/rfs2.ext bs=1M count=40
$ mkfs.ext3 ~/rfs2.ext
$ sudo umount ~/rfs
$ sudo mount ~/rfs.ext /mnt
$ sudo mount ~/rfs2.ext ~/rfs
$ sudo cp -rp /mnt/* ~/rfs
cd /opt/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi/arm-linux-gnueabi/libc/lib
sudo cp libm-2.25.so ~/rfs/lib
sudo cp libc-2.25.so ~/rfs/lib
sudo cp libresolv-2.25.so ~/rfs/lib
xy@xydpc:~/rfs/lib$ sudo ln -s libc-2.25.so libc.so.6
xy@xydpc:~/rfs/lib$ sudo ln -s libm-2.25.so libm.so.6
xy@xydpc:~/rfs/lib$ sudo ln -s libresolv-2.25.so libresolv.so.2

重新编译为静态文件

$ make defconfig   
Settings  ---> --- Build Options  
    [*] Build static binary (no shared libs) 

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-  
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install

xy@xydpc:/usr/local/src/busybox-1.29.3/_install/bin$ file busybox 
busybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=cb8df546bfd3e37b86def4cdd3dffc9e586d795e, stripped

xy@xydpc:/usr/local/src/busybox-1.29.3/_install$ sudo cp -r * ~/rfs/
xy@xydpc:~/rfs/bin$ arm-linux-gnueabi-readelf -d busybox 

There is no dynamic section in this file.

新报错:rcS权限及tty文件不存在问题

can’t run ‘/etc/init.d/rcS’: Permission denied
can’t open /dev/tty4: No such file or directory
方法
xy@xydpc:~/rfs$ sudo chmod 744 etc/init.d/rcS
xy@xydpc:~/rfs$ sudo mknod dev/tty1 c 4 1
xy@xydpc:~/rfs$ sudo mknod dev/tty2 c 4 2
xy@xydpc:~/rfs$ sudo mknod dev/tty3 c 4 3
xy@xydpc:~/rfs$ sudo mknod dev/tty4 c 4 4
没有作用,sudo mv rcS bak.rcS后可以进入命令行。
恢复rcS,增加inittab文件后可以进入命令行。但是df发现都没有挂载文件系统。
找不到的tty的错误原因是:参考root@xydpc:/usr/local/src/busybox-1.29.3/examples# vi inittab的解释,当未指定inittab时,默认的配置包含了tty2/3/4

# Note: BusyBox init works just fine without an inittab. If no inittab is
# found, it has the following default behavior:
#         ::sysinit:/etc/init.d/rcS
#         ::askfirst:/bin/sh
#         ::ctrlaltdel:/sbin/reboot
#         ::shutdown:/sbin/swapoff -a
#         ::shutdown:/bin/umount -a -r
#         ::restart:/sbin/init
#         tty2::askfirst:/bin/sh
#         tty3::askfirst:/bin/sh
#         tty4::askfirst:/bin/sh

找不到tty的问题2:修改inittab配置

之前做的那个busybox,也是报错找不到tty,去掉tty2::askfirst:-/bin/sh前面的tty2后解决。
报错找不到null设备的,但回车可以进入命令行,注释掉这一行 ::respawn:/sbin/getty -L ttyAMA0 115200 xterm
修改后的文件如下,也可以正常进入了。

[root@(none) etc]# cat inittab
::sysinit:/etc/init.d/rcS
#::respawn:/sbin/getty -L ttyAMA0 115200 xterm
#::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
[root@(none) etc]#

注意检查inittab文件的一些中文字符,重启后正常。

EXT4-fs (mmcblk0): mounting ext3 file system using the ext4 subsystem
random: fast init done
EXT4-fs (mmcblk0): warning: mounting fs with errors, running e2fsck is recommended
EXT4-fs (mmcblk0): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext3 filesystem) on device 179:0.
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
random: crng init done
/bin/sh: can't access tty; job control turned off   这里仍然有个报错
~ # df 
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root                45478     21981     20937  51% /
~ # cat /proc/cpuinfo
processor	: 0
model name	: ARMv7 Processor rev 0 (v7l)
BogoMIPS	: 508.72
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpd32 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc09
CPU revision	: 0

Hardware	: ARM-Versatile Express
Revision	: 0000
Serial		: 0000000000000000
~ # ls /sys/devices/
armv7_cortex_a9  platform         system           uprobe
breakpoint       software         tracepoint       virtual
~ #

正确情况inittab是有减号的,表示需要进行交互,也就是需要按一下回车键。
::respawn:-/bin/sh

/dev目录为空的问题

启动后发现找不到手动在rfs.ext3文件系统中创建的文件,注释掉etc/fstab中的行
#mdev /dev ramfs defaults 0 0
重启后问题解决。

验证mdev加载问题

参考资料 mdev详解
移走/dev下的文件,启动日志

EXT4-fs (mmcblk0): mounting ext3 file system using the ext4 subsystem
random: fast init done
EXT4-fs (mmcblk0): warning: mounting fs with errors, running e2fsck is recommended
EXT4-fs (mmcblk0): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext3 filesystem) on device 179:0.
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
random: crng init done

检查启动情况

~ # mount 
/dev/root on / type ext3 (rw,relatime)
proc on /proc type proc (rw,relatime)
none on /tmp type ramfs (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
~ # ls /dev
bb
~ # cat /etc/fstab
proc    /proc   proc    defaults    0   0
none    /tmp    ramfs   defaults    0   0
#mdev    /dev    ramfs   defaults    0   0
sysfs   /sys    sysfs   defaults    0   0

手动挂载mdev,/dev并无变化,仍然为空

~ # mount -t ramfs mdev /dev
~ # mount 
/dev/root on / type ext3 (rw,relatime)
proc on /proc type proc (rw,relatime)
none on /tmp type ramfs (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
mdev on /dev type ramfs (rw,relatime)
~ # ls /dev
~ #

执行mdev -s命令,自动生成多个设备文件。如果需要可以写入到rcS脚本。

~ # mdev -s
~ # ls /dev
console             tty1                tty52
...

对之前的~/armroot/a9rootfs.ext3文件系统再次测试:

[root@(none) ~]# cat /etc/fstab
proc	/proc	proc	defaults    0	0
none    /tmp    ramfs   defaults    0   0
#mdev    /dev    ramfs   defaults    0   0  //去掉mdev的挂载
sysfs   /sys    sysfs   defaults    0   0
[root@(none) ~]# vi /etc/inittab
[root@(none) ~]# cat /etc/inittab
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty -L ttyAMA0 115200 xterm  去掉注释
#::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
[root@(none) ~]# 
[root@(none) ~]# cat /etc/init.d/rcS  保持不变
#! /bin/sh

/bin/mount -a
[root@(none) ~]# reboot

重启后运行正常,日志如下:

EXT4-fs (mmcblk0): mounting ext3 file system using the ext4 subsystem
random: fast init done
EXT4-fs (mmcblk0): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext3 filesystem) on device 179:0.
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
random: crng init done

Please press Enter to activate this console. 

MiniRoot FileSystem is Ready ... 
[root@(none) ~]# 
[root@(none) ~]# exit 

Please press Enter to activate this console. 

MiniRoot FileSystem is Ready ... 
[root@(none) ~]# exit

Please press Enter to activate this console. 

MiniRoot FileSystem is Ready ... 
[root@(none) ~]# shutdown -h now
-/bin/sh: shutdown: not found
[root@(none) ~]# 

根目录问题

前面的启动日志有报错:
EXT4-fs (mmcblk0): warning: mounting fs with errors, running e2fsck is recommended
运行一段时间会出现下面的提示
EXT4-fs (mmcblk0): error count since last fsck: 4
EXT4-fs (mmcblk0): initial error at time 1559970622: ext4_mb_generate_buddy:757
EXT4-fs (mmcblk0): last error at time 1560036552: ext4_mb_generate_buddy:747
关闭目标机器,在宿主机修复文件系统
xy@xydpc:~$ sudo e2fsck ./rfs.ext
重启没有报错(观察了约10分钟)。
虚拟机不能shutdown,只能关闭窗口,关闭前执行sync。关闭窗口启动日志没有再报错。

整个文件系统很小,不到3M,还有网卡可配置

~ # uname -a
Linux (none) 4.19.48 #1 SMP Fri Jun 7 16:16:47 CST 2019 armv7l GNU/Linux
~ # df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                44.4M      2.7M     39.2M   6% /
~ # ip addr add  192.168.199.223/24 dev eth0
~ # ip ad
1: lo: <LOOPBACK> mtu 65536 qdisc noop qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 192.168.199.223/24 scope global eth0
       valid_lft forever preferred_lft forever
~ #

ping不通主机,qemu-system-arm不了解怎么配置互联。

-------qemu模拟--------

qemu-system-arm -M vexpress-a9 -m 512M -dtb /usr/local/src/linux-4.19.48/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel /usr/local/src/linux-4.19.48/arch/arm/boot/zImage -nographic -append “root=/dev/mmcblk0 rw console=ttyAMA0” -sd ~/rfs.ext

图形化运行正常
xy@xydpc:~/armroot/rfs1$ qemu-system-arm -M vexpress-a9 -m 512M -dtb vexpress-v2p-ca9.dtb -kernel zImage -append "root=/dev/mmcblk0 rw " -sd a9rootfs.ext3
更换根正常
xy@xydpc:~/armroot/rfs1$ qemu-system-arm -M vexpress-a9 -m 512M -dtb vexpress-v2p-ca9.dtb -kernel zImage -append "root=/dev/mmcblk0 rw " -sd …/rfs.ext
但更换内核就弹出黑色图形窗口,权限也一样了
xy@xydpc:~/armroot$ sudo chown libvirt-qemu:kvm zImage rfs.ext vexpress-v2p-ca9.dtb
sudo chmod 666 rfs.ext
xy@xydpc:~/armroot/rfs1$ qemu-system-arm -M vexpress-a9 -m 512M -dtb …/vexpress-v2p-ca9.dtb -kernel …/zImage -append "root=/dev/mmcblk0 rw " -sd …/rfs.ext
看来和内核配置有关。

-------内核补丁-看书笔记--------

make ARCH=arm distclean
创建补丁 diff -Naurp kernel-tree kernel-source > patch.file
检查补丁 ./kernel-source/checkpatch.pl
测试补丁 patch -p1 --dry-run < /path/to/patch.file
应用补丁 patch -p1 < /path/to/patch.file

-------常用开源软件-看书笔记--------

DirectFB图形库
Dropbear ssh2软件,含服务器和客户端
QT 图形化环境
JamVM JAVA虚拟机
Rzsz x/z-modem串口传输文件
netcat 管道收发数据,支持shell
tinyxml 解析xml
micro_httpd http服务器
tupid-ftpd ftp服务器
quagga 路由软件
tslib 触摸屏接口
fgetty tty登录

性能分析工具 gprof 编译时增加 -g -pg选项
内存泄漏检测工具 dmalloc mpatrol 静态工具 splint

-------挂载mtdram--------

# ls -l /proc/mtd 
-r--r--r--    1 root     root             0 Jan  1 02:05 /proc/mtd
# cat /proc/mtd
dev:    size   erasesize  name
# ls -l /dev/mt*
ls: /dev/mt*: No such file or directory
# modprobe mtdram total_size=65536 erase_size=128
modprobe: can't open 'modules.dep': No such file or directory
#
在机顶盒无法加载模块mtdram,对应软件包 mtd-tools
在台式机查看
$ lsmod |grep mtdram
mtdram                 16384  0
mtd                    57344  5 mtdram,cmdlinepart,jffs2,cramfs
#modprobe mtdram total_size=65536 erase_size=128
$cat /proc/mtd
dev:    size   erasesize  name
mtd0: 04000000 00020000 "mtdram test device"

# dd if=rootfs.jffs2 of=/dev/mtdblock0  书上的这个文件,实际不存在
# mount -t jffs2 /dev/mtd0 /mnt/    书上挂载的又是mtd0

小结

整个文件系统很小,不到3M,内核4M,还有网卡可配置;最小内存32M可启动,笔记本电脑(Intel® Core™ i5-5200U CPU @ 2.20GHz)虚拟时的时间不到5秒。
折腾了好几天,问题基本上解决了,基本上理解了内核和文件系统,但是bootloader还是未能进行验证。
从网络上找的配置,其中fstab的/dev挂载是个大坑,覆盖掉了原有的/dev文件,而且也没有自动生成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值