使用ramdisk啟動ubuntu文件系統


環境

Qemu 4.1

vexpress-ca9

 

概述

  為了減小linux內核的大小,可以把一些外設驅動編譯成內核模塊,但是在啟動ubuntu的時候,需要加載存放在ubuntu文件系統中的flash驅動,而ubuntu文件系統本身也存放在flash中。為了解決這樣的問題,可以使用ramdisk內存文件系統,將必備的驅動模塊,比如這里的flash驅動模塊放到ramdisk中,當uboot引導linux時,可以將ramdisk和內核鏡像先加載到內存,啟動內核時,會將ramdisk在內存中的內存地址傳給內核。

  當內核啟動后,會先將ramdisk作為根文件系統,然后使用insmod加載存放在ramdisk文件系統中的flash驅動,就可以訪問存放有ubuntu文件系統的塊設備節點,最后再通過命令將根文件系統切換為ubuntu文件系統。

 

正文

  這里為了簡單起見,沒有把存儲器驅動編譯成內核模塊,只是演示一下從ramdisk切到ubuntu的過程。

  原先直接啟動ubuntu使用的命令是:

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根文件系統。

  現在,如果使用ramdisk啟動ubuntu的話,修改啟動命令:

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內容如下(為了簡單明了,我僅保留必備的一些命令):

.
├── 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腳本,內容如下:

#!/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:

 

完。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM