• 搭建基于qemu的linux开发环境


    在某些情况下,如果我们没有Mini2440开发板,或者开发板某些硬件损坏了,这时候我们还要继续学习linux内核移植和驱动开发,我们应该怎么办,这里我们可以采用qemu搭建linux开发环境。

    在之前的u-boot系列博客中我们已经介绍了u-boot的移植、以及linux内核移植、根文件系统制作。并且尝试将编译后的程序烧录到开发板中运行。而这一节我们将尝试在qemu上搭建这一套开发环境。

    由于我们要使用qemu模拟一个开发板,在安装了qemu之后,在系统环境下输入: qemu-system-arm -M help  可以查看qemu支持的ARM平台的开发板的型号,如下图所示:

    这里是没有smdk2440这块板子的,结合一下网上的资料后发现 有关 vexpress-a9 的资料和讨论最多,所以我们选择这个开发板来进行模拟。

    一、准备工作

    1.1 qemu介绍

    qemu 是一个硬件虚拟化程序( hypervisor that performs hardware virtualization),与传统的 VMware / VirtualBox 之类的虚拟机不同,它可以通过 binary translation 模拟各种硬件平台(比如在 x86 机器上模拟 ARM 处理器)。而 VirtualBox 等更多是通过虚拟化来进行资源隔离,以便在其上运行多个 guest os。

    基于 qemu 的硬件模拟能力,我们可以轻松搭建指定硬件平台的运行实验环境。

    qemu 与 VirtualBox 另一个不同点在于,在 VirtualBox 上必须安装一个完整的操作系统套件,而通过 qemu 我们可以通过参数直接启动到一个裸的 Linux Kernel,连 bootloader 都不需要关心。在此之外,按需配置相关工具套件与启动好的 Kernel 一起工作即可。

    qemu 提供的这种高度可定制化的白盒能力,使得我们可以按需构建快速、轻量级的开发环境,提供流畅的开发体验。

    1.2 安装qemu

    在ubuntu环境下安装qemu:

    sudo apt install qemu

    二、编译linux内核

    2.1 编译配置

    这里我们使用linux-5.2.8源码,执行如下命令:

    cd /work/linux-5.2.8      #源码放在这个路径
    make ARCH=arm vexpress_defconfig 

    配置完成后相应的配置项会保存在 .config 文件中。下一次执行 make menuconfig 时可以 load 这份配置文件,在此基础上进行修改。

    进入菜单配置,进行以下设置:

    make ARCH=arm menuconfig

    System Type -->

    • [ ] Enable the L2x0 outer cache controller  取消该选项,否则qemu运行不起来

    Kernel Features -->

    • [*] Use the ARM EABI to compile the kernel  确保该选项被选择

    2.2 编译内核和模块

    编译内核镜像时,执行:

    make ARCH=arm CROSS_COMPILE=arm-linux-

    编译成功后,arch/arm/boot目录下生成内核镜像文件zImage。

    同时在路径下生成设备树文件:arch/arm/boot/dts/vexpress-v2p-ca9.dtb

    需要注意编译linux内核使用的是arm-linux-gcc4.6.4。

    2.3 运行测试

    编译好内核以后,我们就可以使用qemu启动内核了。只需要使用-kernel参数告诉qemu内核文件的位置即可:

    qemu-system-arm \
    -M vexpress-a9 \
    -m 512M \
    -kernel /work/linux-5.2.8/arch/arm/boot/zImage \
    -dtb /work/linux-5.2.8/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
    -nographic \
    -append "console=ttyAMA0"

    -m指定内存大小;

    -kernel:指定内核文件路径;

    -nographic: 不使用图形界面,只使用串口;

    -dtb: 指定dtb文件路径;

    -append :内核启动参数,这里是告诉内核运行的串口设备是什么;

    也可以使用 qemu-system-arm --help 来查看其他参数的使用说明。

    不出意外的话,就可以在启动窗口中看到内核的启动日志了。在内核启动的最后,会出现一条 panic 日志:

    ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]---

    从日志内容可以看出,内核启动到一定阶段后尝试加载根文件系统,但我们没有指定任何磁盘设备,所以无法挂载根文件系统。

    而且编译出来的内核模块现在也没有用上,内核模块也需要存放到文件系统中供内核需要的时候进行加载。

    所以,接下来需要制作一个磁盘镜像文件供内核作为根文件系统加载。

    注意:如果需要退出qemu:在qemu中输入ctrl+a 抬起后,再输入’x’。

     三、根文件系统制作

     根文件系统的制作,需要使用busybox工具,参考之前的文章Mini2440之yaffs2根文件系统移植,按照这篇文章的前两节进行操作,生成rootfs文件夹即可:

     

    制作SD卡镜像:

    cd /work/sambashare
    dd
    if=/dev/zero of=rootfs.ext4.img bs=1M count=32

    此时会在当前路径下生成rootfs.ext4.img文件:

    -rw-r--r--  1 root root 33554432 2月   8 22:24 rootfs.ext4.img

    显然,rootfs.ext4.img并不是真正的SD卡设备,它只是我们在磁盘上创建的一个文件(为qemu创建的虚拟SD卡)。

    接下来我们会假装它是一张SD卡,并正儿八经的对其进行格式化、挂载等操作。先将它按照ext4文件系统格式进行格式化:

    mkfs.ext4 rootfs.ext4.img

    成功后显示如下:

    把这个镜像文件按照ext4文件系统类型进行挂载,从而方便往里面拷贝内容。

    注意,rootfs.ext4.img不是真正的SD卡,实质是一个文件,一个包含有文件系统格式的文件,也就是一个loop设备。所以挂载的时候要添加loop选项:

    mkdir -p /mnt/rootfs   # 没有才创建
    mount
    -t ext4 -o loop rootfs.ext4.img /mnt/rootfs

    这里我们将rootfs.ext4.img挂载到/mnt/rootfs路径下。

    最后,将我们通过busybox创建的根文件系统拷贝到挂载点/mnt/rootfs上,并卸载rootfs.ext4.img:

    cp -a rootfs/* /mnt/rootfs/
    umount /mnt/rootfs

    此时文件系统将会被拷贝到rootfs.ext4.img文件系统中。

    四、在qemu上利用启动kernel

    制作好根文件系统镜像之后,就可以使用qemu运行kernel了,看看能不能成功挂载根文件系统。运行如下命令:

    qemu-system-arm \
    -M vexpress-a9 \
    -m 512M \
    -kernel /work/linux-5.2.8/arch/arm/boot/zImage \
    -dtb /work/linux-5.2.8/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \
    -nographic \
    -sd /work/sambashare/rootfs.ext4.img \
    -append "root=/dev/mmcblk0 rw console=ttyAMA0"

    启动成功后,最后出现如下图示:

    Please press Enter to activate this console.

    按提示按下 Enter 键之后将会启动 shell,进行到我们熟悉的环境,可以执行各种常用命令了。

    比如运行命令:

    [root@zy:/]# ls
    bin         lib         mnt         sbin        usr
    dev         linuxrc     proc        sys
    etc         lost+found  root        tmp

    设备文件也被自动创建了:

    [root@zy:/]# ls /dev
    console             tty10               tty53
    cpu_dma_latency     tty11               tty54
    full                tty12               tty55
    gpiochip0           tty13               tty56
    gpiochip1           tty14               tty57
    ...

    五、总结

    到了这里,基于qemu的linux开发环境已经搭建成功了。这里从网上找到一张linux内核启动流程图:

    参考文章:

    [1]使用 qemu 搭建内核开发环境

    [2]搭建基于qemu的linux开发环境(部分转载)

    [3]Ubuntu-20.04 双网卡:qemu桥接+上网配置

    [4]QEMU模拟vexpress-a9 搭建Linux kernel运行环境

  • 相关阅读:
    [leetcode]Merge Intervals
    ffmpeg错误隐藏框架分析
    [置顶] Hash查找,散列查找
    VS2008LINK : fatal error LNK1000: Internal error during IncrBuildImage
    HDU1257:最少拦截系统(LIS)
    ubuntu系统使用dnw下载程序
    ubuntu系统使用minicom终端操作说明
    uboot显示logo的方式
    在XC2440的uboot中挂载U盘,利用FAT文件系统读写U盘文件
    不知道黑片,千万别说你懂“U盘”-解读Nand Flash
  • 原文地址:https://www.cnblogs.com/zyly/p/15870515.html
Copyright © 2020-2023  润新知