参考:

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.-

sudo apt-get install libglib2.-dev

sudo apt-get install libtool

sudo apt-get install libsdl1.-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. (root@ubuntu) (gcc version 4.7. (Ubuntu/Linaro 4.7.-12ubuntu1) ) # SMP Sat Dec :: PST
CPU: ARMv7 Processor [410fc090] revision (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: bits at 24MHz, resolution 41ns, wraps every 178956969942ns
PERCPU: Embedded pages/cpu @9fbed000 s7552 r8192 d12928 u32768
Built zonelists in Zone order, mobility grouping on. Total pages:
Kernel command line: console=ttyAMA0
PID hash table entries: (order: , bytes)
Dentry cache hash table entries: (order: , bytes)
Inode-cache hash table entries: (order: , 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(,): error -
Please append a correct "root=" boot option; here are the available partitions:
1f00 mtdblock0 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(,)
CPU: PID: Comm: swapper/ Not tainted 3.16. #
[<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(,)

这里简单介绍下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 -

制作根文件系统

到这里是否大功告成了呢? 其实在上面的测试中,你会发现内核报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。

用Qemu模拟vexpress-a9 (一) --- 搭建Linux kernel调试环境的更多相关文章

  1. 用Qemu模拟vexpress-a9 (一) --- 搭建Linux kernel调试环境【转】

    转自:http://www.cnblogs.com/pengdonglin137/p/5023342.html#_label2 阅读目录(Content) 环境介绍: 下载Linux内核 安装arm的 ...

  2. 利用QEMU+GDB搭建Linux内核调试环境

    前言 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试. 其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qe ...

  3. DELPHI 10.2 TOKYO搭建LINUX MYSQL开发环境

    DELPHI 10.2 TOKYO搭建LINUX MYSQL开发环境 笔者使用ubuntu64位LINUX 首先必须保证LINUX可以连互联网. 安装MYSQLsudo apt-get update ...

  4. Xcode搭建真机调试环境 图文实例

    本文介绍的Xcode搭建真机调试环境 图文实例,图文并茂,使我们学习起来更方便些,我们先来看内容. AD: 2013云计算架构师峰会超低价抢票中 Xcode搭建真机调试环境 是本文要介绍的内容,不多说 ...

  5. vscode加MinGw三步搭建c/c++调试环境

    vscode加MinGw三步搭建c/c++调试环境 step1:安装vscode.MinGw 1.1 vscod常规安装:https://code.visualstudio.com/ 1.2 MinG ...

  6. vs2017搭建linux c++开发环境

    最近一直在阅读ovs的源码,看到用户态代码的时候,需要对用户态的代码进行调试,一开始想直接使用linux中的GDB进行调试,但是ovs的工程太过于复杂,从网上找了些文章,发现vs2017能够支持lin ...

  7. 搭建基于qemu + eclipse的kernel调试环境(by quqi99)

    作者:张华  发表于:2016-02-06版权声明:能够随意转载.转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 使用q ...

  8. 通过模拟器和ida搭建Android动态调试环境的问题

    这几天在学Android的native层逆向.在按照教程用ida搭建动态调试环境时,第一步是把android_server 放到手机里执行,但是在手机里可以,在genymotion模拟器上就提示 no ...

  9. qemu模拟vexpress-a9及u-boot引导 linux

    前言 本文讲述使用 qemu 来模拟 vexpress-a9 开发板 ,同时介绍使用 u-boot 引导 linux 的流程.整个坐下来对 qemu 和 u-boot 以及嵌入式 linux 的工作方 ...

随机推荐

  1. Unix IPC之读写锁

    linux中读写锁的rwlock介绍 读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁: 1,当读写锁是写加锁状态时, 在这个锁被解锁之前, 所 ...

  2. C++两个类相互包含引用的问题

    在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A { B b; } class B { A* a; } 请 ...

  3. Linux学习笔记:mkdir创建文件夹

    文件夹,即目录,在linux中使用mkdir创建. 语法:mkdir dir_name 通过 mkdir 命令可以实现在指定位置创建以 dir_name(指定的文件名)命名的文件夹或目录.要创建文件夹 ...

  4. 微信小程序蓝牙模块

    蓝牙部分知识 关于Service: 每个设备包含有多个Service,每个Service对应一个uuid 关于Characteristic 每个Service包含多个Characteristic,每个 ...

  5. 一步一步学习IdentityServer4 (2) 开始一个简单的事例

    前面将来一些配置,但是很多都不是必要的,先放一些事例需要的简要配置把 既然是IdentityServer4 所里下面的例子我 直接放到 Linux上 测试环境 CentOS 7 +Nginx1.9.3 ...

  6. Spark(十六)DataSet

    Spark最吸引开发者的就是简单易用.跨语言(Scala, Java, Python, and R)的API. 本文主要讲解Apache Spark 2.0中RDD,DataFrame和Dataset ...

  7. Vue.js学习笔记(一) - 起步

    本篇将简单介绍一下Vue.js,并在Node.js环境下搭建一个简单的Demo. 一.简介 我个人理解,Vue.js是一套前端视图层的框架,它只关心视图展示和数据绑定,它的一些语法与Angular 1 ...

  8. jquery validate不用submit提交,用js提交的

    jquery validate控件 默认是使用submit提交的, 要想改成使用button的click事件处理函数中手工提交, 可以按照如下方式操作: 1 绑定form的validate, 2 然后 ...

  9. LoadRunner 参数化之 连接数据库进行参数化

    LoadRunner 参数化之 连接数据库进行参数化 Loadrunner(简称“LR”)对性能测试的脚本进行参数化时,由于数据量偏大,大家往往都会把数据录入到数据库表里,然后关联到LR,本文将详细介 ...

  10. cent7.0 mysql 修改端口

    如何查看mysql 默认端口号和修改端口号 2015-03-19 17:42:18 1. 登录mysql [root@test /]# mysql -u root -p Enter password: ...