第 6 章 嵌入式 Linux 系统构建6.1 Linux 内核的裁剪和编译Linux 内核裁剪的目的是根据应用的需要,裁剪掉嵌入式应用中不需要的功能和代码,留下必要的功能和代码,可以减小内核尺寸,较少存储器需求,降低嵌入式系统功耗,教学系统体积内核裁减集的原理是打开一个菜单,让开发人员在其中选择所需要的功能、特色、配置和参数,配置工具为选择的功能定义相应的 C 语言宏,并通过编译命令的-D 选项传给内核源程序,内核源代码中对宏定义进行检查,使用条件编译的手段,将对仅需要的特色和功能进行编译,生成内核,而未选择的功能和特色则不进行编译,从而达到裁剪内核的目的Linux 内核的裁剪工作包括内核配置、内核编译、根文件系统构建等工作,具体过程介绍如下6.1.1 重新编译生成一个新的 X86 系统内核(1)将新下载的内核源码复制到/usr/src 目录并配置内核相关信息1)复制内核源码到/usr/src 目录:# cp linux-2.4.20.bz2 /usr/src/# cd /usr/src# tar zfvj linux-2.4.20.bz2# ln -s linux-2.4.20 linux# cd linux或# cd /usr/src/linux-2.4.20-82) 清理源代码树# make mrpropermake mrproper 命令会删除所有的编译生成文件、内核配置文件(.config 文件) 和各种备份文件,所以几乎只在第一次执行内核编译前才用这条命令。
3) 进入 menuconfig 配置菜单:# make menuconfig进入基于 ncurses 文本模式图形用户配置界面,该方法不需调用 X Window,兼容性和适用性好,操作简单,使用方便而 make config 则采用对每个配置选项进行单独询问和回答模式,使用麻烦,效率低;make xconfig 要求基于 X Windows 图形库,界面美观,但有时存在兼容性问题2)编译生成新的内核1)删除以前编译生成各种.o 目标文件,但保留内核的配置文件 .config# make clean2) 对内核配置阶段选择的功能和特色进行依赖关系分析,这些功能运行所需要的特色和代码添加到裁剪后的内核中 make dep3)编译新内核和内核模块# make zImage4) 编译可加载模块(即内核选项中选择为 M 的选项) ,编译时间跟 M 选项的数量有关,并将编译好的 modules 拷贝到/lib/modules 下 make modules# make modules_inatall(4) 最终生成的压缩映像的路径arch/i386/boot/zImage(5) 用新的内核启动 Linux1) 将新内核复制到/boot 目录# cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz-x.y.z2) 将启动映象文件复制到/boot 目录 # cp /usr/src/linux/System.map /boot/System-x.y.z.map3) 修改启动设置文件目前大多数使用的都是 grub 启动,需要修改/boot/grub/grub.conf ,添加相应的启动信息,添加内容的最简单格式如下:title 显示在启动菜单上的名称root 根文件系统挂载分区kernel 压缩过的内核文件名initrd 根文件系统文件名如:title My new kernelroot (hd0,2)kernel /boot/vmlinuz-x.y.zinitrd /boot/initrd-x.y.z.img6.1.2 重新编译生成一个新的 ARM 系统内核(1)按照 ARM 嵌入式系统的软硬件配置和功能进行内核配置1) 进入 ARM 内核所在目录# cd /arm2410s/kernel-2410s2) 进入 menuconfig 配置菜单,配置内核,进行所需的更改之后,按 Esc 键退出界面并保存。
make menuconfig(2)编译生成新的内核1)删除以前编译生成各种.o 目标文件,但保留内核的配置文件 .config# make clean2) 对内核配置阶段选择的功能和特色进行依赖关系分析,这些功能运行所需要的特色和代码添加到裁剪后的内核中 make dep3)编译新内核和内核模块# make zImage# make modules(4) 最终生成的压缩映像的路径arch/arm/boot/zImage6.2 根文件系统的制作6.2.1 根文件系统的结构根文件系统包括支持 Linux 正常运行所需的程序和数据,如系统命令文件、运行库、系统进程代码和配置文件,包括: 基本文件系统结构:/dev,/proc,/bin,/etc,/lib,/usr,/tmp,/var,/home,/mnt 基本程序运行所需函数库:glibc, uclibc 基本系统配置文件: rc, inittab 必要的设备支持文件: /dev/hd*, /dev/tty*, /dev/fda0 必要的系统命令:sh, ls, cp, mv, rz, ifconfig6.2.2 制作根文件系统映像本节讲述如何在旧的根文件系统中加入新命令或文件的过程。
1)将旧的根文件系统解压缩到一个目录中1)复制旧的根文件系统映像文件 # cp linux-v7.2/img/root.cramfs . [ 当前目录是/root] 2)挂载旧根文件系统 # mount -o loop root.cramfs /mnt/nfs 3)把根文件系统的内容复制出来 # cp -rf /mnt/nfs/ /root/rootfs (2)将新的文件加入到根文件系统目录中1)编辑一个 hello world 的 C 程序,然后编译 # armv4l-unknown-linux-gcc -o hello hello.c 2)移动编译出来的 hello 文件到/root/rootfs/ # mv hello /root/rootfs [当前目录是/root] (3)将/root/rootfs 中的文件打包要成 cramfs 文件系统类型的映像文件 # mkfs.cramfs rootfs/ rootfs.cramfs (4)烧写新的根文件系统1)复制 rootfs.cramfs 到虚拟机与 Linux 的共享目录 # cp rootfs.cramfs /mnt/hgfs/share 2)重启实验箱,按任意键(除了 Enter 键)进入 vivi 的命令行界面,然后输入命令 Load flash root x 打开超级终端的“传送”->“发送文件”,“浏览”选择虚拟机与 Linux 的共享目录 E:\share 里的 rootfs.cramfs,“协议”选择 Xmodern,最后点击“发送” (5)测试新加入根文件系统的命令 待烧写完后重启实验箱,按“Enter 键“进入 Linux 查看在根目录下是否存在可执行文件 hello# ls # ./hello 6.3. VIVI、内核和根文件系统的烧写6.3.1 超级终端设置Windows 超级终端将 Windows 的串行口与开发板的串行口相连,是嵌入式 Linux 的访问接口,用于输入输出、信息显示和程序下载。
超级终端必修进行正确的设置才能与嵌入式开发板建立连接,需要设置的参数包括:(1)用串口线将 PC 的串口(缺省为 COM1)与开发板串口(VIVI 和 Linux 内核缺省使用 COM1,若要修改串口号,则应修改 vivi 和linux 内核源代码并进行重新编译) ;(2) 设置超级终端的串口号,一般用 COM1,因为串口线物理上连接了 PC 的 COM1;(3)设置波特率,必须与 vivi 和 Linux 内核中对串口的设置一致,缺省为 115200bps;(4)设置数据位、停止位和校验方式,必须与 vivi 和 Linux内核中对串口的设置一致,缺省为 N81具体设置方法如下:(1)运行 Windows 系统下的超级终端(HyperTerminal)应用程序,新建一个通信终端如果要求输入区号、号码等信息请随意输入,出现如图 2-12 所示对话框时,为所建超级终端取名为 arm,可以为其选一个图标单击“确定”按钮图 1.5.1 创建超级终端(2)在接下来的对话框中选择 ARM 开发平台实际连接的 PC 机串口(如 COM1) ,按确定后出现如图 2-13 所示的属性对话框,设置通信的格式和协议。
这里波特率为 115200,数据位 8,无奇偶校验,停止位 1,无数据流控制按确定完成设置图1.5.2 设置串行口(3)完成新建超级终端的设置以后,可以选择超级终端文件菜单中的另存为,把设置好的超级终端保存在桌面上,以备后用用串口线将PC 机串口和平台UART0 正确连接后,就可以在超级终端上看到程序输出的信息了在Windows xp 平台下通过超级终端烧写 vivi(bootloader)、内核(Kernel)、根文件系统(root)的步骤如下:(1)复位2410-S 开发板,按住pc 机键盘的“Back Space”键,进入vivi> 命令模式,格式化flash 并重新分区;(2)运行load flash {vivi|kernel|root} x,此命令用于使用xmodem 协议通过串口下载文件到开发板中,其中参数为vivi|kernel|root 之一;(3)启用FTP 服务,上传应用程序压缩包并解压缩;(4)重新启动验证烧录是否成功6.3.2 格式化flash打开超级终端,先按住PC 机键盘的Back Space 键,然后启动2410-S,进入vivi ,按照以下命令格式化flash,重新分区,如图1.5.3。
vivi>bon part 0 128k 192k 1216k 4288k:m 64704k 回车图1.5.3 格式化flash6.3.3 烧写vivi这时已格式化flash,运行的是SDRAM 中的vivi.注意如果这时重启或断电会丢失所有数据,否则必须用Jtag 重新烧写vivivivi>load flash vivi x 回车此时超级终端提示:Ready for downloading using xmodem...Waiting...点击超级终端任务栏上“传送”下拉菜单中的“ 发送文件”,选择协议为Xmodem ,选择镜像文件vivi,点击“发送” ,如图 1.5.4,10 秒左右vivi 就烧写到flash 里了.这时要复位2410-S,重新进入vivi>来烧写kernel,root.图1.5.4 烧写vivi6.3.4 烧写内核映象zImagevivi>load flash kernel x 回车出现提示:Ready for downloading using xmodem...Waiting...点击超级终端任务栏上“传送”下拉菜单中的“ 发送文件”,选择镜像文件zImage,协议为Xmodem,点击“ 发送” ,如图 1.5.5,4 分钟左右zImage 传输完毕,zImage 先传输到SDRAM中,再把数据从SDRAM 复制到flash 里,请等待这一过程结束到出现vivi> ,再烧写root,否则会导致烧写kernel 失败。
图1.5.5 烧写zImage6.3.5烧写根文件系统(root)vivi>load flash root x 回车Ready for downloading using xmodem...Waiting...点击超级终端任务栏上“传送”下拉菜单中的“ 发送文件”,选择镜像文件ro。