目录

1. 环境介绍:

2. 下载Linux内核

3. 安装arm的交叉编译工具链

4.编译Linux内核

5. 下载qemu

6. 制作根文件系统

1. 根文件系统的内容

2. 根文件系统放在哪里

3. 下载、编译和安装busybox

7.使用qemu测试

8.下载、编译u-boot代码

9.u-boot使用qemu测试

10. 利用网络引导的方式启动Linux内核。具体方式如下:

1、启动Qemu的网络支持

2、配置u-boot

11. 使用设备树来启动内核

1、配置u-boot

2、配置内核

3、编译设备树

12. 实现NFS根文件系统的挂载。

1、保证Qemu的网络是可以用的。

2、配置u-boot的环境变量bootargs

3、配置kernel

4、启动

附加

1.错误

2.tftp服务器搭建

tftpd-hpa(服务器)安装:

配置:

使用:

tftp-hpa(客户端)安装:

测试:

3.nfs服务器搭建

1、NFS 介绍

2、安装 NFS 软件包

3、添加 NFS 共享目录

4、启动 NFS 服务

5、测试 NFS 服务器


1. 环境介绍:

Win10 64 + Vmware 14 + ubuntu16.04

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

Linux kernel版本:linux-3.16.y

busybox版本:1_24_stable

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

qemu版本:stable-2.4

2. 下载Linux内核

下载内核有两种方法,一种是用git直接下载内核代码树,方便后面的内核开发。另一种是直接到内核社区下载对应版本的源码包。我采用第一种方法。

方法一:使用git

 git clone git://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

3. 安装arm的交叉编译工具链

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

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

4.编译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会起不来, 暂时还不知道为什么。
Kernel Features -->[*] Use the ARM EABI to compile the kernel
# 确保该选项被选择

编译:

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

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

编译modules

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

设置modules的存放位置

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm  O=./out_vexpress_3_16 modules_install INSTALL_MOD_PATH=../app

错误的提示上面看是重复定义了return_address函数,这里做个笔记!
解决方案

    当前要编译的内核文件夹下面:gedit arch/arm/include/asm/ftrace.h(P.S:如果不是ubuntu可以用vim)源代码:extern inline void *return_address(unsigned int level)修改为:static inline void *return_address(unsigned int level){return NULL;}当前要编译的内核文件夹下面:gedit arch/arm/kernel/return_address.c源代码:void *return_address(unsigned int level)(这里是第二个return_address,里面只有return NULL一行代码){return NULL;}修改为:全部注释掉,或者删除掉

5. 下载qemu

sudo apt-get install qemu-systen-*

查看qemu支持哪些板子

qemu-system-arm -M help

6. 制作根文件系统

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

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

1. 根文件系统的内容

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

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

2. 根文件系统放在哪里

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

3. 下载、编译和安装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主机环境下,形成目录结构,里面存放的文件和目录与单板上运行所需要的目录结构完全一样,然后再打包成镜像,这个临时的目录结构称为根目录.
 
我写了一个脚本来 mkrootfs.sh 完成这个任务:

 #!/bin/bashsudo rm -rf rootfs
sudo rm -rf tmpfs
sudo rm -f a9rootfs.ext3sudo mkdir rootfs
sudo cp busybox/_install/*  rootfs/ -rafsudo 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/ -arfsudo cp -arf /usr/arm-linux-gnueabi/lib rootfs/sudo rm rootfs/lib/*.a
sudo arm-linux-gnueabi-strip rootfs/lib/*sudo cp lib/* rootfs/lib -arfsudo 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 3sudo dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
sudo mkfs.ext3 a9rootfs.ext3sudo chmod 777 a9rootfs.ext3
sudo cp -r rootfs /opt/nfsboot  #/opt/nfsboot 为nfs挂在目录sudo mkdir -p tmpfs
sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop
sudo cp -r rootfs/*  tmpfs/
sudo umount tmpfs

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

http://files.cnblogs.com/files/pengdonglin137/etc.tar.gz

7.使用qemu测试

#!/bin/bash
qemu-system-arm \-M vexpress-a9 \-serial stdio \-m 512M \-kernel ../linux-3.16/out_vexpress_3_16/arch/arm/boot/zImage \-append "init=/linuxrc root=/dev/mmcblk0 rw rootwait earlyprintk console=ttyAMA0 console=tty0" \-sd ./a9rootfs.ext3

8.下载、编译u-boot代码

u-boot从下面的网址获得:

http://ftp.denx.de/pub/u-boot/

取得是最新的代码。我使用的是u-boot-2015.05, 解压后,配置,编译:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_ca9x4_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

9.u-boot使用qemu测试

qemu-system-arm -M vexpress-a9 \-kernel u-boot \-nographic \-m 512M

打印出u-boot的启动信息:
复制代码

U-Boot 2015.07-rc3-00092-gf3edfd3-dirty (Dec 05 2015 - 22:00:46 -0800)DRAM:  512 MiB
WARNING: Caches not enabled
Flash: 128 MiB
MMC:   MMC: 0
*** Warning - bad CRC, using default environmentIn:    serial
Out:   serial
Err:   serial
Net:   smc911x-0
Warning: smc911x-0 using MAC address from net deviceHit any key to stop autoboot:  0

10. 利用网络引导的方式启动Linux内核。具体方式如下:

开启Qemu的网络支持功能,启动u-boot,设置u-boot的环境变量,u-boot采用tftp的方式将uImage格式的Linux内核下载到内存地址0x60003000处,为什么是0x60000000起始的地址,参考文件u-boot的配置文件 include/configs/vexpress_common.h。如果用Qemu直接启动Kernel,是通过-append parameter 的方式给kernel传参的,现在是通过u-boot,那么需要通过u-boot的环境变量bootargs,可以设置为如下值 setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0 console=tty0'。 然后设置u-boot环境变量bootcmd,如下: setenv bootcmd 'tftp 0x60003000 uImage; bootm 0x60003000'.

具体步骤

1、启动Qemu的网络支持

qemu 支持多种网络链接方式,其中最常用的就是桥接(bridge)。 这需要依赖内核的 tun/tap 模块的支持。

输入如下命令安装必要的工具包:

    sudo apt-get install uml-utilitiessudo apt-get install bridge-utils

输入如下命令查看 /dev/net/tun 文件:

    ls -l /dev/net/tuncrw-rw-rwT 1 root root 10, 200 Apr 15 02:23 /dev/net/tun

如果该文件存在,这表明内核已经支持开启了 tun 支持,在 ubuntu-16.04 中,这个功能默认已经开启。

如果该文件不存在,则需要加载 tun 模块,并创建 /dev/net/tun 文件。
     安装完成后,执行

sudo tunctl -u root -t tap30
#就可以在主机上创建一个网络设备,这是使用 ifconfig -a 命令可以看到名字为tap30的网络设备。
ifconfig tap30 192.168.2.62 promisc up
#配置网卡IP地址,并且以混杂模式启用。

注:此配置主机重启后续重新配置。

主机的网络配置已经完成,接下来开始配置虚拟机,QEMU通过 -net 参数指定网络配置
        有三种选项
                -net nic 必须有的基本配置,macaddr 设置mac地址,model是网卡的类型,可以model=?查看有哪些类型
                -net tap 使用桥接模式的,需要指定启动脚本 script=和关闭脚本 downscript,fd是指向已经有的tap设备,name是在monitor模式使用info network看到的名字,ifname是tap设备在主机中的名字
                -net user 用户模式,qemu使用Slirp实现了一整套tcp/ip协议栈
                一般nic必须有,tap和user选一个使用
        在启动qemu的脚本中添加两行参数:

-net nic,vlan=0 \
-net tap,vlan=0,ifname=tap30,script=no,downscript=no \

进入虚拟系统后,ifconfig eth0 192.168.2.5 up   配置虚拟系统IP。

2、配置u-boot

主要是修改include/configs/vexpress_common.h
复制代码

diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h
index 0c1da01..9fa7d9e 100644
--- a/include/configs/vexpress_common.h
+++ b/include/configs/vexpress_common.h
@@ -48,6 +48,11 @@#define CONFIG_SYS_TEXT_BASE   0x80800000#endif+/* netmask */
+#define CONFIG_IPADDR   192.168.2.5
+#define CONFIG_NETMASK  255.255.255.0
+#define CONFIG_SERVERIP 192.168.2.62
+/** Physical addresses, offset from V2M_PA_CS0-3*/
@@ -202,7 +207,9 @@#define CONFIG_SYS_INIT_SP_ADDR                CONFIG_SYS_GBL_DATA_OFFSET/* Basic environment settings */
-#define CONFIG_BOOTCOMMAND             "run bootflash;"
+/* #define CONFIG_BOOTCOMMAND          "run bootflash;" */
+#define CONFIG_BOOTCOMMAND             "run bootflash; setenv ipaddr \
192.168.2.5; setenv serverip 192.168.2.62; tftp 0x60003000 uImage; tftp 0x60500000 dtb; \
setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0'; bootm 0x60003000 - 0x60500000;"

11. 使用设备树来启动内核

步骤

1、配置u-boot

vexpress-a9的u-boot默认已经支持设备树了。

2、配置内核

vexpress-a9的kernel默认也已经支持了。

3、编译设备树

在内核源码根目录下执行如下命令:

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

然后会在out_vexpress_3_16/arch/arm/boot/dts/下生产如下几个文件

vexpress-v2p-ca15_a7.dtb  vexpress-v2p-ca15-tc1.dtb  vexpress-v2p-ca5s.dtb  vexpress-v2p-ca9.dtb

这里我们用vexpress-v2p-ca9.dtb,然后将其拷贝到/tftpboot下面

cp out_vexpress_3_16/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /tftpboot/dtb

12. 实现NFS根文件系统的挂载。

具体步骤如下。

步骤

1、保证Qemu的网络是可以用的。

进入u-boot交互界面,ping 102.168.2.62,出现 is alive 即网络可用

2、配置u-boot的环境变量bootargs

setenv bootargs 'root=/dev/nfs rw nfsroot=192.168.2.62:/rootfs init=/linuxrc console=ttyAMA0 ip=192.168.2.5'

3、配置kernel

配置内核,使其支持nfs挂载根文件系统

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

配置:

File systems  --->[*] Network File Systems  ---><*>   NFS client support<*>     NFS client support for NFS version 3[*]       NFS client support for the NFSv3 ACL protocol extension[*]   Root file system on NFS

然后重新编译内核

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 LOADADDR=0x60003000 uImage -j8

将生成的uImage拷贝到/tftpboot下

4、启动

复制代码

qemu-system-arm -M vexpress-a9 \-kernel u-boot \-nographic \-m 512M \-net nic,vlan=0 -net tap,vlan=0,ifname=tap0

注:这里的-sd参数此时可以不用设置。

此时我们由于指定了-sd参数,所以我们还可以访问原来的根文件系统,方法如下:
复制代码

[root@vexpress ]# ls /dev/mmcblk0  -lh
brw-rw----    1 0        0         179,   0 Dec  6 08:47 /dev/mmcblk0
[root@vexpress ]# df -h
Filesystem                Size      Used Available Use% Mounted on
192.168.11.20:/nfs_rootfs/rootfs15.6G      5.1G      9.7G  34% /
tmpfs                   250.7M         0    250.7M   0% /tmp
tmpfs                   250.7M         0    250.7M   0% /dev
[root@vexpress ]# mount -t ext3 /dev/mmcblk0 /mnt/tmp
random: nonblocking pool is initialized
kjournald starting.  Commit interval 5 seconds
EXT3-fs (mmcblk0): using internal journal
EXT3-fs (mmcblk0): mounted filesystem with writeback data mode
[root@vexpress ]# ls /mnt/tmp/
bin         etc         linuxrc     mnt         root        sys         usr
dev         lib         lost+found  proc        sbin        tmp         var
[root@vexpress ]#

附加

1.错误

kernel/Makefile:971: recipe for target 'prepare3' failed...ninja.mk:148: recipe for target 'ninja_wrapper' failed

结论:

make mrproper 再进行编译,问题解决,原因是srctree不干净了

2.tftp服务器搭建

tftp是client客户端,tftpd是server服务器端,d应该指的是daemon。如果你要从别人的tftp服务器端上传/下载东西,就要用到tftp;如果你为别人提供tftp服务,供别人上传/下载东西,那就要安装tftpd服务程序。

ubuntu中常用的tftp服务器和客户端是tftpd-hpa和tftp-hpa

tftpd-hpa(服务器)安装:

    sudo apt-get install tftpd-hpa

配置:

    sudo vim /etc/default/tftpd-hpaTFTP_USERNAME="tftp"TFTP_DIRECTORY="/tftpboot"    //指定将来下位机的下载目录为上位机的/tftpboot,此目录随意指定即可TFTP_ADDRESS="0.0.0.0:69"TFTP_OPTIONS="-l -c -s"

修改完毕,保存退出

    sudo mkdir /tftpboot //创建tftpd-hpa网络服务的下载目录

修改下载目录的权限

    sudo chmod 777 /tftpboot

使用:

重新启动tftpd-hpa网络服务:sudo service tftpd-hpa restart

tftp-hpa(客户端)安装:

sudo apt-get install tftp-hpa

测试:

随便找个目录,只要不是/tftpboot就行

tftp 127.0.0.1tftp> get xxx    //下载(下载成功后没有提示,并且在当前目录下会出现xxx文件)

3.nfs服务器搭建

1、NFS 介绍

NFS 即网络文件系统(Network File-System),可以通过网络让不同机器、不同系统之间可以实现文件共享。通过 NFS,可以访问远程共享目录,就像访问本地磁盘一样。NFS 只是一种文件系统,本身并没有传输功能,是基于 RPC(远程过程调用)协议实现的,采用 C/S 架构。

2、安装 NFS 软件包

sudo apt-get install nfs-kernel-server  # 安装 NFS服务器端
sudo apt-get install nfs-common         # 安装 NFS客户端

3、添加 NFS 共享目录

sudo vim /etc/exports

若需要把 “/nfsroot” 目录设置为 NFS 共享目录,请在该文件末尾添加下面的一行:

/nfsroot *(rw,sync,no_root_squash)     # * 表示允许任何网段 IP 的系统访问该 NFS 目录

在这里插入图片描述
新建“/nfsroot”目录,并为该目录设置最宽松的权限:

sudo mkdir /nfsroot
sudo chmod -R 777 /nfsroot
sudo chown ipual:ipual /nfsroot/ -R   # ipual 为当前用户,-R 表示递归更改该目录下所有文件

4、启动 NFS 服务

sudo /etc/init.d/nfs-kernel-server start    或者
sudo /etc/init.d/nfs-kernel-server restart  或者
sudo service nfs-kernel-server restart

在 NFS 服务已经启动的情况下,如果修改了 “/etc/exports” 文件,需要重启 NFS 服务,以刷新 NFS 的共享目录。

5、测试 NFS 服务器

sudo mount -t nfs 192.168.12.123:/nfsroot /mnt -o nolock

192.168.12.123 为主机 ip,/nfsroot 为主机共享目录,/mnt 为设备挂载目录,如果指令运行没有出错,则 NFS 挂载成功,在主机的 /mnt 目录下应该可以看到 /nfsroot 目录下的内容(可先在 nfsroot 目录下新建测试目录),如需卸载使用

umount /mnt

使用Qemu模拟vexpress-a9搭建模拟开发板相关推荐

  1. 嵌入式开发环境搭建:开发板tftp下载环境搭建

    (注:本文参考资料:朱有鹏嵌入式课程.本文为个人学习记录,如有错误,欢迎指正.) 1. 设置网络 设置开发板与虚拟主机Ubuntu的网络连接. (1)将开发板与Windows主机用网线相连: (2)开 ...

  2. 搭建S3C6410开发板的测试环境

    1.开发板是开发和学习嵌入式技术的主要设备.OK6410开发板基于三星公司最新的ARM11处理器S3C6410,对三星S3C6410的性能做出了完美诠释,拥有强大的内部资源和视频处理能力,可稳定运行在 ...

  3. [Linux] Ubuntu13.04 搭建OK6410-A开发板的开发环境

    # 下载dnw与驱动文件 cd ~ mkdir -p tmp 2>/dev/null cd tmp/ git clone git://github.com/Qunero/dnw4linux.gi ...

  4. 基于Qemu搭建imx6l模拟开发板环境+添加驱动+驱动测试

    一.Qemu镜像下载 准备环境 vmware ubuntu18.04 git工具 下载镜像文件 root@ubuntu:/home/mf/Desktop# git clone https://e.co ...

  5. Qemu使用及常见开发板的模拟

    Qemu的使用及一些开发板的模拟 介绍 Qemu可以对许多架构的CPU或开发板进行模拟.在我们没有开发板的时候,可以通过其进行一些开发板的模拟,便于学习. 安装 sudo apt-get instal ...

  6. QEMU imx6ul开发板环境搭建

    QEMU imx6ul开发板环境搭建 文章目录 QEMU imx6ul开发板环境搭建 0. 前言 1. 基本环境 2. 安装KVM 3. 下载开发板的QEMU镜像文件 4. 运行QEMU系统 4.1 ...

  7. 在Ubuntu下使用QEMU搭建arm开发环境(一)搭建基本开发环境

    马上就要开学了,开学后就会开始arm+Linux的学习,因为马上就要去学校了,就没有买板子,打算去了学校再买,但是想学习的心是迫切的(O(∩_∩)O哈哈~),在网上浏览的时候发现了QEMU这个&quo ...

  8. Zedboard开发板的linux搭建

    1.简介 zynq是xilinx推出的一款集成arm核以及fpga可编程逻辑器件的soc芯片,使得它不仅拥有 ASIC 在能耗.性能和兼容性方面的优势,而且具有FPGA 硬件可编程性的优点.zynq主 ...

  9. 作为硬件开发,你一定要知道开发板是个什么东西?陈老师带你了解

    作为智能硬件开发,你一定要知道开发板是个什么东西? 如果您有和智能硬件开发人员打交道,或者贵公司正好有智能硬件的开发需求,又或者你正在学习关于智能硬件方面的知识,那么你一定听过『开发板』这个词语. / ...

  10. 新手必看 | RVB2601开发板快速上手指南

    简介:技术解码栏目:是面向开发者详细解读芯片开放社区(OCC)上关于处理器.芯片.基础软件平台.集成开发环境及应用开发平台的相关技术,方便开发者学习及快速上手,提升开发效率. 之前我们推送了RISC- ...

最新文章

  1. SQL Server日期格式的转换
  2. MyEclipse+Tomcat web项目改名
  3. Vue.use()是什么?
  4. 你真的会写二分查找吗
  5. 南阳计算机职称考试报名时间2015,2015河南公务员考试14日起开始报名 南阳市计划招录590人...
  6. 风火编程--用pillow对比展示两张图片
  7. 作用域 (局部作用域和全局作用域) 详细介绍
  8. 两步实现安卓手机秒变网络摄像头
  9. 云端部署 vs 本地化部署
  10. 蓝桥杯大学JAVA题型_蓝桥杯 2020年省赛真题 10月第二场 (Java 大学B组)
  11. 数组的归一化c语言,如何归一化频率数组
  12. Mini LED,显示技术的春天?!
  13. [开发探索]知行合一
  14. 财富杂志:谷歌市场成功带来的10大启示
  15. Android 自定义收音机刻度
  16. JAVA Base64加密解密
  17. 2022考研数学二考试大纲
  18. 如何使计算机理解中医药知识,计算机技术在中医药信息学应用概
  19. byte的取值范围为啥是[-128~127](超详细教学,建议收藏)
  20. 使用OpenSSL1.1.1中的libcrypto库进行RSA加密与解密数据

热门文章

  1. ifftshift和fftshift函数在画图时的作用(matlab)
  2. 服务器Ctrl+R快捷键阵列(RAID)卡配置步骤【超详细】
  3. uni-app网络请求封装_网络工程师必懂篇·数据的传输流程
  4. 如何显示文件后缀名,这4个方法很简单!
  5. 阿里云产品专家解读链路追踪(Tracing Analysis)和应用性能监控(APM)的联系和区别
  6. 二维码的原理以及怎么生成二维码
  7. 编程中十大常用算法:(六)普里姆算法(最小生成树)
  8. 【GRAPH】Weisfeiler-Lehman算法测试图同构
  9. 开发工具|H5微应用本地开发新姿势
  10. 芝草醴泉,和这次的字摘整理