一、系统开发平台介绍
本次试验是基于九鼎创展公司嵌入式开发板x210v3, 核心处理器是ARM Cortex–A8架构的S5PV210,主频1GHz。 PC机Linux版本:Ubuntu Kylin 14.04 内核版本:3.13
二、Linux内核配置和编译
2.1 基本原理介绍
2.1.1目录简介
Linux目录基于“文件系统层次标准”(FHS),目录为树形结构。该标准定义了不同目录的结构和功能。基本目录如下:
arch:architecture的缩写,包含与体系结构相关的内核代码,实验中我们用到的是ARM体系结构;
drivers:设备驱动程序,如block:部分块设备驱动程序,char:字符设备驱动程序,其他的还有cdrom、pci、scsi、net、sound等;
fs:存放各种文件系统的实现代码。每个子目录对应一种文件系统,如:
||devpts-/dev/pts虚拟文件系统 ||ext2-第二扩展文件系统
||fat-fat32文件系统 ||isofs-iso9660光盘cd-rom上的文件系统
include:含内核所需头文件;
init:含内核初始化代码;
ipc:进程间通信的实现代码;
kernel:Linux大多数关键的核心功能都是在这个目录实现;
(调度程序,进程控制,模块化)
lib目录:库文件代码;
Mm:用于实现内存管理中与体系结构无关的部分(与体系结构相关的部分在arch下);
Net:网络协议的实现代码。如:
||802-802无线通讯协议核心支持代码 ||ipv4-ip协议族V4版32未寻址模式
||ipv6-ip协议族V6版
Scripts:含配置内核的脚本文件;
2.1.2 内核配置的基本结构
Linux内核的配置系统由三部分(或者四部分,区别在于分类方式)组成:
1) Makefile:分布在 Linux 内核源代码中的 Makefile,定义 Linux 内核的编译规则,在顶层及各子目录下都有。顶层 Makefile 有两个主要的任务:产生 vmlinux 文件和内核模块(module); 另一个文件Rules.make 为规则文件,定义了所有 Makefile 共用的编译规则。
2) 配置文件(config.in):给用户提供配置选择的功能。文件中有许多的配置变量等式,用来说明用户配置的结果。例如 CONFIG_MODULES=y 表明用户选择了 Linux 内核的模块功能。
3) 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供基于字符界面、基于 Ncurses 图形界面以及基于 Xwindows 图形界面的用户配置界面,各自对应于 Make config、Make menuconfig 和 make xconfig)。本次实验使用的是make menuconfig
2.2 内核配置过程
1.利用tar 指令解压内核并进入解压出的内核文件夹,试验中使用的内核是已经移植好的与开发板配套的内核;
2.ExportARCH=arm ;选择处理器构架为arm平台,执行完该指令之后Makefile 将使用以arm平台为基础的代码
3.Makeclean ;清除之前编译的残留成分
4.makemenuconfig 进入配置的菜单界面
为保证操作系统正常启动,需要配置一下几个部分:
1)general setup——>(内核编译配置的基本方法)
cross-compiler tool prefix 选项中设置交叉编译器的路径及前缀;
Initial RAM filesystem and RAMdisk(initramfs/initrd) support 用于内核启动时装载ramdisk作为它的根文件系统;
由于ramdisk使用的是gzip压缩方式,故还应选择 support initial ramdisks compressed using gzip ;
2)system type ——>(系统选型)
ARM system type 一项中应选择与开发板配套的 (samsungS5PV210/S5PC110);
3)device drivers——>(设备驱动)
应支持块设备驱动:block devices——>RAMblock device support;
此外,选择缺省的ramdisk 的大小为8192kbytes(8M);
3)File systems ——>(文件系统)
由于ramdisk使用的ext2文件系统,故应选择支持ext2文件系统(属于磁盘文件系统)、另外在网络文件系统中应选中NFS,保证NFS的客户端支持,后面的开发中将要使用到。
配置完成后保存并退出,配置的信息会保存在 .config文件中。另外也可以将已配置好的config配置文件内容直接复制到当前的.config文件当中;之前的配置自动保存与config.old文件内,必要时可以进行恢复。
5、make 对内核进行编译,生成zImage文件,保存在内核目录下的 arch/arm/boot/zImage中。
注:也可以使用make –j4指令编译内核。这里的-j4指的是4核同时编译,可以加快编译速度,减少等待时间。
至此第一个实验已经完成,生成了实验所需要的内核镜像文件zImage。
Ø 内核镜像文件的对操作系统的作用
内核镜像文件zImage是核心的linux内核vmlinux经过压缩后得到,它有点类似于windows系统中的ISO文件,其中包含了可执行的二进制指令(内核),调试信息,符号表等内容,为可运行的二进制内核镜像,可以说是整个操作系统的核心部件。同时,zImage可以烧写到Flash中,方便加载进入我们需要的嵌入式系统。
三、嵌入式文件系统的构建
3.1 Linux常用文件系统及其优缺点
1) RomfS:只读文件系统,可以放在ROM空间,也可以在系统的RAM中
优点:相对简单、占用空间较少。
缺点:文件系统Romfs为只读文件系统,禁止写操作,因此系统同时需要虚拟盘(Ramdisk)支持临时文件数据文件的存储.
2) Ext2fs/Ext3fs(以Ext2fs为例)
优点:支持4 TB 存储、文件名称最长1012 字符;可选择逻辑块;快速符号链接
缺点:Ext2fs不适合flash设备;是为象IDE设备那样的块设备设计的,逻辑块大小必 须是512 byte、1KB、2KB等;没有提供对基于扇区的擦除/写操作的良好管理;如果在一个扇区中擦除单个字节,必须将整个扇区复制到 RAM,然后擦除,再重写入;在出现电源故障时,Ext2fs 是不能防止崩溃的;文件系统不支持损耗平衡,缩短了flash的寿命
3) JFFS/JFFS2:是为Flash设计的日志文件系统日志文件系统
优点:提供了更好的崩溃、掉电安全保护;支持对flash的均匀磨损;在扇区级别上执行闪存擦除/写/读操作要 比Ext2文件系统好;
缺点:文件系统接近满时,JFFS2 会大大放慢运行速度(垃圾收集);jffs/jffs2启动的时候需要扫描日志节点,不适合大容量的Nand flash;jffs的日志通过jffs_node建立在RAM中,占用 RAM空间:如对于128MB的Nand大概需要4MB的空间来维护节点!
3.2 以BusyBox为基础构建适合的文件系统
3.2.1 根目录介绍
目录名 |
存放的内容 |
/bin |
必备的用户命令,例如ls、cp等 |
/sbin |
必备的系统管理员命令,例如ifconfig、reboot等 |
/dev |
设备文件,例如mtdblock0、tty1等 |
/etc |
系统配置文件,包括启动文件,例如inittab等 |
/lib |
必要的链接库,例如C链接库、内核模块 |
/home |
普通用户主目录 |
/root |
root用户主目录 |
/usr/bin |
非必备的用户程序,例如find、du等 |
/usr/sbin |
非必备的管理员程序,例如chroot、inetd等 |
/usr/lib |
库文件 |
/var |
守护程序和工具程序所存放的可变,例如日志文件 |
/proc |
用来提供内核与进程信息的虚拟文件系统,由内核自动生成目录下的内容 |
/sys |
用来提供内核与设备信息的虚拟文件系统,由内核自动生成目录下的内容 |
/mnt |
文件系统挂接点,用于临时安装文件系统 |
/tmp |
临时性的文件,重启后将自动清除 |
3.2.2 实验步骤
1、编译BusyBox:
按照Make menuconfig——>make——>make install顺序编译BusyBox,编译完之后的代码安装在指定目录_install目录下,主要是生成/bin、/sbin、/usr/bin、/usr/sbin目录,存储常用命令的二进制文件。
2、做一个8M的ext2文件系统
#ddif=/dev/zero of=ramdisk_img bs=8k count=1k ;建立一个8M的文件
#/sbin/mke2fsramdisk_img ;将该文件格式化为一个ext2文件系统
3、在/mnt目录下创建一个名为ramdisk的目录,将之前做的ramdisk_img文件系统挂载到该目录,有两种方式:
方式一:
#sudo mountramdisk_img /mnt/ramdisk/ -o loop ;将ramdisk_img作为文件系统挂载到指定目录(需要超级用户权限)
方式二:
#more/etc/fstab ;可不需要超级用户权限(缺点是只限于当前目录下的ramdisk文件)
# mount/mnt/ramdisk/ ;注意不要出现重配置的问题
4、进入_install目录,将里面所有文件文件复制文件到 /mnt/ramdisk中
#cp */mnt/ramdisk/ -ar
5、在根文件系统中配置一些启动的选项
(1)ramdisk目录中建立proc、sys、dev、etc、lib目录,各目录功能前面已经做了简要介绍
(2)在etc目录内里面创建inittab文件,作为启动脚本的内容;创建rc文件,包含一些系统启动的命令;创建motd文件,里面的内容将最终打印在终端上;之后创建init.d目录,并利用ln指令做符号链接,该文件作为inittab启动脚本
#vi rc
#mkdir init.d
#ln –fs ../rc rcS ;链接
#sudo chmod +xrc ;给rc加上可执行的属性
(3)ramdisk目录中建立lib目录,在交叉编译库路径下找到 ld-2.10.1.so,libc-2.10.1.so,libm-2.10.1.so三个动态库文件及相应的动态链接库加载器,通过ln指令实现动态库的链接
(4)进入dev 目录,通过编写mkdev.sh在目录内快速创建一些设备文件
#shmkdev.sh ;快速创建设备文件
6、回到radisk_img的目录中卸载ramdisk文件系统,实现系统更新:
#umonut/mnt/ramdisk
以上步骤成功制作了一个ramdisk文件系统映像,可压缩节省FLASH占用空间。
三、嵌入式系统开发
通过前面两个实验,已经做了Linux内核镜像zImage及根文件系统ramdisk_img.gz,下面的实验通过之前这两个文件熟悉整个嵌入式系统的开发过程.
3.1 基本原理简介
原理内容如果详细介绍篇幅过多,这里只做简单的说明:
1) Bootloader:为PC机引导加载程序的一部分,主要作用是将内核映像从硬盘读到RAM中,跳转到相应地址运行操作系统,目前参考书中比较常见的作为引导嵌入式操作系统的Bootloader以U-Boot居多。
2) minicom:为一款串口通信软件,用于实现串口通信。第一次使用软件时需要根据实际情况进行串口的设置,由于前面同学基本已经做好,故无需多少改动。
3) Tftp传输协议:基于UDP协议的简单文件传输协议,以目标板作为客户机。
4) NFS:Net File System,网络文件系统,通过NFS用户和程序可以像访问本地文件一样访问远端系统上的文件。前面在做内核镜像时已支持该网络文件系统。
3.2实验内容
1) 将之前制作的内核镜像及根文件系统复制到实验室的tftpboot文件夹内,分别命名为wzs_zImage及ramdisk_wzs.gz;
2) 进入minicom中,打开嵌入式开发平台的电源,在boot时进行干预,进行一些配置:
x210# setenv ipaddr 192.168.207.122 ;本机(即嵌入式开发平台)地址
x210# setenv serverip 192.168.207.22 ;服务器地址
x210# setenv ramdisk root=/dev/ram rw initrd=0x40000000,8M
x210# setenv bootargs console=ttySAC2,115200 $ramdisk ;指示挂载ramdisk作为根文件系统
x210# tftp 0xc0008000 wzs_zImage
x210# tftp 0x40000000 ramdisk_wzs.gz ;将内核镜像和文件系统分别挂载到相应内存地址
x210# bootm 0xc0008000 ;系统开始加载内核
Ø 启动。。。。。。
3)先配置网络,再使用mount命令将主机(开发板)的/mnt目录挂到服务器(电脑)的/exp目录下:
#ifconfigeth0 192.168.207.122
#mount192.168.207.22:/exp /mnt -o nolock,proto=tcp
之后,尝试简单编写了简单的hello程序,通过不同的编译器进行编译分别实现了在主机和服务器上的运行。
Ø 交叉编译器的配置:
#exportPATH=$PATH/usr/local/arm-2009q3/bin/
#arm-none-linux-gnueabi-gcc-static -o hello hello.c
(仅适用于当前终端)
3.3 嵌入式系统下软件开发的一般流程(基于Linux)
一般是先在自己的宿主机上搭建好Linux系统环境,如准备好交叉编译器等,接着就是像实验三中的操作,配置好串口之后利用bootloader下载已经移植好的Linux操作系统,接着使用NFS服务把嵌入式系统某个目录挂载宿主机目录下,之后就可以较方便地在宿主机上实现嵌入式系统软件的开发和下载。