第一篇:应用Scratchbox构建基于CF卡的嵌入式linux系统
应用Scratchbox构建基于CF卡的嵌入式Linux系统
石涛 师卫
(太原理工大学信息工程学院 山西省 太原市 030024)
摘要: 本文介绍了一种应用Scratchbox构建Linux操作系统的新方法,详细论述了应用Scratchbox和Busybox等开源软件在CF卡上构建一个嵌入式Linux操作系统的全过程。关键词:Busybox; Scratchbox ;CF ;嵌入式Linux操作系统 中图法分类号:TP399文献标识码:A
Construction of embeded Linux on CF card using Scratchbox
SHI Tao, SHI Wei
(Department of Information Engineering,Taiyuan University of Technology,Shanxi Taiyuan,030024)
Abstract:This paper introduces a new method of building embedded Linux using Scratchbox.It also describes the whole process in detail of building a embedded Linux on CF card using Scratchbox and Busybox etc, open source software.Key Words:Busybox;Scratchbox;CF;embedded Linux
面的4项内容,分别来构建Linux根文件系统,这样不仅增加了开发的时间和成本,而且增加了开发的难度,很难成功。在长期的摸索和实践中,我们发现了一种新的开源软件Scratchbox,利用他来构建嵌入式Linux系统可以达到事半功倍的效果。
Scratchbox是一个交叉编译的工具组,可以简化嵌入式Linux应用开发。Scratchbox提供了一组工具,用这组工具我们可以构建一个完整的Linux交叉编译环境。用Scratchbox来构建嵌入式Linux系统具有以下优点:
1)运行与chroot的环境中,完全独立于主机,编译2)可以很容易的变换目标系统中的工具链。3)根据Linux系统的目标运行环境对chroot后的系过程将与主机系统无关。
引言
Linux由于其内核的可裁剪性,而受到嵌入式市场应用领域的青睐。在某些领域,Linux实际上已经处于领导地位,成为最流行的嵌入式操作系统之一。然而,我们在应用嵌入式Linux操作系统时,都面临着如何快速方便的构建一个特定的嵌入式环境的问题。本文在这里探索了一种新的方法,利用Scratchbox、Busybox等开源软件实现基于CF卡的嵌入式linux系统的构建。
统进行定制,这样就可以进行交叉编译,使软件误认为是在1、嵌入式Linux系统构建方法介绍
嵌入式Linux系统包含引导程序、内核和文件系统3
目标平台上进行编译。
4)可以自动创建Linux的根文件系统所需的目录结构。基于Scratchbox以上几个优点,我们完全可以在自己
部分。对于嵌入式Linux系统来说,这三个部分是必不可少的。在这3个部分中,构建Linux的根文件系统是最困难的。在这里主要介绍一些构建Linux根文件系统的方法。
Linux的根文件系统具有非常独特的特点,就其基本组成来说,Linux的根文件系统应该包括支持Linux系统正常运行的基本内容,包含着系统使用的软件和库,以及所有用来为用户提供支持架构和用户使用的应用软件。因此,至少应该包括以下几项内容。
1)基本的文件系统结构,包含一些必需的目录:2)基本程序运行所需的库函数,如Glibc/uC-libc。3)基本的系统配置文件,比如rc,inittab等脚本文/dev,/proc,/bin,/etc,/sbin,/usr,/lib,/tmp等。的主机系统中用Scratchbox构建一个基于目标平台的虚拟系统,chroot进这个系统之后,对工具链和函数库进行定制编译。然后将Scratchbox创建好的根文件系统拷贝到目标平台上即可。
2、构建嵌入式Linux系统
2.1 Linux操作系统裁剪
由于CF卡的容量大小有限,我们在CF卡上构建Linux
操作系统时,需要对Linux内核进行裁剪。要得到一个精简的Linux操作系统,大致有二个步骤:编译裁剪内核,形成精简的内核映像;构建根文件系统,形成可以运行的新系统。
件。
4)基本的应用程序,如sh,ls,cp,mv等。
传统的构建Linux根文件系统方法,通常都是按照上
2.2.1 编译Linux内核
Linux内核裁剪主要是根据系统所需要的功能,缩减掉不需要的模块和组件,重新编译内核。Linux内核由专门的机构维护,我们可以从
Linux
官方网站
(http:// 通信地址:太原理工大学北区3241信箱 邮编:030024
联系电话:0351-6011570,***师卫 男
太原理工大学信息工程学院,电路与系统 硕士导师,主要研究方向嵌入式系统应用
第二篇:构建嵌入式linux系统
构建嵌入式linux系统
(MP3播放器)
功能要求:
(1)系统(bootloader,kernel,rootfs)烧写在板子中;
(2)打开电源开关,系统自动启动,启动最后进入到一个GUI界面(MP3播放器)。
(3)用户可以操作该界面,播放歌曲。
具体要求:
(1)自定义的bootloader添加内核启动功能;或者修改u-boot的go命令使之能够启动zImage。
(2)根文件系统制作时,移植Qt库。
(3)sqlite3的移植
(4)madplay移植
./configure--help
--host=arm-linux
第三篇:基于CF卡的 linux系统制作
在CF卡上安装嵌入式linux全过程
吴刚 2007-4-4 摘要:本文主要介绍在一块128M的CF卡上定制安装linux操作系统,并在此基础上建立一个简单的应用平台。
关键词:extlinux,busybox, CF卡,嵌入式linux
随着信息技术和网络技术的高速发展,嵌入式技术的广泛应用,嵌入式系统已经打破传统PC工业的垄断地位,成为非PC设备的主体。而作为嵌入式系统,应用环境通常比较恶劣,而应用又比较简单,为保证系统的稳定性和便携性通常使用DOM卡或CF卡一类的存储设备来代替硬盘。
经过一段时间的摸索和收集资料终于在一块CF卡上实践安装了一个满足特定需要的嵌入式linux系统,这里取名为cflinux.在这里首先要感谢《babylinux制作全过程的》作者,正是这片文章,为我制作cflinux指明了道路。本文将讲述在一张容量为128M的CF卡上定制安装嵌入式linux操作系统的详细过程,一 主机和目标机情况简介
主机:
Linux:Red Hat 9.0 Kernel: 2.4.20 目标机:
基于X86的工控板
二 cflinux简介
cflinux是一运行于CF卡上的经过自定义剪裁的嵌入式linux操作系统。因其运行于CF卡上,故取名为cflinux.当此操作系统和应用环境搭建好后可以通过网络telnet和串口访问目标板,可运行QT/E图形界面应用程序。可以通过串口,网口和USB口和外围设备交互。既可作为嵌入式操作系统,也可作为启动盘作为系统维护工具。
三 linux得引导过程简介
在系统启动时,主板上的BIOS会读取硬盘的主引导记录(MBR),MBR中存放的是一段很小的程序,他的功能是从硬盘读取操作系统核心文件并运行,因为这个程序太小了,因此通常这个小程序不具备直接引导系统内核的能力,他先区引导另一个稍微大一点的小程序去引导系统内核。在linux系统中这样得小程序有LILO,GRUB和SYSLINUX等。我们在这个项目中这里用到的引导程序是SYSLINUX得一个分支:EXTLINUX。
Linux系统内核被引导程序装进内存并运行后,linux内核会检测系统中得各种硬件,并做好硬件得初始化工作,使他们在系统正式运行后能正常工作。剩下就是linux内核要做得最后一个工作:运行/sbin下得init程序。Init是英文单词(initialization)初始化得简称,init程序得工作是读取/etc/inittab文件中的指令,对系统的各种软硬件环境做最初的初始化工作,最后运行gettty活mingetty等待用户输入用户名和密码(当然根据需要也可以跳过登录这个步骤,直接以root身份登录)。所有的工作就是这么简单。明白了这个道理,你也可以写一些脚本程序让他在系统启动时的特定时间完成运行,完成你指定的任务。/sbin/init程序只是系统默认的运行的第一个程序,他可以是一个二进制程序也可以是一段bash脚本,一个指向另一个程序的链接。他的位置也并不一定在/sbin下,只要启动内核时加上init参数节能被运行,开始时给内核加上init=/bin/sh参数,内核就能直接运行时并给出提示符,不需要登陆。
四 extlinux安装
EXTLINUX是SYSLINUX的一个新的派生。可以从linux系统的ext2和ext3文件系统启动。EXTLINUX使用和SYSLINUX相似,只需做一点改动即可。首先从http://www.xiexiebang.com/pub/linux/utils/boot/syslinux/ 上下载syslinux-3.20.tar.gz。
cp syslinux-3.20.tar.gz /usr/tmp tar xzvf syslinux-3.20.tar.gz 进行解压。然后用IDE to CF转接卡把CF卡连到主机上(注意:一般CF卡是不支持热插拔的,故插上CF后一般需要重新启动主机系统)。我的CF卡对应的设备文件是hdd1.在这里先使用fdisk工具把CF卡分成两个区,一个用于存放内核和randisk,另一个用于存放应用程序及相关文件。Fdisk的使用可参见相关资料,这里不做详细说明。我的CF卡主分区为hdd1,扩展分区为hdd2,将所有的扩展分区都分给逻辑分区hdd5。分好区后,将hdd1 和 hdd5格式化为ext2系统 mke2fs –m 0 /dev/hdd1 mke2fs –m 0 /dev/hdd5 //-m 0参数的作用是告诉系统不为root保留空间 一切准备好后,就可以安装EXTKINUX了,安装步骤如下: mount –t auto /dev/hdd1 /mnt cd /usr/tmp/syslinux-3.20/extlinux./extlinux –i /mnt
安装成功后会提示extlinux 成功安装到/mnt,然后在/mnt目录下会出现extlinux.sys文件。
umount /mnt 至此extlinux已经安装完毕,可以把CF卡插到工控板上,上电启动一下看看有什么效果。如果安装成功的话,启动后会出现如下的提示:
EXTLINUX 3.20 2006-08-06 EBIOS Copyright(c)1994-2005 H.peter Anvin Could not finf kernel image:linux boot: 注:关于extlinux的详细使用方法,请参阅syslinux-3.20目录下的extlinux.doc文件
五 linux内核编译
在内核编译前,我们首先要明确你需要内核支持什么样的硬件,支持多少种分区类型和文件系统,支持那些网卡,支持那些网络协议等等。虽然现在有128兆的空间,但也不能什么都要,够用就行啊。好了,现在开始内核的编译工作。首先准备好内核代码,可以到官方网站上下载,我的内核源码是安装linux时带上的,在/usr/src/linux-2.4/目录下。cd /usr/src/linux-2.4 make mrproper 清理源码树 make menuconfig 然后对各项取舍如下:(至于具体配置项的意义,请参考相关资料,不在本文讨论范围之内)
code maturity level options 先不选,当我们配置好常规的东西,要加入framebuffer支持时再将这一项选上。因为在2.4.20版本中,对frambuffer的支持尚属于试验性代码,如果不选择此项将不能配置frambuffer.Load module support 取消选择此项,为了简化系统的制作,这个项目中将不选择可加载内核模块的支持。
Processer type and features Processor family中选择你需要的cpu类型,如果你想让老至386,新到p4的CPU都能运行cflinux的话,请选择386,否则根据实际情况来选择。建议选386。
General setup Networking support 都选上
PCI支持 选上,除非你不用PCI设备,不过一般人都要的,因为大部分的网卡都是PCI的。
System V ipc 选上 Systrl support选上
Kernel support for ELF 选上
其他内容如果没什么特殊需要,都不选。
Memory technology devices(MTD)不选
Parallel port support 由于本项目中需要使用并口打印机,故将此项选上
Plug and play configuration 不选
Block devices Normal floppy disk support 不选
Loopback device support RAM disk support Initial RAM disk(initrd)support Per partion statics in /proc/partions
以上几项都选上。由于这几项比较重要这里做详细说明。Loopback device 即回环设备,我们平时用的命令瓜子ramdisk或光盘镜像时都用到回环设备。如:mount –o loop ramdisk.img /mnt RAM disk support 即内存磁盘(比较贴切的说法是虚拟磁盘,即拨出一部分内存当磁盘用)。本项目中将所有系统的的文件都做成ramdisk,所以在运行时你在根文件系统上所作的操作都是在内存中完成的,但形式上和在真正的磁盘上运行一样。只不过放在RAM disk上的所有内容会在系统关闭后全部消失。
不仅在运行cflinux时用到ramdisk,我们在制作根文件系统时也用到ramdisk。学习ramdisk的使用也是制作cflinux的重要目标之一。在linux中还支持另外一种虚拟磁盘:shm.(shared memory),这种要虚拟磁盘机制比ramdisk更加先进。Ramdisk的大小是固定的,由编译内核时的default ram disk size决定,默认为4096K,因为本项目中要往ramdisk中放很多东西,故这里我们要将其改为8192K(8M)。也可以在内核加载钱加上ramdisk_size=参数来决定他的大小,但系统一启动,ramdisk的大小是不能改变的,而shm的大小却是动态改变的。默认情况下为物理内存的一半,当系统需要更多内存的时候,他就自动缩小。系统内存富余时,他又会自动增大,这样可以充分灵活的利用内存空间,shm通常作为磁盘的高速缓存,放在系统运行中的临时文件等。既然shm这么好,为什么这里还使用ramdisk呢,因为ramdisk可以很方便的在系统启动时加载,而shm则没那么容易。Initial RAM disk(initrd)support 即初始化ramdisk支持,这个选项让内核有能力在内核加载阶段就能装入RAMDISK,并运行其中的内容。否则只能在系统运行阶段用ramdisk,我们平时编译了一个内核后,如果你的根文件系统用的是ext3,而你没有把ext编译进内核,而作为一个模块编译了,那么就需要用mkinitrd命令做一个initrd,这个ramdisk里放了ext3的模块,这样内核在加载根文件系统前就能正确识别ext3系统,否则内核加载的最后一步就会出现kernel panic cant not find init„..的错误。
Per partion statics in /proc/partions 这个选项不是必须的,但是不把这个选项编译进内核在执行fdisk指令时就会提示找不到/proc/partions,另外还可能出现不能以简写的挂载命令来挂载文件系统。所以我把该选项也编译进内核。
Multi-device support(RAID and LVM)不选 Cryptography support(CryptoAPI)不选
Networking options 在这一大项中需要把下列项目编译进内核: Packet socket:mmapped IO TCP/IP networking 对于IP:advanced router 这项,如果你想重点把cflinux用做静态路由软件,那么把这项编译进去。另外unix domain sockets 这项也不必选择,只有运行X的情况下才需要这项。
Telephony support 不选
ATA/IDE/MFM/RLL support 选上,然后在下面的“IDE,ATA and ATAPI Block Devices”按钮就被激活,下面几项选上,其余都不用选
Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support Include IDE/ATA-2 DISK support Auto-Geometry Resizing support Include IDE/ATA CDROM support
SCSI support 因为这个项目中是通过CF卡启动的,所以把这项也选上。在这个大项中只需选择一下3项即可: SCSI disk support SCSI generic support SCSI tape support
Fusion MPT device support 不选 IEEE1394(FireWrite)support 不选
I2O device support 选上,子项全部选上 Network device support 选上,这样就可以支持网卡了,其余都选择N.然后点Ethernet(10 or 100 Mbit)按钮选择你 需要的网卡驱动,你可以把最常见的几种Reltek8139,NE2000,3COM等网卡编译进内核.虽然网卡的驱动通常都很小
如果你发现你需要的网卡是灰色的,不能点,那么先确定他上一级的选项已经点了,比如你想选NE2000的网卡,就必需先选择ELSA,VLB,PCI and on board controllers.如果还不能点,那么请确定是否已经把PCI的支持选项选上了,(在Geneal setup)里.没有PCI的支持,PCI的网卡将不能选.Amateur Radio support 不选 IrDA(infrared)support 不选 ISDN subsystem 不选
Old CD-ROM drivers(not SCSI,not IDE)不选
Import core support 因为本项目中要使用到键盘和鼠标,所以选上该项,其子项也全部选中。然后把Horizontal screen resoulution 改为 800,vertial scrren resoulution 改为600。
Character devices 这一项和block devices一样重要,这里将作重点讲述。
如果要在终端上显示系统信息就必须将virtual terminal 和support for console on virtual terminal 选上。因为本项目中防治系统信息覆盖掉QT的图形界面,所以没选这两项。
接下来就是对串口的指出。因为本项目中需要通过串口和并口与设备交互,故下面几项都要选上:
Standard(gtneric18250/16550 and compatible UARTs)serial support Support for console serial port Extended dumb serial driver options Support special multport boards Non-standard serial port support
Unix98 PTY support(telnetd 服务用到)Parallel printer support Support for console on line printer Support for user-space parallel device drivers
哈哈,下面的文件系统可是个重头戏哦,配置完这一项,整个内核配置也基本急速了。选上下面几个常用的文件系统选项: Kernel auto mounter support Kernel automounter version 4 support DOS FAT fs support MSDOS fs support UMSDOS:unix-like file system on top of standard MSDOS VFAT fs support EFS file system support /proc file system support 少了他很多软件和命令都不能运行 /dev/pts file system for unix98 PTYs telnetd服务用到 ROM file system support Second extended fs support cflinux的基本文件系统
最后是console drivers 这是linux在字符模式下高分辨率显示的内核模块,前面三个子项都选上。
Frame-buffer support 按钮是灰色的不能选,别急,回到第一个大项,选上他,然后在Frame-buffer support的子项中选上 Support for framebuffer devices VESA VGA granphics console 你也可以选择其他的显卡驱动,比如nVida的,但是VESA和VGA是通用性最好的,只要不是几十年前的黑白卡,都兼容VESA和VGA。Support only 8 pixels wide fonts 这个一定要选,否则当你给内核传递vga=768参数,让linux在字符界面下高分辨率显示的时候,系统会因为找不到合适的字体而返回低分辨率模式。
好了,所有的内核配置到这里就全部结速了,剩下的几个大项全部不用选。保存退出。make dep make baImage 编译好的内核放在:/usr/src/linux-2.4.20-8/arch/i386/boot目录下 将其拷贝到CF卡的主分区上: mount /dev/hdd1 /mnt cp /usr/src/linux-2.4.20-8/arch/i386/boot/bzImage /mnt
到此为止我们已经安装好了extlinux和内核编译,现在就可以试试刚编译的内核是否能启动了。不过首先要在bzImage所在的目录建立extlinux.conf配置文件,告诉extlinux在哪里寻找内核和ramdisk。extlinux.conf的格式如下: default emblinux display logo.txt label emblinux kernel bzImage append root=/dev/hdc1 initrd=ramdisk.img ide=nodma vga=0x0314 保存即可。注:在工控板上cf卡对应的设备是hdc所以这里用root=/dev/hdc1 指明根文件系统所在 initrd=ramdisk.img 指明ramdisk名称。
ide=nodma 告诉内核不使用DMA控制器,这是针对CF卡的一个选项。vga=0x0314 指明分辨率为800×600
执行 umount /mnt 卸载CF卡,然后将CF卡插到工控板上上电启动,看看是不是能看到系统内核启动信息了啊。
六 编译busybox 1 busybox简介
Busybox是一个集成一百多个最长用的linux命令和工具的软件,他甚至还集成了http服务器、dhcp服务器和telnet服务器,而所有这些功能却只有1M左右的大小。我们平时用的那些linux命令就好比分离的电子元件,而busybox就好比是一个集成电路,把常用的工具和命令集成压缩在一个可执行的文件里,功能基本不变,而大小却小很多倍,在嵌入式式linux中使用非常广泛。现在最新的busybox版本是1.5.0可以从busybox的官方网站上下载得到:http://www.xiexiebang.com> # # Note: BusyBox init doesn't support runlevels.The runlevels field is # completely ignored by BusyBox init.If you want runlevels, use # sysvinit.# # Format for each entry: # # id == tty to run on, or empty for /dev/console # runlevels == ignored # action == one of sysinit, respawn, askfirst, wait, and once # process == program to run # Startup the system null::sysinit:/bin/mount-o remount,rw / null::sysinit:/bin/mount-t proc proc /proc null::sysinit:/bin/mount-a >> /etc/mtab null::sysinit:/bin/hostname-F /etc/hostname null::sysinit:/sbin/ifconfig lo 127.0.0.1 up null::sysinit:/sbin/ifconfig-a eth0 null::sysinit:/sbin/ifconfig eth0 192.168.4.44 netmask 255.255.255.192 null::sysinit:/sbin/route add-net 127.0.0.0 netmask 255.0.0.0 lo null::sysinit:/sbin/route add-net 192.168.4.0 netmask 255.255.255.255 eth0 # now run any rc scripts ::sysinit:/etc/init.d/rcS # Set up a couple of getty's # 使用login登陆管理 tty1::respawn:/sbin/getty 38400 tty1 #不需要登陆直接进入控制台,进行操作 #tty1::respawn:/bin/sh tty2::askfirst:/bin/sh # Put a getty on the serial port #ttyS0::respawn:/sbin/getty-L ttyS0 115200 vt100 # Stuff to do for the 3-finger salute ::ctrlaltdel:/sbin/reboot ::restart:/sbin/init # Stuff to do before rebooting null::shutdown:/bin/umount-a –r passwd: root:x:0:0:root:/root:/bin/sh cf:x:1001:0:Linux User,,:/home/soullon:/bin/sh shadow: root::10933:0:99999:7::: cf::13604:0:99999:7::: 注意:这里两个用户都没设密码,如果要加密码胡话在用户名后的第一个“:”和第二个“:”之间加上密码胡hash值。如: root:$1$NuFDgiiI$664QR8N4HSdgkUDKpxEB00:10933:0:99999:7::: shadow-: root::10933:0:99999:7::: cf::13604:0:99999:7::: resolv.conf -> /tmp/resolv.conf fstab: /dev/hdc1 / ext2 defaults 1 1 /dev/hdc1 / ext2 defaults 1 1 none /proc proc defaults 0 0 usbdevfs /proc/bus/usb usbdevfs rw 0 0 none /dev/pts devpts rw,gid=5,mode=620 0 0 none /tmp tmpfs defaults 0 0 /dev/hdc5 /myapp ext2 defaults 0 0 init.d(目录): rcS: #start inetd and telnetd /sbin/telnetd-p 23 #run myapp export QTDIR=/yysg export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/myapp/lib:/usr/lib cd /myapp./myapp –qws issue: Welcome to CFLinux profile : # ~/.bashrc: executed by bash(1)for non-login interactive shells.export PATH= /bin: /sbin: /usr/bin: /usr/sbin: /usr/bin/X11: /usr/local/bin # If running interactively, then: if [ “$PS1” ];then if [ “$BASH” ];then export PS1=“[u@h W]$ ” alias ll='/bin/ls--color=tty-laFh' n/ls--color=tty-F' export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.png=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:';else if [ “`id-u`”-eq 0 ];then export PS1='# ' else export PS1='$ ' fi fi export USER=`id-un` export LOGNAME=$USER export HOSTNAME=`/bin/hostname` export HISTSIZE=1000 export HISTFILESIZE=1000 export PAGER='/bin/more ' export EDITOR='/bin/vi' export INPUTRC=/etc/inputrc export DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile ### Some aliases alias ps2='ps facux ' alias ps1='ps faxo “%U %t %p %a” ' alias af='ps af' alias cls='clear' alias df='df-h' alias indent='indent-bad-bap-bbo-nbc-br-brs-c33-cd33-ncdb-ce-ci4-cli0-cp33-cs-d0-di1-nfc1-nfca-hnl-i4-ip0-l75-lp-npcs-npsl-nsc-nsob-nss-ts4 ' #alias bc='bc-l' alias minicom='minicom-c on' alias calc='calc-Cd ' alias bc='calc-Cd ' fi; inputrc: # /etc/inputrc-global inputrc for libreadline # See readline(3readline)and `info readline' for more information.# Be 8 bit clean.set input-meta on set output-meta on set bell-style visible # To allow the use of 8bit-characters like the german umlauts, comment out # the line below.However this makes the meta key not work as a meta key, # which is annoying to those which don't need to type in 8-bit characters.# set convert-meta off “e0d”: backward-word “e0c”: forward-word “e[h”: beginning-of-line “e[f”: end-of-line “e[1~”: beginning-of-line “e[4~”: end-of-line #“e[5~”: beginning-of-history #“e[6~”: end-of-history “e[3~”: delete-char “e[2~”: quoted-insert # Common standard keypad and cursor #(codes courtsey Werner Fink, securetty: tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 ttyS0 ttyS1 ttyS2 ttyS3 network(目录): interfaces: # Configure Loopback auto lo iface lo inet loopback 八 复制需要的库到/lib目录下 1 看看需要什么库 进入busybox编译目录,执行ldd指令看看需要哪些动态联结库 #cd /usr/tmp/busybox-1.5.0 #ldd busybox 会出现如下信息: libcrypt.so.1-> /lib/libcrypt.so.1(0x40029000)libc.so.6-> /lib/tls/libc.so.6(0x42000000)/lib/ld-linux.so.2-> /lib/ld-linux.so.2(0x4000000) 2 拷贝库文件 然后把这些库文件相关联的库文件都拷贝到相应的目录: #cd /usr/tmp/rootfs/lib #cp –arf /lib/libcrpt*./ #cp –arf /lib/ld-linux*./ #mkdir tls #cp –arf /lib/tls/libc.so*./tls/ 如果你的应用程序还需要其他的动态库,且不是很大的话都可以放过来。 九 制作ramdisk映象文件 cflinux根文件系统需要的所有东西都已经在/usr/tmp/rootfs目录下准备好了。我们将利用ramdisk把这些内容做成ramdisk映象文件。 以下是ramdisk的制作过程。#cd /usr/tmp #mkdir ramdisk #dd if=/dev/zero of=./ramdisk.img bs=1M count=6 读入了 6+0个块 输出了 6+0个块 #mke2fs –m 0 ramdisk.img make2fs 1.32(09-Nov-2002)ramdisk.img is not a block special device Proceed anyway?(y,n)//输入y,按回车键 Filesystem label = OS type:Linux Block size=1024(log=0)1536 inodes ,6144blocks „„„„„„„„„„„„„„„„„„„„ 180 days,whichever comes first.Use tune2fs –c or –I to overrite zero是一个特殊的设备,表示全部为零的字符块。上面这条指令的意思是把系统的第一个ramdisk用全部为0的数据填充。Bs=1M 表示块的大小为1M,count=6 表示有6块。即我们监理了一个大小为6M的ramdisk.接下来就应该往ramdisk中填充文件了: #mount –o loop ramdisk.img ramdisk #cp –arf rootfs/* ramdisk/ #umount ramdisk 做完以上几步,你就应该明白ramdisk设备的含义,他和hda1,hdb1,一样的块设备用mount挂到文件系统下后就可以访问,往里面放东西,但是所有的东西在内存上,关机将丢失所有东西。 十 系统整合 前面已经做好了内核,安装好了extlinux,现在只需要把ramdisk放到bzImage 所 在的目录就可以了。 #mount /dev/hdd1 /mnt #cp ramdisk /mnt #umount /mnt 好了现在就可以把cf卡插到工控板上,试一把了。如果一切正常的话就可以进入登陆界面了,呵呵。 十一 移植应用程序 在本文开始的时候已经说过将操作系统文件放在cd卡的注分区上hdd1上,把应用程序放在逻辑分区hdd5上。因此我们将编译好的应用程序及其相关文件拷贝到hdd5上。由于应用程序用到的共享库不是固定的所以就没有将他们放到ramdisk中,直接和应用程序放在一起,只不过在系统启动后要将这个库目录加到系统库目录路径上即可。在这个项目中,我在hdd5上件了一个lib目录,然后把应用程序用到的库全部放在这个目录下面,然后在profile文件中增加一项两行就行: export LD_LIBRARY_PATH=#LD_LIBRARY_PATH:/myapp/lib export QTIDR=/myapp 十二 参考文献 《BabyLinux制作过程详解》作者:GuCuiwen email:win2linux@163.com 嵌入式系统的主要应用 嵌入式系统是一种包括硬件和软件的完整的计算机系统,它的定义是:“嵌入式系统是以应用为中心,以计算机技术为基础,并且软硬件可剪裁,适用于应用系统对功能、可靠性、成本、体积和功耗有严格要求的专用计算机系统。”嵌入式系统所用的计算机是嵌入到被控对象中的专用微处理器,但是功能比通用计算机专门化,具有通用计算机所不能具备的针对某个方面特别设计的、合适的运算速度、高可靠性和较低比较成本的专用计算机系统。 嵌入式系统的应用前景是非常广泛的,人们将会无时无处不接触到嵌入式产品,从家里的洗衣机、电冰箱,到作为交通工具的自行车、小汽车,到办公室里的远程会议系统等等。在家中、办公室、公共场所,人们可能会使用数十片甚至更多这样的嵌入式无线电芯片,将一些电子信息设备甚至电气设备构成无线网络;在车上、旅途中,人们利用这样的嵌入式无线电芯片可以实现远程办公、远程遥控,真正实现把网络随身携带。其应用领域可以包括: 1.交通管理:在车辆导航、流量控制、信息监测与汽车服务方面,嵌入式系统技术已经获得了广泛的应用,内嵌GPS模块,GSM模块的移动定位终端已经在各种运输行业获得了成功的使用。目前GPS设备已经从尖端产品进入了普通百姓的家庭,只需要几千元,就可以随时随地找到你的位置。2.家庭智能管理系统:水、电、煤气表的远程自动抄表,安全防火、防盗系统,其中嵌有的专用控制芯片将代替传统的人工检查,并实现更高,更准确和更安全的性能。 3.POS网络及电子商务:公共交通无接触智能卡发行系统,公共电话卡发行系统,自动售货机,各种智能ATM终端将全面走入人们的生活。 4.环境工程与自然:水文资料实时监测,防洪体系及水土质量监测、堤坝安全,地震监测网,实时气象信息网,水源和空气污染监测。在很多环境恶劣,地况复杂的地区,嵌入式系统将实现无人监测。 5.机器人:嵌入式芯片的发展将使机器人在微型化,高智能方面优势更加明显,同时会大幅度降低机器人的价格,使其在工业领域和服务领域获得更广泛的应用。 6.工业控制:相对于其他的领域,机电产品可以说是嵌入式系统应用最典型最广泛的领域之一。从最初的单片机到现在的工控机、SOC在各种机电产品中均有着巨大的市场。工业设备是机电产品中最大的一类,在目前的工业控制设备中,工控机的使用非常广泛,这些工控机一般采用的是工业级的处理器和各种设备,其中以X86的MPU最多。工控的要求往往较高,需要各种各样的设备接口,除了进行实时控制,还须将设备状态,传感器的信息等在显示屏上实时显示。这些要求8位的单片机是无法满足的,以前多数使用16位的处理器,随着处理器快速的发展,目前32位、64位的处理器逐渐替代了16位处理器,进一步提升了系统性能。采用PC104总线的系统,体积小,稳定可靠,受到了很多用户的青睐。不过这些工控机采用的往往是DOS或者Windows系统,虽然具有嵌入式的特点,却不能称作纯粹的嵌入式系统。另外在工业控制器和设备控制器方面,则是各种嵌入式处理器的天下。这些控制器往往采用16位以上的处理器,各种MCU,Arm、Mips、68K系列的处理器在控制器中占据核心地位。这些处理器上提供了丰富的接口总线资源,可以通过它们实现数据采集,数据处理,通讯以及显示(显示一般是连接LED或者LCD)。最近飞利浦和ARM共同推出32位RISC嵌入式控制器,适用于工业控制,采用最先进的0.18微米CMOS嵌入式闪存处理技术,操作电压可以低至1.2伏,它还能降低25%到30%的制造成本,在工业领域中对最终用户而言是一套极具成本效益的解决方案。美国TERN工业控制器基于Am188/186ES、i386EX、NEC V25、Am586(Elan SC520),采用了SUPERTASK实时多任务内核,可应用于便携设备、无线控制设备、数据采集设备、工业控制与工业自动化设备以及其它需要控制处理的设备。 7.家电行业是嵌入式应用的另一大行业。现在只有按钮、开关的电器显然已经不能满足人们的日常需求,具有用户界面,能远程控制,智能管理的电器是未来的发展趋势。据IDG发布的统计数据表明,未来信息家电将会成长五至十倍。中国的传统家电厂商向信息家电过渡时,首先面临的挑战是核心操作系统软件开发工作。硬件方面,进行智能信息控制并不是很高的要求,目前绝大多数嵌入式处理器都可以满足硬件要求,真正的难点是如何使软件操作系统容量小、稳定性高且易于开发。Linux核心可以起到很好的桥梁作用,作为一个跨平台的操作系统,它可以支持二三十种CPU,而目前已有众多家电业的芯片都开始做Linux的平台移植工作。1999年就登录中国的微软“维纳斯”计划给了国人一个数字家庭的概念,引导各大家电厂商纷纷投入到这场革命中来,虽然最终未能获得成功,却使信息家电深入人心。如今各大厂商仍然在努力推出适用于新一代家电应用的芯片,英特尔公司已专为信息家电业研发了名为StrongARM的ARM CPU系列,这一系列CPU本身不象X86CPU需要整合不同的芯片组,它在一颗芯片中可以包括你所需要的各项功能,即硬件系统实现了SOC的概念。美商网虎公司已将全球最小的嵌入式操作系统——QUARK成功移植到StrongARM系列芯片上,这是第一次把Linux、图形界面和一些程序进行完整移植(QUARK的内核只有143K),它将为信息家电提供功能强大的核心操作系统。相信在不久的将来,数字智能家庭必将来到我们身边。 这些应用中,可以着重于在控制方面的应用。就远程家电控制而言,除了开发出支持TCP/IP的嵌入式系统之外,家电产品控制协议也需要制订和统一,这需要家电生产厂家来做。同样的道理,所有基于网络的远程控制器件都需要与嵌入式系统之间实现接口,然后再由嵌入式系统来控制并通过网络实现控制。所以,开发和探讨嵌入式系统有着十分重要的意义。 目录 嵌入式系统概述...................................................................................................................4 1.1 嵌入式系统简介.......................................................................................................4 1.2 嵌入式系统的组成...................................................................................................5 1.3 本课题的背景和意义...............................................................................................5 2 硬件平台及ARM体系结构................................................................................................7 2.1 处理器选择...............................................................................................................7 2.2 ARM体系结构............................................................................................................7 3 软件平台...............................................................................................................................9 3.1嵌入式操作系统选择................................................................................................9 3.2 交叉编译环境的建立.............................................................................................10 3.2.1 上位机的软硬件配置.........................................................................................10 3.2.2 硬件连接与调试.............................................................................................11 3.2.3 配置TFTP及NFS服务...................................................................................13 3.2.4 安装交叉编译工具.........................................................................................15 4 移植 Bootloader.................................................................................................................16 4.1 Bootloader 概述.................................................................................................16 U-boot 简介...................................................................................................................17 4.2.1 U-boot 的获取.................................................................................................17 4.2.2 U-boot 目录结构.............................................................................................17 U-boot 的启动过程及工作原理...................................................................................18 4.3.1 启动模式介绍...................................................................................................18 4.3.2 启动阶段1分析...............................................................................................19 4.3.3 启动阶段2分析...............................................................................................20 U-boot的移植过程........................................................................................................20 4.4.1 准备工作...........................................................................................................20 4.4.2 添加支持 NAND Flash 启动功能...................................................................21 4.4.3 添加 NAND Flash 读写功能.......................................................................22 4.4.4 修改 U-boot环境变量保存方式....................................................................22 4.4.5 加入 NAND Flash 闪存型号支持...............................................................23 4.5 U-boot 的烧写及测试.........................................................................................23 4.6 设置U-boot环境变量..................................................................................................24 5 Linux 内核的移植.............................................................................................................25 Linux 内核的结构.........................................................................................................25 Linux 启动过程简析.....................................................................................................26 Linux内核的移植过程..................................................................................................26 5.3.1 选择参考板.......................................................................................................26 5.3.2 修改 NAND Flash 分区信息...........................................................................26 5.3.3 关闭 ECC 校验.................................................................................................27 5.4 CS8900a网卡的移植过程....................................................................................28 5.4.1 修改硬件地址映射...........................................................................................28 5.4.2 添加 CS8900A 内核编译项.............................................................................28 5.5 Linux 内核的剪裁配置.......................................................................................29 5.5.1 使用配置菜单...........................................................................................................29 5.5.2 基本配置选项...................................................................................................30 5.5.3 驱动程序配置选项...................................................................................................31 5.5.4 保存配置文件...................................................................................................31 5.5.5 编译 Linux 内核.............................................................................................31 5.6 内核的下载及启动...............................................................................................32 5.6.1 将引导信息加入内核映像...............................................................................32 5.6.2 内核映像的下载及运行...................................................................................32 6 建立根文件系统.................................................................................................................33 6.1 根文件系统概述...................................................................................................33 6.1.1 根文件系统简介...........................................................................................33 6.1.2 NFS 文件系统与Cramfs文件系统...................................................................33 6.2 建立Linux根文件系统目录...............................................................................33 7 心得体会.............................................................................................................................34 基于嵌入式系统的图形界面应用设计 嵌入式系统概述 1.1 嵌入式系统简介 嵌入式系统是一种以应用为目的,软硬件可裁减,适应应用系统对功能、成本、体积、功耗严格要求的专用计算机系统。随着计算机的发展和应用的普及,嵌入式系统取得了迅猛的发展,嵌入式产品已经渗透到社会经济、军事、交通、通信等相关行业,而且深入到家电、娱乐等各个领域,掀起了一场数字化革命。嵌入式图形用户界面系统是嵌入式系统的一个重要组成部分,它将极大的促进嵌入式技术的发展和应用。 嵌入式系统是当前最热门、最有发展前途的IT应用技术之一。一方面,嵌入式系统广泛的应用于智能家电、手持终端、工业控制等专用设备上,通常这些设备的硬件资源(如处理器、存储器等)非常有限,并且对成本很敏感,有时对实时响应要求很高;另一方面,随着计算机技术的发展,越来越多的嵌入式系统设备需要良好的人机交互界面,这需要一个高性能、高可靠、占用系统资源少的用户图形界面的支持。为了适应嵌入式设备对人机交互界面的要求,本论文对基于嵌入式Linux图形用户界面的设计实现进行了研究。 一方面,嵌入式硬件性能不断提升,使得嵌入式设备上运行精美的图形用户界面成为可能;另一方面,嵌入式手持式消费电子产品的普及,例如PDA(个人数字助理)、智能手机、PMP(便携式多媒体播放器),一个完善的嵌入式图形用户界面成为不可缺少的组成部分,嵌入式GUI(图形用户界面:Graphical User Interface)为嵌入式系统提供了一种应用于特殊场合的人机交互接口。 纵观国际相关产业在图形用户界面方面的发展现状,许多国际知名公司早已认识到GUI在嵌入式产品方面产生的强大增值功能,以及带动的巨大市场价值,因此在公司内部成立了专门从事GUI研究与设计的部门。 图形用户界面(GUI)是一种结合计算机科学、美学、心理学、行为学,以及商业领域需求分析的人机系统工程。这种面向用户的系统工程设计目的是优化产品性能,使操作更人性化,减轻使用者的认知负担,使其更适合用户的操作需要,直接提升产品的市场竞争力。 图形用户界面的广泛流行是当今计算机技术的重大成就之一,它极大的方便了非专业用户的使用,可以通过窗口、菜单方便的进行操作。一个图形用户界面通常由三个基本层次组成,也就是显示模型、窗口模型和用户模型。用户模型包含了显示和交互的主要特征,因此用户图形界面有时也仅指用户模型。 然而,对于嵌入式系统来说,由于其固有的体积、功耗以及价格的限制,使得传统的图形用户界面并不能直接应用于嵌入式系统[41,在嵌入式系统上实现GUI是一个具有挑战性的课题。总的来说,嵌入式GUI要求简单、直观、可靠、占用资源小且反应速度快,以适应系统硬件资源有限的条件嘲。另外,由于嵌入式系统硬件本身的特殊性,嵌入式GUI应具备高度可移植性与可裁减性,以适应不同的硬件条件和使用需求。具体的嵌入式GUI一般具备如下特点: 1.体积小 2.运行时耗用系统资源小 3.上层接口与硬件无关,高度可移植 4.高可靠性 5.在某些应用场合应具备实时性 目前,嵌入式GUI的开发正处于起步阶段,有许多技术难题尚待解决,因此对嵌入式图形系统的研究成为嵌入式系统研究及发展中的一个重要内容。 可以预见,随着电子、计算机等行业的高速发展,嵌入式系统将以它专用化,效率高的特性深入实际应用的各个领域,因而开发与改进嵌入式图形用户界面有着长远的意义。 1.2 嵌入式系统的组成 嵌入式系统一般可以分为四个部分:嵌入式处理器、嵌入式外围设备、嵌入式操作系统和嵌入式应用软件,如图1-1所示。 图1-1 嵌入式系统的组成 1.3 本课题的背景和意义 嵌入式导航计算机是飞机,车辆,导弹和船舶等运载体上的重要设备,主要任务是按照原定的计划和任务,以要求的精度,在一定时间内将载体引 导至目的地。嵌入式导航计算机主要分为两部分:硬件电路,嵌入式操作系 统。本课题的目的就是针对其硬件环境,搭建起一个高效、稳定的嵌入式操 作系统的平台。它具有通用操作系统的基本特点,能够有效管理复杂的系统 资源;能够快速的处理大量的信息;能够提供库函数、驱动程序、工具集以 及部分应用程序。在这个系统平台上可以运行导航程序,接受传感器的数据 经处理后得到任务所需要的信息,从而实施导航任务。 嵌入式Linux有着嵌入式导航计算机操作系统需要的很多特色:支持多 任务处理、中断处理及任务间通信,性能稳定,剪裁性好,开发与使用都很 方便。因此,本设计选用嵌入式Linux作为嵌入式导航计算机的操作系统,这对于实现导航计算机的高效率、低功耗具有现实意义。 图1-2 嵌入式导航计算机硬件平台结构图 1.4 本课题的主要工作和研究内容 本课题的最重目标是为嵌入式导航计算机移植Linux操作系统。通过参 阅大量文献,学习嵌入式Linux系统和 ARM 体系微处理芯片S3C2410的相 关知识,研究启动下载程序 Bootloader 和 Linux内核的基本工作原理,并且 搭建交叉编译平台,重点是移植Bootloader和内核,以及制作根文件系统。具体工作内容包括: (1)学习Linux操作系统的知识。 (2)了解 ARM的体系结构和S3C2410芯片硬件结构。(3)完成交叉编译环境的建立。(4)修改并移植U-boot 1.2.0。 (5)修改和裁剪Linux 2.6.24.4内核,移植网卡驱动程序。(6)制作根文件系统。(7)编写应用程序进行测试。 (8)将内核和根文件系统部署到开发板。2 硬件平台及ARM体系结构 2.1 处理器选择 本设计的处理器选择高性能、低功耗的ARM9微处理器Samsung S3c2410。S3c2410 是著名半导体公司 Samsung 推出的一款 32 位 RISC 处理器。S3c2410的内核基于 ARM920T,带有MMU功能,主频高达203MHz,可以支持 Linux、WinCE 等主流嵌入式操作系统。同时它还采用了一种叫做Advanced Microcontroller Bus Architecture(AMBA)的新型总线结构。 此外S3c2410还集成了以下片上功能: (1)16KB指令 Cache和16KB的数据Cache;(2)LCD控制器(支持STN和TFT); (3)4通道DMA; (4)3通道UART; (5)2通道USB; (6)4路PWM和 1个内部时钟控制器; (7)117个通用IO,24路外部中断; (8)16位看门狗定时器;(9)RTC(实时时钟); (10)1通道IIC/IIS控制器; (11)NAND Flash控制器; (12)PLL数字锁相环。 S3c2410 将系统的存储空间分为 8 组(bank),每组大小是 128MB,共1GB。Bank0 到 Bank6 都采用固定 Bank 起始寻址,用于 ROM 或 SRAM。Bank7具有可编程的 Bank的起始地址和大小,用于ROM、RAM或SDRAM。S3c2410还支持从NAND Flash启动,NAND Flash具有容量大、比NOR Flash价格低等特点。系统采用NAND Flash与SDRAM相结合的方式,可以获得非常高的性价比。 2.2 ARM体系结构 ARM微处理器基本架构: ARM9微处理器采用RISC体系结构:优先选取使用频最高的简单指令,避免复杂指令 RISC体系结构应具有如下特点: 1.采用固定长度的指令格式,指令归整、简单、基本寻址方式有2~3种。2.使用单周期指令,便于流水线操作执行。3.大量使用寄存器,数据处理指令只对寄存器进行操作,只有加载/ 存储指令可以访问存储器,以提高指令的执行效率。 4.除此以外,ARM体系结构还采用了一些特别的技术,在保证高性能的前提下尽量缩小芯片的面积,并降低功耗: 5.所有的指令都可根据前面的执行结果决定是否被执行,从而提高指令的执行效率。 6.可用加载/存储指令批量传输数据,以提高数据的传输效率。7.可在一条数据处理指令中同时完成逻辑处理和移位处理。8.在循环处理中使用地址的自动增减来提高运行效率。ARM微处理器的寄存器结构: 1.ARM处理器共有37个寄存器,被分为若干个组(BANK),这些寄存器包括: 2.31个通用寄存器,包括程序计数器(PC指针),均为32位的寄存器。3.6个状态寄存器,用以标识CPU的工作状态及程序的运行状态,均为32位,目前只使用了其中的一部分。 4.同时,ARM处理器又有7种不同的处理器模式,在每一种处理器模式下均有一组相应的寄存器与 之对应。即在任意一种处理器模式下,可访问的寄存器包括15个通用寄存器(R0~R14)、一至二个状态寄存器和程序计数器。在所有的寄存器中,有些是在 7种处理器模式下共用的同一个物理寄存器,而有些寄存器则是在不同的处理器模式下有不同的物理寄存器。 ARM微处理器的指令结构: ARM微处理器的在较新的体系结构中支持两种指令集:ARM指令集和Thumb指令集。其 中,ARM指令为32位的长度,Thumb指令为16位长度。Thumb指令集为ARM指令集的功能子集,但与等价的ARM代码相比较,可节省30% ~40%以上的存储空间,同时具备32位代码的所有优点。 ARM9系列微处理器具有以下特点: 1.5级整数流水线,指令执行效率更高。2.提供1.1MIPS/MHz的哈佛结构。 3.支持32位ARM指令集和16位Thumb指令集。4.支持32位的高速AMBA总线接口。 5.全性能的MMU,支持Windows CE、Linux、Palm OS等多种主流嵌入式操作系统。 6.MPU支持实时操作系统。 7.支持数据Cache和指令Cache,具有更高的指令和数据处理能力。大小都为16K。8.ARM9系列微处理器主要应用于无线设备、仪器仪表、安全系统、机顶盒、高端打印机、数字照相机和数字摄像机等。 9.ARM9系列微处理器包含ARM920T、ARM922T和ARM940T三种类型,以适用于不同的应用场合。软件平台 3.1嵌入式操作系统选择 本设计的嵌入式操作系统选择嵌入式Linux操作系统。 嵌入式操作系统是一种支持嵌入式系统应用的操作系统软件,它是嵌入式系统(包括硬、软件系统)极为重要的组成部分,通常包括与硬件相关的底层驱动软件、系统内核、设备驱动接口、通信协议、图形界面、标准化浏览器等Browser。 一般情况下,嵌入式操作系统可以分为两类,一类是面向控制、通信等领域的实时操作系统,如 WindRiver 公司的 VxWorks、ISI 的 pSOS、QNX系统软件公司的QNX、ATI的 Nucleus等;另一类是面向消费电子产品的非实时操作系统,这类产品包括个人数字助理(PDA)、移动电话、机顶盒等。嵌入式 Linux 操作系统 Linux 的嵌入式改造主要围绕体积和实时性展开,目前已经有很多公司在进行这方面的工作,其中包括 RT-Linux,uClinux,Embedix,Xlinux,MidoriLinux和红旗嵌入式 Linux等等。 与目前市场上的众多商业的实时系统相比,嵌入式Linux除具有内核稳定,功能强大,支持多种硬件平台,兼容性好的优势外,还拥有以下的特点:(1)完全开放源代码 嵌入式 Linux完全开放其源代码,这使得修改,裁剪 Linux成为可能,开发者可以根据实际需要优化操作系统代码,降低整个系统的开销与能耗。(2)成本低 GPL协议保证了源自Linux的嵌入式Linux也是开放源代码的自由软件。而大多数嵌入式Linux使用的开发工具也是遵守GPL协议的,同样也可以免费获得。 (3)丰富的实用软件支持 Linux 提供了大量的实用程序和各种应用软件。这些软件的正确性和有效性都经过了实际检验,可以根据需要合理利用他们迅速构建嵌入式应用的软件环境。这样可以极大地减小嵌入式软件开发的时间和费用,提高系统可靠性。而商用的实时操作系统也试图提供各种常用软件工具包,但其数量是无法和Linux操作系统匹敌的。由此可见,选择嵌入式Linux操作系统,就有了丰富的资源保障,在节省成本的同时,提高了开发效率。 3.2 交叉编译环境的建立 采用交叉开发环境(Cross Development Environment)是嵌入式应用软 件开发时的一个显著特点,通常在通用计算机上编写程序,然后通过交叉编 译生成目标平台上可运行的二进制代码格式,最后再下载到目标平台上的特 定位置运行,交叉开发环境是指编译、链接和调试嵌入式应用软件的环境,它与运行嵌入式应用软件的环境有所不同,通常采用主机/目标及模式。交叉开发模型如图2-1所示: 图3-1 交叉开发模型 3.2.1 上位机的软硬件配置 硬件: 本课题用到一台通用PC机和一台笔记本电脑,其硬件配置如下: PC机: CPU:P IV 2.0G RAM:256MB 串口:RS-232 并口:25针母头 笔记本电脑: CPU:PM 705 RAM:768MB 网卡:10/100MBps自适应网卡 软件: PC机的操作系统为Windows XP,装有DNW串口调试工具以及SJF2410 三星Flash烧写工具。前者用于串口调试,后者用于烧写Bootloader。 笔记本电脑的操作系统为 Ubuntu7.10,装有 GCC 等编译工具以及arm-linux-gcc交叉编译工具,并开启TFTP和 NFS服务。用于 Linux内核编 译和软件开发,并作为TFTP服务器和NFS主机。其中,Ubuntu7.10 是 Linux 的桌面发行版之一,是当今最为流行的桌面Linux 系统。使用 Linux 操作系统及其自带的工具,是目前最权威的嵌入式Linux系统开发方式,但是许多操作都是基于命令行的,所以需要扎实的Linux基础知识。 在 Ubuntu 中建立 arm用户,专门用于 ARM 开发。在 home 目录中建立下列几个子目录: Boot:用于存放bootloader相关程序。Kernel:用于存放 Linux内核源码。FS:用于存放根文件系统相关的程序。Program:用于存放用户程序。 3.2.2 硬件连接与调试 硬件连接方式: 图3-2 硬件连接图 (1)开发板串口UART0通过交叉串口线与PC主机的 COM1口相连。 (2)开发板的JTAG口通过20PIN排线与SUPER JTAG调试头相连,再通过25PIN并口线连接到主机的LPT1口。 (3)开发板的网卡接口通过以太网线连接到路由器的LAN1口。 (4)笔记本的网卡接口通过以太网线连接到路由器的LAN2口。 (5)路由器的 WAN口连接到INTERNET。串口调试: 在本课题嵌入式系统中的目标开发板,采用串口调试的方法,即把串口当作目标开发板的显示终端,无论是打印输出,还是管理配置输入,都使用串口,这就需要主机系统装有串口调试工具。PC机中安装有DNW串口调试工具,在使用DNW之前,应当对PC机的串口进行设置。方法如下: (1)XP系统中,右键单击“我的电脑”,选择“属性”。 (2)选择“硬件”——“设备管理器。 (3)选择“端口”——“串口(COM1)”,打开的对话框按图2-3设置。 图3-3 串口属性设置 运行 DNW 工具,选择菜单“Configuration”——“Options”,按图 2-4所示进行设置。 图 3-4 DNW 设置 每次使用DNW之前,应当设置DNW连接到串口。点击菜单中的 “Serial Port”——“Connect”,当DNW的标题栏出现[COM1,115200bps]的提示后,表明已经连接好,此时才可以使用DNW工具。 3.2.3 配置TFTP及NFS服务 TFTP 服务简介: TFTP(Trivial File Transfer Protocol)协议即简单文件传输协议,是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。TFTP承载在UDP上,提供不可靠的数据流传输服务,不提供存取授权与认证机制,使用超时重传方式来保证数据的到达。 TFTP 服务在 Linux 系统中有客户端和服务器两个软件包。配置 TFTP服务,必须都安装好。 TFTP 服务安装与配置: (1)Ubuntu中安装tftp工具只需在终端中键入命令: $ sudo apt-get install tftp tftpd 其中,前者是客户端,后者是服务器。 (2)Ubuntu是debian类的系统,默认是没有安装 inetd的,安装命令如下: $ sudo apt-get install netkit-inetd(3)在home目录里建立tftpboot 文件夹,命令如下: $ cd ~ $ sudo mkdir tftpboot $ sudo chmod 777 tftpboot 其中,参数 777 的意义是:根管理员、组和其他用户对 tftpboot 文件夹 的权限均为“可读、可写、可以执行”(4)修改/etc/inetd.conf,添加如下语句: tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /home/arm/tftpboot 目的是指定 tftp 服务的根目录为/home/arm/tftpboot,修改/etc/inetd.conf 文件后应当重启 inted进程,命令如下: $ sudo /etc/init.d/inetd reload(5)重启 inted 进程后,配置即可生效,在 tftpboot 中建立文件 test 后,用 下列命令可以进行测试: $ cd ~ $ tftp 127.0.0.1 Tftp> get test 若可下载test 文件,则证明TFTP服务配置正确。NFS 服务简介: NFS 就是 Network File System 的缩写,最早之前是由 Sun 这家公司所开发的。最大的功能就是可以透过网络,让不同的机器、不同的操作系统、可以彼此分享个别的档案(share files)。所以,可以简单的将它看做是一个文件服务器(file server)。通过 NFS 服务器可以让开发板将网络远端的 NFS 主机分享的目录,挂载到开发板当中,在开发板看起来,那个远端主机的目录就好像是自己的根目录一样,可以方便的进行开发调试。NFS 服务安装与配置: (1)Ubuntu上默认是没有安装NFS服务器的,首先要安装NFS服务程序: $ sudo apt-get install nfs-kernel-server 在安装nfs-kernel-server时,apt 会自动安装nfs-common和portmap。这样,宿主机就相当于NFS Server。(2)配置/etc/exports: NFS 挂载目录及权限由/etc/exports 文件定义。本课题要将 home 目录中 的/home/zp/share 目录让 192.168.0.*的 IP 共享, 则在该文件末尾添加下列语句: /home/arm/FS/myrootfs 192.168.0.2/10(rw,sync,no_root_squash)配置参数说明: rw:具有可擦写的权限。 sync:文件同步写入到内存和硬盘当中。 no_root_squash:若登陆共享目录的使用者是 root 的话,则他的权限将被限 制为匿名使用者,通常他的UID和GID都会变为nobody。(3)本地测试NFS: 输入以下命令可以将NFS根目录挂载到本地的/mnt 目录中: $ sudo mount 192.168.0.2:/home/arm/FS/myroot /mnt 此时/mnt 中的内容应当与NFS根目录中的内容一致。 3.2.4 安装交叉编译工具 交叉编译简介: 所谓交叉编译,简单的说,就是在一个平台上生成另一个平台上的可执行代码,比如在 PC平台上(X86 CPU)编译出能运行在以 ARM 为内核的CPU平台上的程序,一般选择GNU开发工具 gcc。GNU的开发工具都是免费的,遵循 GPL协议,任何人可以从网上获取。GNU 提供的编译工具包括汇编器as、c编译器gcc、c++编译器g++、连接器ld和二进制转换工具objcopy。出于兼容性和稳定性考虑,本课题选择目前比较稳定的版本 Cross-3.3.2 和Cross-3.4.1。 交叉编译器的安装及配置: (1)获取arm-linux交叉编译工具: 登陆arm-linux项目组的FTP服务器: ftp.arm.linux.org.uk/pub/armlinux/toolchain/ 下载cross-3.3.2.tar.bz2和cross-3.4.1.tar.bz2。 (2)通过下列命令可以安装arm-linux交叉编译工具: $ cp cross-3.4.1.tar.bz2 / $ cd / $ tar jxvf cross-3.4.1.tar.bz2 这样,交叉编译工具就被安装到了/usr/local/arm/3.4.1中。用同样的方法 可以安装cross-3.3.2版的交叉编译工具。 (3)设置环境变量: 修改home目录下的profile文件,加入如下代码,指明交叉编译工具的 目录。 # User specific environment and startup programs export TARGET=arm-linux export PRJROOT=/home/arm export PATH=$PATH:$HOME/bin:$PREFIX/bin:/usr/local/arm/3.4.1/bin:/sbin:/usr/ sbin:/usr/local/sbin 测试交叉编译器: 可以通过一个简单的程序测试安装好的交叉编译工具,看其能否正常工作。编写一个 hello.c源文件,通过以下命令进行编译,编译后生成名为Hello的可执行文件,通过 file 命令可以查看文件的类型。当显示以下信息是表明交叉编译工具正常安装了,通过编译生成了ARM体系可执行的文件。注意,通过该交叉编译器编译的可执行文件只能在 ARM 体系下执行,不能在基于X86的普通PC上执行。 $ arm-linux-gcc –o Hello hello.c $ file Hello Hello:ELF 32-bit LSB executable ,ARM, version 1(ARM), for GNU/Linux 2.4.3, dynamically linked(uses shared libs), not stripped 4 移植 Bootloader 4.1 Bootloader 概述 简单地说,Bootloader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。 通常,Bootloader是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的Bootloader几乎是不可能的,不同处理器构架都有不同的 Bootloader。Bootloader 不但依赖于 CPU 的体系结构,而且依赖于嵌入式板级设备的配置。对于不同的嵌入式板而言,即使它们使用同一种处理器,要想让运行在一块板子上的Bootloader运行在另一块板子上,一般也要修改其源代码。 目前常用的Bootloader程序有以下几种: U-boot、VIVI、Blob和RedBoot。其中,U-boot 功能丰富,且对于ARM体系支持良好,事实上,它已成为ARM平台上标准Bootloader。因此,本课题选用U-boot 作为移植对象。U-boot 简介 U-boot 是德国 DENX 小组的开发用于多种嵌入式 CPU 的 Bootloader 程序,U-boot 不仅仅支持嵌入式Linux系统的引导,还支NetBSD,VxWorks,QNX,ARTOS,LynxOS 等嵌入式操作系统。U-boot 除了支持 ARM 系列的处理器外,还能支持 MIPS、x86、PowerPC、NIOS、XScale 等诸多常用系列的处理器。 4.2.1 U-boot 的获取 U-boot 的源码可以从sourceforge网站下载,网址为: http://sourceforge.net/project/u-boot。 下载的文件为u-boot-1.2.0.tar.bz2,用以下命令将其解压。 $ tar jcvf u-boot-1.2.0.tar.bz2 /home/arm/boot/ 4.2.2 U-boot 目录结构 解压后,在 U-boot 顶层目录下有 18 个子目录,分别存放和管理不同的源码。这些目录中所要存放的文件有其规则,可以分为3类,如表3-1所示: 第一类目录与处理器体系结构或开发板硬件直接相关。第二类目录是一些通用的函数或者驱动程序。第三类目录是U-boot 的应用程序、工具或者文档。 表4-1 U-boot顶层目录下部分目录的存放规则 U-boot 的启动过程及工作原理 4.3.1 启动模式介绍 Bootloader 都包含两种不同的操作模式:“启动加载”模式和“下载”模式,这种区别仅对于开发人员才有意义。但从最终用户的角度看,Boot Loader 的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载工作模式的区别。 启动加载(Bootloading)模式:这种模式也称为“自主”(Autonomous)模式。也即 Bootloader 从目标机上的某个固态存储设备上将操作系统加载 到 RAM中运行,整个过程并没有用户的介入。这种模式是 Boot Loader 的 正常工作模式,因此在嵌入式产品发布的时侯,Bootloader 显然必须工作在这种模式下。 下载(Downloading)模式:在这种模式下,目标机上的 Boot Loader 将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被 Bootloader保存到目标机的 RAM 中,然后再被 Bootloader 写到目标机上的 FLASH 类固态存储设备中。Bootloader 的这种模式通常在第一次安装内核与根文件系统时被使用; 此外,以后的系统更新也会使Bootloader的这种工作模式。工作于这种模式下的 Bootloader 通常都会向它的终端用户提供一个简单的命令行接口。 U-boot 这样功能强大的Bootloader 同时支持这两种工作模式,而且允许用户在这两种工作模式之间进行切换。 大多数Bootloader都分为阶段1(stage1)和阶段2(stage2)两大部分,U-boot也不例外。依赖于CPU体系结构的代码(如CPU初始化代码等)通常都放在阶段1中且通常用汇编语言实现,而阶段 2 则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。 图 4-1 U-boot启动代码流程图 4.3.2 启动阶段1分析 如果 S3C2410 被配置成从 NAND 闪存启动,上电后,S3C2410 的 NAND 闪存控制器会自动把 NAND 闪存中的前 4K 数据搬移到内部 RAM中,并把 0x00000000 设置为内部 RAM 的起始地址,CPU 从内部 RAM 的0x00000000 位置开始启动。因此要把最核心的启动程序放在 NAND 闪存的前4K中。由于NAND闪存控制器从NAND闪存中搬移到内部RAM的代码是有限的,所以,在启动代码的前 4K里,必须完成 S3C2410 的核心配置,并把启动代码的剩余部分搬到 RAM 中运行。这前4K完成的主要工作就是 U-boot 启动的第一个阶段(stage1)。 U-boot 的stage1代码通常放在start.s文件中,它用汇编语言写成。此阶段要完成的主要工作如下: (1)设置异常向量,当发生异常时,执行 cpu/arm920t/interrupts.c 中定义的中断处理函数。 (2)设置CPU的模式为SVC(管理模式,操作系统使用的保护模式)(3)关闭看门狗。(4)禁掉所有中断。 (5)设置 cpu 频率,默认频率比为 FCLK:HCLK:PCLK = 1:2:4,默认FCLK的值为120 Mhz,该值为S3C2410手册的推荐值。(6)调用cpu初始化函数cpu_init_crit。其中一个功能是设置CP15寄存 器,失效指令(I)Cache和数据(D)Cache后,禁止MMU与 Cache。(7)重定向,将 NAND Flash代码复制到 RAM,其中有以下两个个步 骤: (a)通过copy_myself子程序,把数据从Nand Flash中拷贝到RAM。 (b)配置栈空间,配置代码段的开始地址、动态内存区长度、全局数据 大小以及分配IRQ 和FRQ的栈空间。 (8)BSS(Block Started by Symbol)段清零。(9)进入C代码: ldr pc, _start_armboot _start_armboot:.word start_armboot 其中 start_armboot 是 U-boot 运行的第一个 C 程序,在 lib_arm/board.c 文件中定义。随后进入第二阶段。 4.3.3 启动阶段2分析 lib_arm/board.c 中的 start armboot 是 C 语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个 U-boot(armboot)的主函数,该函数主要完成如下操作:(1)定义初始化函数表。 (2)NAND Flash初始化,利用 nand_init()函数实现。(3)环境变量初始化,利用env_relocate()函数实现。(4)外围设备初始化,利用 devices_init()函数实现。(5)使能中断,利用enable_interrupts()函数实现。(6)初始化网络设备。 (7)进入U-boot 的命令循环,接受用户输入的命令,执行相应的工作。 U-boot的移植过程 移植U-boot 的主要工作就是添加开发板硬件相关的文件、配置选项,然后进行编译。 4.4.1 准备工作 (1)建立开发板编译项,在顶层Makefile中加入如下两行: LJD2410_config : unconfig @$(MKCONFIG)$(@:_config=)arm arm920t LJD2410 NULL s3c24x0 各项意义如下: arm:CPU 的架构(ARCH)arm920t:CPU 的类型(CPU),其对应于 cpu/arm920t 子目录。LJD2410:开发板的型号(BOARD),对应于 board/crane2410 目录。NULL:开发者/或经销商(vender)。s3c24x0:片上系统(SOC)。 (2)在 board 子目录中建立 LJD2410开发板目录: $ cp rf board/smdk2410 board/LJD2410 $ cd board/LJD2410 $ mv smdk2410.c LJD2410.c(3)在 include/configs/中建立配置头文件: $ cp include/configs/smdk2410.h include/configs/LJD2410.h(4)测试编译能否成功: $ make distclean $ make LJD2410_config $ make CROSS_COMPILE=arm-linux-如果编译成功,证明已经建立好了LJD2410的编译项,但是还要进行进一步的修改,因为现在的代码是完全拷贝 smdk2410 开发板的,还不能工作在LJD2410板上。接下来要按照 LJD2410板的硬件配置来进一步移植。(5)调整SDRAM的刷新率,修改 lowlevel_init.S: #define REFCNT 1268 在smdk2410.c中调整 HCLK为 100MHz: /*Fout = 200MHz */ #define M_MDIV 0x5C #define M_PDIV 0x4 #define M_SDIV 0x0 4.4.2 添加支持 NAND Flash 启动功能 由于U-boot 不支持从NAND Flash启动,所以将程序复制到RAM里面去需要新加代码实现,一般通过 copy_myself 函数实现。这可以参考 VIVI的copy_muself代码将其添加到Start.S中,详见附录 A-1。 在Start.S中调用了nand_reak_ll函数,该函数用于NAND Flash读操作,在U-boot 中没有定义,需要新加代码实现,该函数的实现可以参考VIVI源代码。将VIVI/s3c2410/nand_read.c 复制到LJD2410目录内即可。 由于使用了新的 Flash 读函数,在编译时需要重新链接,修改 LJD2410目录中的Makefile文件,将原先的OBJS := myboard.o flash.o 改为:OBJS := myboard.o nand_read.o。 S3c2410处理器带有NAND Flash控制器,但是U-boot 没有定义其寄存器地址,修改 include/s3c2410.h文件,加入如下代码: #define oNFCONF 0x00 #define oNFCMD 0x04 #define oNFADDR 0x08 #define oNFDATA 0x0C #define oNFSTAT 0x10 #define oNFECC 0x14 4.4.3 添加 NAND Flash 读写功能 U-boot 运行至第二阶段进入 start_armboot()函数。其中 nand_init()函数是对 NAND Flash 的最初初始化函数。其调用与CFG_NAND_LEGACY 宏有关,如果没定义 CFG_NAND_LEGACY 这个宏,就按照 start_armboot()调用 drivers/nand/nand.c 中的 nand_init 函数(该函数在 1.2.0 已经被实现)默认规定,但还有个 board_nand_init()函数没实现,需自己添加。如果定义CFG_NAND_LEGACY,就不使用默认的nand_init,而调用自己写的nand_init函数了,本课题选择第二种方式。 在/drivers/nand_legacy/nand_legacy.c 中添加 NAND Flash 初始化函数nand_init,详见附录 A-2。 可以看到 nand_init()调用 NF_Init()函数,使能 NAND Flash 控制器和 NAND Flash;调用 NF_Reset()函数置位,NF_WaitRB()查询 NAND Flash 的状态,最后再调用 nand_probe((ulong)nand)函数探测 NAND Flash。 在 include/configs/smdk2410.h 文件的后半部原先有 Flash 的参数,删除它,并加入NAND Flash的参数,并且开启一些命令宏。 4.4.4 修改 U-boot环境变量保存方式 由于本课题使用NAND Flash作为外存储器,所以U-boot 的参数存储函数应当进行适当的修改。 在/common/env_common.c里添加default_env函数,此函数的作用是对环境变量保存方式的简单初始化。这个文件中还定义了U-boot 保存环境变量的底层函数。其中/* Environment not changable */行下面的部分应当用 default_env 函数代替。这样,就可以在 U-boot 命令行中实现对环境变量的设置与保存。文件 /common/env_nand.c 中 包 含 了 Flash 擦 写 函 数,结合 CFG_NAND_LEGACY这个宏,添加代码实现 NAND Flash的擦写功能。初 始化环境仍用 default_env函数替换。 4.4.5 加入 NAND Flash 闪存型号支持 在/include/linux/mtd/ nand_ids.h 中 对 nand_flash_dev nand_flash_ids结构体的赋值进行修改,加入下列代码: {“Samsung K9F1208U0B”, NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0}, 这样,U-boot 就可以正确识别此款NAND Flash芯片。 4.5 U-boot 的烧写及测试 若开发板中没有任何程序,则不能启动,需要先将 U-boot 烧写到 Flash中。常用的烧写方法有如下几种:(1)将Flash取下,用编程器烧写。(2)通过串口线烧写。(3)通过JTAG调试接口烧写。 本课题采用第三种方法。通过JTAG接口烧写的优点是操作简单,但是烧写速度较慢,总体来说是一种非常经济实用的方法。具体操作如下:(1)连接好开发板和PC主机,主机安装并口设备驱动程序。 (2)将 u-boot.bin 拷贝至 sjf2410 目录下,用以下命令运行 sjf2410: sjf2410 /f:u-boot.bin(3)sjf2410程序启动后,会有三个选项,依次为: (a)选择Flash芯片型号,(b)选择程序类型,(c)选择烧写起始地址。 本课题全部选择“0”即可。 (4)烧写完毕后选择“2”退出sjf2410。 烧写完成后,断开JTAG线,PC机运行DNW串口调试软件。重启开发板后,DNW中会输出以下信息,表明U-boot可以正常启动: 其中,“LJD2410 >”即系统提示符,在此可以输入 U-boot 的命令并执行。U-boot 提供了几十个常用的命令,通过这些命令,可以对开发板进行调试,可以引导Linux内核,还可以擦写 Flash 完成系统部署等功能。 输入“help”命令,可以看到U-boot 当前的所有命令列表,如表3-2所示,每一条命令后面是简单的说明。 表4-2 U-boot中几个常用命令及其说明 4.6 设置U-boot环境变量 U-boot的环境变量存储在NAND Flash中U-boot程序映像后面的128Kb字节中,这部分被称为“变量区”。 本课题中,设置U-boot 环境变量共有两种方法:(1)在板级头文件LJD2410.h中定义有相关的环境变量宏。 这类的宏名称中以“CONFIG_”开头,区别于以“CFG_”开头的内部变量宏。以开发板的IP地址为例,LJD2410.h中有如下代码: #define CONFIG_IPADDR 192.168.0.10 这种方法定义简便,但是每次更改环境变量必须重新编译、烧写U-boot程序,操作复杂,不方便调试。(2)使用命令设置环境变量。 这种方法得益于先前所做的移植工作,优点是操作简便,可以在线设置,重启开发板即可生效。还是以设置开发板 IP 地址为例,U-boot 提示符下输入以下命令: LJD2410 > setenv ipaddr 192.168.0.10 LJD2410 > saveenv 系统显示: Saving Environment to NAND...Erasing Nand...Writing to Nand...done 表明新设置的环境变量已保存至Flash中的变量区。5 Linux 内核的移植 Linux 内核的结构 在对Linux内核移植之前,首先要明确内核源码的基本组织情况,只有了解了各目录级代码的功能才能准确找到需要修改和改进的地方。 Linux 内核主要由 5 个子系统组成:进程调度、内存管理、虚拟文件系 统、网络接口、进程间通信。 Linux内核源码中几个主要的目录说明如下: (1)/arch包含了所有硬件结构特定的内核代码。 Linux 系统能支持如此多平台的部分原因是因为内核把原程序代码清晰的划分为体系结构无关部分和体系结构相关部分。对于任何平台,都必须包含以下几个目录: (a)boot:包括启动内核所使用的部分或全部平台特有代码。 (b)kernel:存放支持体系结构特有的(如信号处理和SMP)特征的实现。 (c) lib:存放高速体系结构特有的(如strlen和 memcpy)通用函数的实现。 (d)mm:存放体系结构特有的内存管理程序的实现。 (e)math-emu:模拟 FPU 的代码。对于 ARM 处理器来说,此目录用mach-xxx代替。 (2)/drivers包含了内核中所有的设备驱动程序。 (3)/fs包含了所有的文件系统的代码。 (4)/include包含了建立内核代码时所需的大部分库文件。 该目录也包含了不同平台需要的库文件。比如,asm-arm是 arm平台需要的库文件。 (5)/init 包含了内核的初始化代码,内核从此处工作。这是研究核心如何工作的好起点。 (6)/ipc包含了进程间通信代码。 (7)/kernel包含了主内核代码。 (8)/mm包含了所有内存管理代码。 (9)/net 包含了和网络相关的代码。 (10)/documents包含了内核源码各个部分的说明文件。 通常,在每个目录下,都有一个 Kconfig 文件和一个Makefile文件,这两个文件都是编译时使用的辅助文件,仔细阅读这两个文件对弄清各个文件之间的联系和依托关系很有帮助;而且在有的目录下还有 Readme 文件,它是对该目录下的文件的一些说明,同样有利于我们对内核源码的理解。 显然,移植工作的重点就是移植arch目录下的文件。Linux 启动过程简析 Linux 内核启动就是引导内核映像启动的过程。典型的内核映像是zImage,包含自引导程序和压缩的vmlinux两部分。 启动过程从内核映像入口开始执行,解压 vmlinux并转到虚拟地址空间;再调用统一的内核启动函数 start_kernel(),完成一系列基本初始化;随后启动一个叫做 init 的内核线程,完成挂载文件系统、初始化设备驱动和启动用户空间 init 进程等工作。 Linux内核的移植过程 5.3.1 选择参考板 内核的移植工作主要是修改跟硬件平台相关的代码,一般不涉及 Linux内核通用程序。移植的难度也取决于两种硬件平台的差异。Linux 对于特定硬件平台的软件叫做BSP(Board Support Package).Linux 内核已经支持了各种体系的多种开发板,我们很容易从中找到与本课题类似的目标板,参考该目标板并做一定的修改,即可完成移植工作。选择参考板的原则如下: (1)参考板与开发板具有相同的处理器,至少类似的处理器; (2)参考板与开发板具有相同的外围接口电路,至少基本接口相同; (3)Linux内核已经支持参考板,至少有非官方的补丁或者BSP; (4)参考板Linux设备驱动工作正常,至少已经驱动基本接口。 根据以上原则,本课题选择SMDK2410作为参考板。修改顶层Makefile文件,指定体系结构和编译器地址: ARCH := arm CROSS_COMPILE := /usr/local/arm/3.4.1/bin/arm-linux- 5.3.2 修改 NAND Flash 分区信息 本课题中,NAND Flash应按照功能分为 4个分区,如图4-1所示: 图5-1 NAND Flash分区示意图 Linux 内核对于 Flash分区由 arch/arm/plat-s3c24xx/common-smdk.c 文件中的 mtd_partition smdk_default_nand_part 结构体定义,默认已经分为了8个区。按照图4-1的分区信息,修改该结构体为: static struct mtd_partition smdk_default_nand_part[] = { [0] = { .name = “U-boot”,.size = 0x00100000,.offset = 0x0,},[1] = { .name = “Kernel”,.offset = 0x00100000,.size = 0x00300000,},[2] = { .name = “RootFS”,.offset = 0x00400000,.size = 0x02800000,},[3] = { .name = “User”,.offset = 0x02d00000,.size = 0x00f00000,},同时还应根据CPU手册修改NAND Flash的读写时序: static struct s3c2410_platform_nand smdk_nand_info = { .tacls = 0,.twrph0 = 30,.twrph1 = 0,};5.3.3 关闭 ECC 校验 本设计中,内核都是通过 U-boot 写到 Nand Flash 的,U-boot 通过的软件ECC算法产生ECC校验码,这与内核校验的ECC码不一样,而内核中的 ECC 码是由 S3C2410 中 Nand Flash 控制器产生的。所以,我们在这里选择禁止内核 ECC 校验.,具体操作如下: 文件drivers/mtd/nand/s3c2410.c中,找到s3c2410_nand_init_chip()函数,将最后一行的 chip-->eccmode = NAND_ECC_SOFT 改为: chip-->eccmode = NAND_ECC_NONE 5.4 CS8900a网卡的移植过程 本课题中使用的LJD2410开发板带有 CS8900A网卡芯片,并提供RJ-45网络接口。Linux内核中并没有为 ARM体系配置CS8900A的网卡驱动,需要自己添加。CS8900A的驱动文件有两个:CS8900A.h 和CS8900A.c,这两个文件可以由网络获得,将其拷贝至 drivers/net/arm 文件夹下,但这样并不能使驱动程序正常工作,还应对内核源文件做些修改。 5.4.1 修改硬件地址映射 (1)在/arch/arm/mach-s2410文件夹里建立文件smdk2410.h,添加如下代码: #define pSMDK2410_ETH_IO __phys_to_pfn(0x19000000) #define vSMDK2410_ETH_IO 0xE0000000 #define SMDK2410_EHT_IRQ IRQ_EINT9 这三个宏分别定义了网卡的物理地址、虚拟地址和占用的中断号。 (2)修改/arch/arm/mach-s2410/mach-smdk2410.c,添加如下代码: #include (3)在 map_desc smdk2410_iodesc[]结构题中添加CS8900A对于的 io 空间映射: static struct map_desc smdk2410_iodesc[] __initdata = { { vSMDK2410_ETH_IO , pSMDK2410_ETH_IO, SZ_, MT_DEVICE }, }; 5.4.2 添加 CS8900A 内核编译项 Kconfig 文件是 Linux2.6 内核引入的配置文件,是内核配置选项的源文件。只有在这个文件里加入相应代码,才能在编译选项中出现菜单项。 在/drivers/net/arm/Kconfig中增加CS8900A的编译项代码: config ARM_CS8900 tristate “CS8900 support” depends on NET_ETHERNET && ARM && ARCH_SMDK2410 help … 最后应在/drivers/net/arm/Makefile 中添加: obj-$(CONFIG_ARM_CS8900) += cs8900.o 以上工作完成后,新移植的CS8900A驱动就可以编译进内核里了。 5.5 Linux 内核的剪裁配置 配置内核选项是整个移植过程中很重要的一步,本设计使用SMDK2410作为参考开发板,所以可以参考内核中 SMDK2410 开发板的配置文件,通过以下命令将其复制到内核根文件夹下: $ cp arch/arm/config/smdk2410_defconfig.config 在此基础上,根据本课题的实际需求进行配置增减。 5.5.1 使用配置菜单 配置内核可以选择不同的配置界面,图形界面或者光标界面。由于光标菜单运行时不依赖于X11图形软件环境,可以运行在字符终端上,所以光标菜单界面比较通用。图4-2所示就是执行 make menuconfig出现的配置菜单。 在各级子菜单中,选择相应的配置时,有 3种选择,它们代表的含义分别如下: Y—将该功能编译进内核。 N—不将该功能编译进内核。 M—将该功能编译成可以在需要时动态插入到内核中的模块。 图5-2 内核配置主菜单 内核配置原则是:将与内核其他部分关系较远且不经常且不经常使用的部分功能代码编译成可加载模块,有利于减少内核长度,减小内核消耗的内存,简化该功能相应的环境改变时对内核的影响;不需要的功能就不选;与内核关系紧密而且经常使用的部分功能代码直接编译到内核中。 5.5.2 基本配置选项 Linux内核的各个版本配置餐单各不相同,下面以本课题使用的2.6.24.4版为例,结合本课题的实际需求,简介下内核的基本配置选项。 (1)General setup:包含通用的一些配置选项,保持默认即可。 (2)Enable loadable module supple:包含支持动态模块的配置选项,保持默认。 (3)System Type:包含系统平台列表及其相关的配置,去掉SMDK2410以外所有开发板的支持、开启s3c2410 DMA支持。 (4)Bus support:包含各种总线配置选项,全部去掉。 (5)Kernel Features:包含内核特性相关选项,保持默认。 (6)Boot options:包含内核启动相关选项,其中内核启动参数设置为: “noinitrd console=ttySAC0,115200 root=/dev/nfs init=linuxrc nfsroot=192.168.0.2:/home/arm/FS/myrootfs mem=64M ip=192.168.0.10:192.168.0.2:192.168.0.1:255.255.255.0:LJD2410:eth0:off”,支持NFS文件系统。 (7)Floating point emulation:包含浮点数运算仿真功能,需要开启“NWFPE”选项。 (8)Userapace binary formats:包含支持的应用程序格式,仅保留“ELF”格式支持,去掉其它。 (9)Power management options:包含电源管理功能,保持默认。 (10)Networking:包含网络功能:需要开启基本功能选项。 (11)Device Drivers:包含设备驱动选项,下一小节将详细介绍。 (12)File systems:包含各种文件系统的支持选项,去掉“EX2”等选项,仅保留 ROM 文件系统支持,在“Miscellaneous filesystems”子菜单中近保留“cramfs”文件系统支持,并且开启NFS文件系统支持,去掉其它选项。 (13)Kernel hacking:包含各种内核调试选项,保持默认。 (14)Security options:包含安全性有关选项,保持默认。 (15)Cryptographic API:包含加密算法,保持默认。 (16)Library routines:包含几种压缩和校验函数,保持默认。5.5.3 驱动程序配置选项 几乎所有Linux的设备驱动都在“Device Drivers”菜单下,它对设备驱动程序加以归类,放在子菜单下。本课题对于设备驱动的裁剪较多,具体如下: (1)MTD support:MTD设备驱动,应添选NAND Flash驱动支持。 (2)Network debice support:网络设备支持,在子菜单“Ethernet(10 or 100Mbits)”中可以看到CS8900A网卡的配置项,这正是4.4节工作的结果。 (3)Real Time Clock:时钟驱动选项,应选上“Samsung S3C series SoC RTC”,这样系统时钟才能正常运行。 (4)由于嵌入式导航计算机只使用串口作为输入输出接口,所以应该剪裁掉那些无用的驱动,包括:并口、ATA及SATA驱动、RAID驱动、ISDN支持、输入设备驱动、多媒体设备支持、USB 支持以及MMC/SD卡支持。(5)其它驱动支持保持默认即可。 5.5.4 保存配置文件 内核配置主菜单中选择“Save an Alternate Configuration File”即可将目前的配置状态保存成文件。程序默认保存为“.config”,此文件位于内核根目录内,可以直接修改。 5.5.5 编译 Linux 内核 正式编译Linux内核之前,应当清理一下内核树,命令如下: $ make mrproper 此命令会清除掉.config 文件,所以应当在配置内核之前做。 Linux 2.6 版本的编译已经简化,使用一个 make 命令就可以完成诸如建 立文件依赖、生成zImage、编译模块、安装模块等一系列功能。内核编译完 成后,将在/arch/arm/boot 目录中生成 image 和 zIamge 两个内核映像文件,其中 image 为正常大小的映像文件,而 zImage 为压缩后的映像文件。此时 编译好的可加载模块也被安装到预定位置,默认为/lib/modules。5.6 内核的下载及启动 5.6.1 将引导信息加入内核映像 U-boot 引导内核时需要检查一个 64byte 的头信息,其中包含了入口地址、映像类型等基本信息。这个引导头可以用 U-boot 附带的 mkimage 工具生成,命令如下: $ mkimage-n 'linux-2.6.24'-A arm-O linux-T kernel-C none-a 0x30008000-e 0x30008040-d zImage zImage.img 各个参数的含义: -n:设置映像名 -A:设置体系信息 -O:设置操作系统信息 -T:设置映像类型 -c:压缩类型 -a:读入地址 -e:入口地址 -d:源映像文件 该命令生成的zImage.img文件就可以下载到开发板运行了。 5.6.2 内核映像的下载及运行 将上一小节中生成的zImage.img文件拷贝到主机tftpboot 文件夹内。启动开发板,进入U-boot 提示符。使用tftp命令将内核映像下载到开发板内存中: LJD2410> tftp 0x30008000 zImage.img TFTP from server 192.168.0.2;our IP is 192.168.0.10 Filename ‘zImage.img’ Load address : 0x30008000 Loading: #### Done 其中 0x30008000 为指定的下载到内存的地址,zImge.img 就是带有引导头的内核映像。当内核下载完成后,可以通过bootm命令启动内核: LJD2410> bootm 0x30008000 6 建立根文件系统 6.1 根文件系统概述 6.1.1 根文件系统简介 对于嵌入式操作系统而言,仅包含内核是不够的,还必须有文件系统的支持。跟文件系统(root filesystem)是 Linux系统的核心部分,包含系统使用的软件和库,以及无偶有用来为用户提供支持架构和用户使用的应用软件,并作为存储数据读写结果的区域。在Linux系统启动时,首先完成内核安装及环境初始化,最后会寻找一个文件系统作为根文件系统被加载。Linux系统中使用“/”来唯一表示根文件系统的安装路径。嵌入式系统中通常可以选择的根文件系统有:Romfs, CRAMFS, RAMFS,JFFS2, EXT2等,甚至还可以使用NFS(网络文件系统)作为根文件系统。 6.1.2 NFS 文件系统与Cramfs文件系统 NFS(Network File System)是由SUN公司发展,并于1984年推出的一种文件系统。它可以让开发者通过网络连接,使开发板可以直接挂载主机的某一个指定文件夹作为根文件系统。在嵌入式开发过程中,通常使用这种文件系统搭建交叉编译环境。 cramfs(Compressed ROM File System)是Linux创始人Linus Torvalds开发的一个适用于嵌入式系统的文件系统。cramfs是一个只读文件系统,采用了zlib压缩,压缩比一般可以达到1:2,但仍可以做到高效的随机读取。Linux系统中,通常把不需要经常修改的目录压缩存放,并在系统引导的时候再将压缩文件解开。因为 cramfs 不会影响系统读取文件的速度,而且是一个高度压缩的文件系统,因此本课题最终选用cramfs作为根文件系统部署到开发板。 6.2 建立Linux根文件系统目录 嵌入式Linux根文件系统必须包含一些必须的目录,比如设备目录/dev、命令目录/bin、库目录/lib等等。 本课题构建根文件系统的工作目录是 myrootfs,通过下列命令可以在myrootfs中创建所需的子目录: $ mkdir bin dev etc lib proc sbin sys usr $ mkdir usr/bin usr/lib usr/sbin lib/modules $ mkdir mnt tmp var $ chmod 1777 tmp $ mkdir var/lib var/lock var/log var/run var/tmp $ chmod 1777 var/tmp $ mkdir home root boot 这样,一个基本的根文件系统就建立起来了,但是各个目录都是空的,缺少各种程序和命令工具,需要进一步完善。心得体会 本课题的目标是为基于ARM9处理器的导航计算机移植Linux操作系统。研究过程中,使用了 LJD2410 型开发板,此开发板的处理器是基于 ARM920T的 Samsung S3c2410,能够满足嵌入式导航计算机的硬件需求。本课题所做的工作简要总结如下: 首先,本文对嵌入式系统、嵌入式Linux操作系统和ARM体系处理器做了简单介绍,并且分析了嵌入式导航计算机的操作系统需求。 其次,介绍了交叉开发环境的建立。本课题两台主机连接开发板的方法,主机分别安装不同的操作系统,在开发过程中完成不同的工作。通过 TFTP和NFS等网络服务,实现高效连接,有利于提高开发效率。这部分是整个课题的基础,之后的所有工作都是在这个基础上完成的。 第三,本文重点介绍了 Linux 系统的移植过程。Linux 系统移植包括三个方面:启动加载程序(Bootloader)的移植,Linux 内核的移植和根文件系统的建立。本课题选用功能强大的 U-boot 作为启动加载程序,通过对其源代码进行修改,使其可以正常运行于开发板,并且实现下载、烧写等功能。内核则采用了2008年 4月发布的2.6.24.4版本,移植了网卡驱动,并针对课题需求,进行了修改和裁剪,使得内核加载更快,运行更稳定。根文件系统选用了Cramfs文件系统,这种文件系统采用压缩格式,存储空间需求小,但是不影响读取速度,非常适合与嵌入式Linux系统。这三个方面的工作有前后继承关系,但是又有一定独立性,移植过程中应多调试,多实验。 最后,简单介绍了系统部署的方法。将Linux 内核和根文件系统部署到开发板后,开发板就可以脱离交叉开发环境而独立运行,最终达到设计需求。 本课题充分利用前人积累的经验,结合最新的软件版本进行移植工作。在移植过程中遇到了许多困难和问题,主要靠查阅文献和自己的试探性试验来研究问题,通过多次的实践,最终得到明确的解决方法。虽然移植后的Linux系统可以正常运行在开发板上,能满足设计需求。但由于时间仓促,许多问题没有深入研究,难免会出现一定的疏漏和瑕疵,需要我在今后的学习中不断努力,加以改进。第四篇:嵌入式系统的主要应用
第五篇:基于嵌入式系统的图形界面应用设计范文