• 用Qemu模拟vexpress-a9 (一) --- 搭建Linux kernel调试环境


    参考:

    http://blog.csdn.net/linyt/article/details/42504975

     

    环境介绍:

    Win7 64 + Vmware 11 + ubuntu14.04 32

    u-boot 版本:u-boot-2015-04

    Linux kernel版本:linux-3.16.y

    busybox版本:1_24_stable

    交叉编译工具链:arm-linux-gnueabi-

    qemu版本:stable-2.4

     

    下载Linux内核

    下载内核有两种方法,一种是用git直接下载内核代码树,方便后面的内核开发。另一种是直接到内核社区下载对应版本的源码包。我采用第一种方法,但后面发现 主线上3.18版本和后面版本的代码,使用这种搭建方法运行不起来。目前未查明问题的根因。如果读者想快速搭建成功,建议选用3.16版本的内核进行搭建。(这个刚开始我用的是linux-4.4版本的内核,用qemu-system-arm无法运行,然后我就改用linux-3.16的内核了

    方法一:使用git

     git clonegit://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

     

    方法二:直接下载3.16源代码包

     wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.tar.xz

     

    安装arm的交叉编译工具链

     想必做嵌入式开发的朋友,对交叉编译工具链不陌生。如果你订制一个交叉编译工具链,建议你使用crosstool-ng开源软件来构建。但在这里建议直接安装arm的交叉编译工具链:

    sudo apt-get install gcc-arm-linux-gnueabi

    编译Linux内核

     生成vexpress开发板子的config文件:

    make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16  vexpress_defconfig
     
    然后执行如下命令:
    make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 menuconfig

    将:

    System Type  --->

        [ ] Enable the L2x0 outer cache controller

    即, 把 Enable the L2x0 outer cache controller 取消, 否则Qemu会起不来, 暂时还不知道为什么。

     

    编译:

    make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 zImage -j2

    生成的内核镱像位于./out_vexpress_3_16/arch/arm/boot/zImage, 后续qemu启动时需要使用该镜像。

    下载和安装qemu模拟器

    下载qemu,我用的版本是2.4版本,可以用如下方式下载,然后checkout到2.4分支上即可

    git clone git://git.qemu-project.org/qemu.git
    cd qemu
    git checkout remotes/origin/stable-2.4 -b stable-2.4

    配置qemu前,需要安装几个软件包:

    sudo apt-get install zlib1g-dev
    
    sudo apt-get install libglib2.0-0
    
    sudo apt-get install libglib2.0-dev
    
    sudo apt-get install libtool
    
    sudo apt-get install libsdl1.2-dev 

    sudo apt-get install autoconf

    配置qemu,支持模拟arm架构下的所有单板,我为了使qemu的代码干净一些,采用如下方式编译,最后生成的中间文件都在build下

    mkdir build
    cd build
    ../qemu/configure --target-list=arm-softmmu --audio-drv-list=

    编译和安装:

    make
    make install

    查看qemu支持哪些板子

    qemu-system-arm -M help

    测试qemu和内核能否运行成功

    qemu已经安装好了,内核也编译成功了,到这里最好是测试一下,编译出来的内核是否OK,或者qemu对vexpress单板支持是否够友好。

    运行命令很简单:

    qemu-system-arm 
        -M vexpress-a9 
        -m 512M 
        -kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage 
        -nographic 
        -append "console=ttyAMA0"
    可以把上面的命令放到一个脚本中执行。

      如果看到内核启动过程中的打印,说明前的搭建是成功的。

    Booting Linux on physical CPU 0x0
    Initializing cgroup subsys cpuset
    Linux version 3.16.7 (root@ubuntu) (gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-12ubuntu1) ) #5 SMP Sat Dec 5 21:17:17 PST 2015
    CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c53c7d
    CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
    Machine: ARM-Versatile Express
    Memory policy: Data cache writeback
    CPU: All CPU(s) started in SVC mode.
    sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956969942ns
    PERCPU: Embedded 7 pages/cpu @9fbed000 s7552 r8192 d12928 u32768
    Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
    Kernel command line: console=ttyAMA0
    PID hash table entries: 2048 (order: 1, 8192 bytes)
    Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
    Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
    Memory: 513272K/524288K available (4563K kernel code, 190K rwdata, 1292K rodata, 239K init, 149K bss, 11016K reserved)
    Virtual kernel memory layout:
    ......
    
    VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
    Please append a correct "root=" boot option; here are the available partitions:
    1f00          131072 mtdblock0  (driver?)
    Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
    CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.16.7 #5
    [<8001507c>] (unwind_backtrace) from [<800115d4>] (show_stack+0x10/0x14)
    [<800115d4>] (show_stack) from [<8044f9c8>] (dump_stack+0x74/0x90)
    [<8044f9c8>] (dump_stack) from [<8044ce08>] (panic+0x90/0x1fc)
    [<8044ce08>] (panic) from [<805c210c>] (mount_block_root+0x1a0/0x254)
    [<805c210c>] (mount_block_root) from [<805c22b4>] (mount_root+0xf4/0x114)
    [<805c22b4>] (mount_root) from [<805c2400>] (prepare_namespace+0x12c/0x190)
    [<805c2400>] (prepare_namespace) from [<805c1d8c>] (kernel_init_freeable+0x1f4/0x240)
    [<805c1d8c>] (kernel_init_freeable) from [<8044adb8>] (kernel_init+0x8/0xec)
    [<8044adb8>] (kernel_init) from [<8000e4b8>] (ret_from_fork+0x14/0x3c)
    ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

    这里简单介绍下qemu命令的参数:

    -M vexpress-a9 模拟vexpress-a9单板,你可以使用-M ?参数来获取该qemu版本支持的所有单板

    -m 512M 单板运行物理内存512M

    -kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage  告诉qemu单板运行内核镜像路径

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

    -append "console=ttyAMA0" 内核启动参数,这里告诉内核vexpress单板运行,串口设备是哪个tty。

    注意:

    我每次搭建,都忘了内核启动参数中的console=参数应该填上哪个tty,因为不同单板串口驱动类型不尽相同,创建的tty设备名当然也是不相同的。那 vexpress单板的tty设备名是哪个呢? 其实这个值可以从生成的.config文件CONFIG_CONSOLE宏找到。

    如果搭建其它单板,需要注意内核启动参数的console=参数值,同样地,可从生成的.config文件中找到。

    此时只能通过杀死qemu-system-arm这个进程来退出,我简单写了一个脚本来完成这个任务 kill_qemu.sh

    #!/bin/bash
    
    ps -A | grep qemu-system-arm | awk '{print $1}' | xargs sudo kill -9

    制作根文件系统

    到这里是否大功告成了呢? 其实在上面的测试中,你会发现内核报panic,因为内核找不到根文件系统,无法启init进程。

    根文件系统要考虑两个方面:

    1. 根文件系统的内容

        如果你看过《Linux From Scratch》,相信你会对这一步产生恐惧感,但如果一直从事嵌入式开发,就可以放下心来。根文件系统就是简单得不能再简单的几个命令集和态动态而已。为什么Linux From Scratch会有那么复杂,是因为它要制作出一个Linux发生版。但在嵌入式领域,几乎所有的东西,都是mini版本,根文件系统也不例外。

       本文制本的根文件系统 = busybox(包含基础的Linux命令)  + 运行库 + 几个字符设备

     

    2. 根文件系统放在哪里

         其实依赖于每个开发板支持的存储设备,可以放到Nor Flash上,也可以放到SD卡,甚至外部磁盘上。最关键的一点是你要清楚知道开发板有什么存储设备。

         本文直接使用SD卡做为存储空间,文件格式为ext3格式

    下载、编译和安装busybox

    我用的busybox版本是1_24,下载地址:https://busybox.net/downloads/

    配置:

    在busybox下执行 make menuconfig

    做如下配置:

    Busybox Settings  --->

        Build Options  --->

            [*] Build BusyBox as a static binary (no shared libs)

            (arm-linux-gnueabi-) Cross Compiler prefix

    然后执行

    make
    make install

    安装完成后,会在busybox目录下生成_install目录,该目录下的程序就是单板运行所需要的命令。

    形成根目录结构

    先在Ubuntu主机环境下,形成目录结构,里面存放的文件和目录与单板上运行所需要的目录结构完全一样,然后再打包成镜像(在开发板看来就是SD卡),这个临时的目录结构称为根目录.
     
    我写了一个脚本来 mkrootfs.sh 完成这个任务:
     
    #!/bin/bash
    
    sudo rm -rf rootfs
    sudo rm -rf tmpfs
    sudo rm -f a9rootfs.ext3
    
    sudo mkdir rootfs
    sudo cp busybox/_install/*  rootfs/ -raf
    
    sudo mkdir -p rootfs/proc/
    sudo mkdir -p rootfs/sys/
    sudo mkdir -p rootfs/tmp/
    sudo mkdir -p rootfs/root/
    sudo mkdir -p rootfs/var/
    sudo mkdir -p rootfs/mnt/
    
    sudo cp etc rootfs/ -arf
    
    sudo cp -arf /usr/arm-linux-gnueabi/lib rootfs/
    
    sudo rm rootfs/lib/*.a
    sudo arm-linux-gnueabi-strip rootfs/lib/*
    
    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
    sudo mknod rootfs/dev/console c 5 1
    sudo mknod rootfs/dev/null c 1 3
    
    sudo dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
    sudo mkfs.ext3 a9rootfs.ext3
    
    sudo mkdir -p tmpfs
    sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop
    sudo cp -r rootfs/*  tmpfs/
    sudo umount tmpfs


    其中,etc下是启动配置文件,可以的到这里下载:

    系统启动运行

    完成上述所有步骤之后,就可以启动qemu来模拟vexpress开发板了,命令参数如下:
    qemu-system-arm 
        -M vexpress-a9 
        -m 512M 
        -kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage 
        -nographic 
        -append "root=/dev/mmcblk0  console=ttyAMA0" 
        -sd /root/tq2440_work/busybox_study/a9rootfs.ext3 

    上面是不太图形界面的,下面的命令可以产生一个图形界面:

    qemu-system-arm 
        -M vexpress-a9 
        -serial stdio 
        -m 512M 
        -kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage 
        -append "root=/dev/mmcblk0  console=ttyAMA0 console=tty0" 
        -sd /root/tq2440_work/busybox_study/a9rootfs.ext3

    下一节,用Qemu模拟运行vexpress的u-boot。

  • 相关阅读:
    go调查内存泄漏
    c++ 使用模板按类型统计stl多维容器中元素的数量
    phxpaxos遇到反复拉取checkpoint但是反复失败的问题,给其它节点造成压力
    phxpaxos实现状态机CAS操作
    使用phxpaxos开发过程中遇到的坑
    std::condition_variable::wait_until segment
    c++ protected 访问限定
    c++多态
    IO多路复用的水平触发与边缘触发
    Redis 源码分析系列1-main函数相关调用分析
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/5023342.html
Copyright © 2020-2023  润新知