qemu+uboot+kernel+nfs文件系统
版本介绍 ubuntu16
参考学习:
- http://edu.51cto.com/course/10445.html (其实看博客一直没有搞定nfs挂载文件系统的问题,最后学习视频教程,提问才搞定)
- https://blog.csdn.net/nxcxl88/article/details/53244754
- http://www.cnblogs.com/pengdonglin137/p/5023875.html
安装ARM交叉编译工具
下载编译uboot
-
uboot下载地址 http://ftp.denx.de/pub/u-boot/
我自己下载的是u-boot-2017.05,原因编译最新的uboot报错提示说要求6.0以上的gcc编译工具
-
配置编译uboot
export ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make vexpress_ca9x4_defconfig make -j8
编译kernel
- 下载kernel https://www.kernel.org/
我下载的是linux-4.18.11 -
配置编译kernel
export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabi- make vexpress_defconfig make zImage -j8 make modules -j8 make LOADADDR=0x60003000 uImage -j8 make dtbs
编译busybox文件系统
-
下载busybox https://busybox.net/downloads/
我下载的是 busybox-1.22.1
-
配置编译busybox
bash
export ARCH=armexport ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make menuconfig
make -j8
make install注意make menuconfig 配置busybox为静态编译 Busybox Settings ---> Build Options ---> [*] Build BusyBox as a static binary (no shared libs)
-
添加最简单文件系统
sudo mkdir -p rootfs/dev
sudo mknod rootfs/dev/tty1 c 4 1
sudo mknod rootfs/dev/tty2 c 4 2
sudo mknod rootfs/dev/tty3 c 4 3
sudo mknod rootfs/dev/tty4 c 4 4
安装qemu
安装nfs服务
-
安装nfs服务
sudo apt-get install nfs-kernel-server
-
创建共享文件夹
sudo chmod 777 /root/rootfs
-
修改/etc/exports文件
sudo vim /etc/exports
添加 /home/pc/share *(rw,insecure,sync,no_root_squash) -
启动nfs服务
/etc/init.d/rpcbind restart
/etc/init.d/nfs-kernel-server restart -
验证nfs是否可以正常使用
- 显示共享的nfs目录: showmount -e
$ showmount -e
Export list for ubuntu:
/home/pc/share * - 尝试挂载一下/home/pc/share
$mkdir sss
$sudo mount -t nfs 127.0.0.1:/home/pc/share ./sss/
$sudo umount ./sss
- 显示共享的nfs目录: showmount -e
安装配置tftp服务
-
安装tftp程序
apt-get install tftp-hpa tftpd-hpa xinetd
-
备份原始的配置文件
sudo cp /etc/default/tftpd-hpa /etc/default/tftpd-hpa_back
-
修改配置文件:/etc/default/tftpd-hpa
# /etc/default/tftpd-hpa TFTP_USERNAME="tftp" TFTP_DIRECTORY="/var/lib/tftpboot" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="-l-c-s"
创建tftp目录:
mkdir -p /var/lib/tftpboot; chmod 777 /var/lib/tftpboot
重启tftp服务:
$ /etc/init.d/tftpd-hpa restart
把 uboot,dtb,uImage 文件拷贝到 /var/lib/tftpboot
测试tft服务是否正常 (我的VMware主机ip是192.168.227.128)
$ tftp 192.168.227.128 tftp> get uImage tftp> q
配置VMware 和的网络 qemu
VMware 需要配置成NAT模式, 在VMware的桥接模式下面,目前qemu无法成功连接网络
VMware也不能设置成静态ip地址,设置成静态ip地址也是无法连接网络
-
修改 /etc/network/interfaces
cat /etc/network/interfaces # interfaces(5) file used by ifup(8) and ifdown(8) auto lo iface lo inet loopback auto ens33 auto br0 iface br0 inet dhcp bridge_ports ens33
- 然后重启虚拟机, 运行ifconfig
- 检查测试VMware网络
- ping 192.168.0.106 (虚拟机ping实体机)
- ping www.baidu.com (虚拟机ping外网)
启动qemu系统
-
启动uboot,ping通ubuntu以后,手动传入kernel,dtb,逐渐挂载启动文件系统
sudo qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M -net nic,vlan=0 -net tap,vlan=0,ifname=tap0
U-Boot 2017.05-gcac7f3d-dirty (Oct 04 2018 - 22:48:17 -0700) DRAM: 512 MiB WARNING: Caches not enabled Flash: 128 MiB MMC: MMC: 0 **** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: smc911x-0 Hit any key to stop autoboot: 0 => => ping 192.168.227.128 smc911x: MAC 52:54:00:12:34:56 smc911x: detected LAN9118 controller smc911x: phy initialized smc911x: MAC 52:54:00:12:34:56 *** ERROR: `ipaddr' not set smc911x: MAC 52:54:00:12:34:56
启动以后尝试ping 192.168.227.128 在qemu的uboot里面ping一下虚拟机失败了(192.168.227.128是我ubuntu的ip地址)
原因是没有添加,uboot的ip地址。为了可以使用tftp服务读入kernel,和dtb还需要,添加serverip地址。
下面添加ipaddr和serverip=> setenv ipaddr 192.168.227.8; => setenv serverip 192.168.227.128; => ping 192.168.227.128 smc911x: MAC 52:54:00:12:34:56 smc911x: detected LAN9118 controller smc911x: phy initialized smc911x: MAC 52:54:00:12:34:56 Using smc911x-0 device smc911x: MAC 52:54:00:12:34:56 host 192.168.227.128 is alive =>
可以发现ping 192.168.227.128 成功了。
应该先把uboot和dtb文件拷贝到tftp的默认目录中。
运行tftp 0x60003000 uImage;
tftp 0x60500000 vexpress-v2p-ca9.dtb;=> tftp 0x60003000 uImage; smc911x: MAC 52:54:00:12:34:56 smc911x: detected LAN9118 controller smc911x: phy initialized smc911x: MAC 52:54:00:12:34:56 Using smc911x-0 device TFTP from server 192.168.227.128; our IP address is 192.168.227.8 Filename 'uImage'. Load address: 0x60003000 Loading:############################# #################################### #################################### 9.3 MiB/s done Bytes transferred = 4096816 (3e8330 hex) smc911x: MAC 52:54:00:12:34:56 => tftp 0x60500000 vexpress-v2p-ca9.dtb; smc911x: MAC 52:54:00:12:34:56 smc911x: detected LAN9118 controller smc911x: phy initialized smc911x: MAC 52:54:00:12:34:56 Using smc911x-0 device TFTP from server 192.168.227.128; our IP address is 192.168.227.8 Filename 'vexpress-v2p-ca9.dtb'. Load address: 0x60500000 Loading: #3.4 MiB/s done Bytes transferred = 14430 (385e hex) smc911x: MAC 52:54:00:12:34:56 =>
继续设置启动参数
这了的192.168.227.128是我ubuntu的ip地址, 192.168.227.8是qemu开发板的ip地址setenv bootargs ‘root=/dev/nfs rw nfsroot=192.168.227.128:/home/pc/share/rootfs init=/linuxrc ip=192.168.227.8 console=ttyAMA0’;
启动系统 运行
bootm 0x60003000 - 0x60500000;
=> setenv bootargs ‘root=/dev/nfs rw nfsroot=192.168.227.128:/home/pc/share/rootfs init=/linuxrc ip=192.168.227.8 console=ttyAMA0’; => bootm 0x60003000 - 0x60500000; ## Booting kernel from Legacy Image at 60003000 ... Image Name: Linux-4.18.11 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 4096752 Bytes = 3.9 MiB Load Address: 60003000 Entry Point: 60003000 Verifying Checksum ... OK ## Flattened Device Tree blob at 60500000 Booting using the fdt blob at 0x60500000 Loading Kernel Image ... OK Loading Device Tree to 7fed4000, end 7feda85d ... OK Starting kernel ...
最后系统就启动了
/ # ls bin dev linuxrc sbin usr / # / #
-
修改编译uboot直接启动文件系统
修改 include/configs/vexpress_common.h 的patch
diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h index 0880b62..77a87e7 100644 --- a/include/configs/vexpress_common.h +++ b/include/configs/vexpress_common.h @@ -184,8 +184,14 @@ /* Basic environment settings */ #define CONFIG_BOOTCOMMAND \ - "run distro_bootcmd; " \ - "run bootflash; " + "setenv serverip 192.168.227.128; \ + setenv ipaddr 192.168.227.8; \ + tftp 0x60003000 uImage; \ + tftp 0x60500000 vexpress-v2p-ca9.dtb; \ + setenv bootargs 'root=/dev/nfs rw \ + nfsroot=192.168.227.128:/home/pc/share/rootfs init=/linuxrc \ + ip=192.168.227.8 console=ttyAMA0'; \ + bootm 0x60003000 - 0x60500000; " #define BOOT_TARGET_DEVICES(func) \ func(MMC, mmc, 1) \
可以看到其实,这个修改就是把刚刚手动输入的命令,直接写入到了uboot二进制文件里面
然后启动qemu,命令和刚刚一样sudo qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M -net nic,vlan=0 -net tap,vlan=0,ifname=tap0
启动效果
VFS: Mounted root (nfs filesystem) on device 0:13. Freeing unused kernel memory: 1024K random: fast init done can't run '/etc/init.d/rcS': No such file or directory Please press Enter to activate this console. / # / # / # ls bin dev linuxrc sbin usr / #
-
直接启动kernel ,启动文件系统
好像,直接启动kernel就不能挂载,不能挂载nfs文件系统。
- 未完待续
完善busybox文件系统
-
添加目录必须的
mkdir proc sys tmp var lib
-
拷贝库文件
sudo cp -P /usr/arm-linux-gnueabi/lib/* rootfs/lib/
-
添加 /etc/inittab
::sysinit:/etc/init.d/rcS #::respawn:-/bin/sh #tty2::askfirst:-/bin/sh #::ctrlaltdel:/bin/umount -a -r console::askfirst:-/bin/sh ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r
-
添加 /etc/init.d/rcS
#! /bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin LD_LIBRARY_PATH=/lib export PATH LD_LIBRARY_PATH mount -a mkdir -p /dev/pts mount -t devpts devpts /dev/pts mdev -s mkdir -p /var/lock echo "-----------------------------------" echo " welcome to A9 vexpress board" echo "-----------------------------------"
-
添加 /etc/fstab
proc /proc proc defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 sysfs /sys sysfs defaults 0 0 tmpfs /dev tmpfs defaults 0 0 var /dev tmpfs defaults 0 0 ramfs /dev ramfs defaults 0 0
-
添加 /etc/profile
PS1='liucheng@vexpress:\w # ' export PS1
小技巧
-
ctrl+a 然后按 x , 可以关闭qemu退出
-
制作sd卡启动的命令
dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32 mkfs.ext3 a9rootfs.ext3 sudo mkdir tmpfs sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop cp -r rootfs/* tmpfs/ sudo umount tmpfs
问题记录
rmmod: can’t change directory to ‘/lib/modules’: No such file or directory
解决方案 mkdir -p /lib/modules/4.18.11