• 使用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:

    完。

  • 相关阅读:
    Java并发基础10:原子性操作类的使用
    Java并发基础09. 多个线程间共享数据问题
    Java并发基础08. 造成HashMap非线程安全的原因
    Java并发基础07. ThreadLocal类以及应用技巧
    Java并发基础06. 线程范围内共享数据
    Java并发基础05. 传统线程同步通信技术
    Java并发基础04. 线程技术之死锁问题
    我是如何从通信转到Java软件开发工程师的?
    IOS 判断耳机插入/拔出
    海量数据处理
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/12861381.html
Copyright © 2020-2023  润新知