Qemu 4.1linux
vexpress-ca9shell
爲了減少linux內核的大小,能夠把一些外設驅動編譯成內核模塊,可是在啓動ubuntu的時候,須要讀取flash,可是此時flash的驅動模塊存放在ubuntu文件系統中。爲了解決這樣的問題,能夠使用ramdisk內存文件系統,將必備的驅動模塊,好比這裏的flash驅動模塊放到ramdisk中,當uboot引導linux時,能夠將ramdisk和內核鏡像先加載到內存,啓動內核時,會將ramdisk在內存中的內存地址傳給內核。express
當內核啓動後,會先將ramdisk做爲根文件系統,而後使用insmod加載flash驅動,就能夠訪問存放有ubuntu文件系統的塊設備節點,最後再經過命令將根文件系統切換爲ubuntu文件系統。ubuntu
這裏爲了簡單起見,咱們沒有把存儲器驅動編譯成內核模塊,只是演示一下從ramdisk切到ubuntu的過程。bash
原先直接啓動ubuntu使用的命令是:app
kernel_dir=./linux-4.14.13 kernel_image=${kernel_dir}/arch/arm/boot/zImage dtb_image=${kernel_dir}/arch/arm/boot/dts/vexpress-v2p-ca9.dtb sudo qemu-system-arm \ -M vexpress-a9 \ -m 1024M \ -smp 4 \ -kernel ${kernel_image} \ -append "noinitrd root=/dev/vda1 rw rootfstype=ext4 console=ttyAMA0,115200" \ -dtb ${dtb_image} \ -drive if=none,file=./ubuntu_rootfs/ubuntu.fulldisk,id=hd0 \ -device virtio-blk-device,drive=hd0 \ -nic tap \ -serial stdio
其中vda是一個虛擬磁盤,它的第一個分區中存放的是ubuntu根文件系統。oop
如今,若是使用ramdisk的話,修改啓動命令:spa
kernel_dir=./linux-4.14.13 kernel_image=${kernel_dir}/arch/arm/boot/zImage dtb_image=${kernel_dir}/arch/arm/boot/dts/vexpress-v2p-ca9.dtb sudo qemu-system-arm \ -M vexpress-a9 \ -m 1024M \ -smp 4 \ -kernel ${kernel_image} \ -dtb ${dtb_image} \ -drive if=none,file=./ubuntu_rootfs/ubuntu.fulldisk,id=hd0 \ -device virtio-blk-device,drive=hd0 \ -append "root=/dev/ram0 rw rootfstype=ext4 console=ttyAMA0 init=/linuxrc ignore_loglevel" \ -initrd ./rootfs/ramdisk.img \ -nic tap \ -serial stdio
爲此,須要修改ramdisk的內容,原先我用的ramdisk中的根文件系統使用busybox編譯生成的,/linuxrc是指向/bin/busybox的軟鏈接。須要對此進行修改,修改後的ramdisk內容以下(爲了簡單明瞭,我僅保留必備的一些命令):code
. ├── bin │ ├── busybox │ ├── cd -> busybox │ ├── chroot -> busybox │ ├── echo -> busybox │ ├── exec -> busybox │ ├── mdev -> busybox │ ├── mkdir -> busybox │ ├── mount -> busybox │ ├── pivot_root -> busybox │ ├── sh -> busybox │ └── umount -> busybox ├── dev ├── linuxrc └── sys
其中linuxrc是一個shell腳本,內容以下:blog
#!/bin/sh echo "hello world" echo "mount -t sysfs sysfs /sys" mount -t sysfs sysfs /sys echo "mdev -s" mdev -s echo "mkdir /newroot" mkdir /newroot echo "mount -t ext4 /dev/vda1 /newroot" mount -t ext4 /dev/vda1 /newroot echo "sys" umount /sys echo "cd /newroot" cd /newroot echo "mkdir -p oldroot" mkdir -p oldroot echo "pivot_root . oldroot" pivot_root . oldroot echo "exec chroot . /sbin/init <dev/console >dev/console 2>&1" exec chroot . /sbin/init <dev/console >dev/console 2>&1
若是ramdisk裏有須要加載的flash驅動,須要先insmod,而後才能看到/dev/vda1。
ubuntu文件系統中/sbin/init是一個軟鏈接,實際指向的是/lib/systemd/systemd。
製做ramdisk鏡像的命令:
#!/bin/bash sudo dd if=/dev/zero of=ramdisk bs=1M count=32 sudo mkfs.ext4 -F ramdisk sudo mkdir -p tmpfs sudo mount -t ext4 ramdisk ./tmpfs/ -o loop sudo cp -raf rootfs/* tmpfs/ sudo umount tmpfs sudo gzip --best -c ramdisk > ramdisk.gz sudo mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
下面是啓動log:
完。