
学会配置NFS服务
学会搭建Linux的根文件系统
掌握Bootloader的原理
5.1 嵌入式开发环境的搭建
5.1.1 嵌入式交叉编译环境的搭建
交叉编译的概念在第4章中已经详细讲述过,搭建交叉编译环境是嵌入式开发的第一步,也是必备一步。搭建交叉编译环境的方法很多,不同的体系结构、不同的操作内容甚至是不同版本的内核,都会用到不同的交叉编译器,而且,有些交叉编译器经常会有部分的BUG,这都会导致最后的代码无法正常地运行。因此,选择合适的交叉编译器对于嵌入式开发是非常重要的。
交叉编译器完整的安装一般涉及到多个软件的安装(读者可以从ftp://gcc.gnu.org/pub/下载),包括binutils、gcc、glibc等软件。其中,binutils主要用于生成一些辅助工具,如objdump、as、ld等;gcc是用来生成交叉编译器,主要生成arm-linux-gcc交叉编译工具(应该说,生成此工具后已经搭建起了交叉编译环境,可以编译Linux内核了,但由于没有提供标准用户函数库,用户程序还无法编译);glibc主要是提供用户程序所使用的一些基本的函数库。这样,交叉编译环境就完全搭建起来了。
上面所述的搭建交叉编译环境比较复杂,很多步骤都涉及到对硬件平台的选择。因此,现在提供开发板的公司一般会在附赠的光盘中提供该公司测试通过的交叉编译器,而且很多公司把以上安装步骤全部写入脚本文件或者以发行包的形式提供,这样就大大方便了用户的使用。如优龙的开发光盘里就随带了2.95.3和3.3.2两个版本的交叉编译器,其中前一个版本是用于编译Linux2.4内核的,而后一个版本是用于编译Linux2.6版本内核的。由于这是厂商测试通过的编译器,因此可靠性会比较高,而且与开发板能够很好地吻合。所以推荐初学者直接使用厂商提供的编译器。当然,由于时间滞后的原因,这个编译器往往不是最新版本的,若需要更新时希望读者另外查找相关资料学习。本书就以优龙自带的cross-3.3.2为例进行讲解(具体的名称不同厂商可能会有区别)。
安装交叉编译器的具体步骤在第2章的实验二中已经进行了详细地讲解了,在此仅回忆关键步骤,对于细节请读者参见第2章的实验二。
在/usr/local/arm下解压cross-3.3.2.bar.bz2。
[root@localhost arm]# tar –jxvf cross-3.3.2.bar.bz2
[root@localhost arm]# ls
3.3.2 cross-3.3.2.tar.bz2
[root@localhost arm]# cd ./3.3.2
[root@localhost arm]# ls
arm-linux bin etc include info lib libexec man sbin share VERSIONS [root@localhost bin]# which arm-linux*
/usr/local/arm/3.3.2/bin/arm-linux-addr2line
/usr/local/arm/3.3.2/bin/arm-linux-ar
/usr/local/arm/3.3.2/bin/arm-linux-as
可以看到,这个优龙公司提供的交叉编译工具确实集成了binutils、gcc、glibc这几个软件,而每个软件也都有比较复杂的配置信息,读者可以查看V ersion文件了解相关信息。
5.1.2 超级终端和Minicom配置及使用
前文已知,嵌入式系统开发的程序运行环境是在硬件开发板上的,那么如何把开发板上的信息显示给开发人员呢?最常用的就是通过串口线输出到宿主机的显示器上,这样,开发人员就可以看到系统的运行情况了。在Windows和Linux中都有不少串口通信软件,可以很方便地对串口进行配置,其中最主要的配置参数就是波特率、数据位、停止位、奇偶校验位和数据流控制位等,但是它们一定要根据实际情况进行相应配置。下面介绍Windows中典型的串口通信软件“超级终端”和在Linux下的“Minicom”。
1.超级终端
首先,打开Windows下的“开始”→“附件”→“通讯”→“超级终端”,这时会出现如图5.1所示的新建超级终端界面,在“名称”处可随意输入该连接的名称。
接下来,将“连接时使用”的方式改为“COM1”,即通过串口1,如图5.2所示。
接下来就到了最关键的一步——设置串口连接参数。要注意,每块开发板的连接参数有可能会有差异,其中的具体数据在开发商提供的用户手册中会有说明。如优龙的这款FS2410采用的是波特率:115200,数据为8位,无奇偶校验位,停止位1,无硬件流,其对应配置如图5.3所示。
这样,就基本完成了配置,最后一步“单击”确定就可以了。这时,读者可以把开发板的串口线和PC机相连,若配置正确,在开发板上电后在超级终端的窗口里应能显示类似如图5.4的串口信息。
图5.1 新建超级终端界面
《嵌入式Linux 应用程序开发详解》——第5章、嵌入式Linux 开发环境的搭建
图5.2 选择连接时使用方式 图5.3 配置串口相关参数
注意 要分清开发板上的串口1,串口2,如在优龙的开发板上标有“UART1”、“UA TR2”,否则串口
无法打印出信息。
2.Minicom
Minicom 是Linux 下串口通信的软件,它的使用完全依靠键盘的操作,虽然没有“超级终端”那么易用,但是使用习惯之后读者将会体会到它的高效与便利。下面主要讲解如何对Minicom 进行串口参数的配置。
图5.4 串口相关信息
首先在命令行中键入“minicom”,这就启动了minicom软件。Minicom在启动时默认会进行初始化配置,如图5.5所示。
图5.5 minicom启动
注意在Minicom的使用中,经常会遇到三个键的操作,如“CTRL-A Z”,这表示先同时按下CTRL 和“A”(大写),然后松开此二键再按下“Z”。
正如图5.5中的提示,接下来可键入CTRL+A Z,来查看minicom的帮助,如图5.6所示。
按照帮助所示,可键入“O”(代表Configure Minicom)来配置minicom的串口参数,当然也可以直接键入“CTRL-A O”来进行配置。如图5.7所示。
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
图5.6 minicom帮助
图5.7 minicom配置界面在这个配置框中选择“Serial port setup”子项,进入如图5.8所示配置界面。
上面列出的配置是minicom启动是的默认配置,用户可以通过键入每一项前的大写字母,分别对每一项进行更改。图5.9所示为在“Change which setting中”键入了“A”,此时光标转移到第A项的对应处。
在minicom中“ttyS0”对应“COM1”,“ttyS1”对应“COM2”。
图5.8 minicom串口属性配置界面《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
图5.9 minicom串口号配置
接下来,要对波特率、数据位和停止位进行配置,键入“E”,进入如图5.10所示的配置界面。
在该配置界面中,可以键入相应波特率、停止位等对应的字母,即可实现配置,配置完成后按回车键就退出了该配置界面,在上层界面中显示如图5.11所示配置信息,要注意与图5.8行对比,确定相应参数是否已被重新配置。
图5.10 minicom波特率等配置界面图5.11 minicom配置完成后界面
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
在确认配置正确后,可键入回车返回上级配置界面,并将其保存为默认配置,如图5.12所示。
之后,可重新启动minicom使刚才配置生效,在连上开发板的串口线之后,就可在minicom 中打印出正确的串口信息,如图5.13所示。
图5.12 minicom保存配置信息
图5.13 minicom显示串口信息
到此为止,读者已经能将开发板的系统情况通过串口打印到宿主机上了,这样,就能很好地了解硬件的运行状况。
小知识通过串口打印信息是一个很常见的手段,很多其他情况如路由器等也是通过配置串口的波特率这些参数来显示对应信息的。
5.1.3 下载映像到开发板
正如第4章中所述,嵌入式开发的运行环境是目标板,而开发环境是宿主机。因此,需要把宿主机中经过编译之后的可执行文件下载到目标板上去。要注意的是,这里所说的下载是下载到目标机中的SDRAM。然后,用户可以选择直接从SDRAM中运行或写入到Flash 中再运行。运行常见的下载方式有网络下载(如tftp、ftp等方式)、串口下载、USB下载等,本书主要讲解网络下载中的tftp方式和串口下载方式。
1.tftp
Tftp协议是简单文件传输协议,它可以看作是一个FTP协议的简化版本,与FTP协议相比,它的最大区别在于没有用户管理的功能。它的传输速度快,可以通过防火墙,使用方便快捷,因此在嵌入式的文件传输中广泛使用。
同FTP一样,tftp分为客户端和服务器端两种。通常,首先在宿主机上开启tftp服务器《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
端服务,设置好tftp的根目录内容(也就是供客户端下载的文件),接着,在目标板上开启tftp 的客户端程序(现在很多开发板都已经提供了该项功能)。这样,把目标板和宿主机用直连线相连之后,就可以通过tftp协议传输可执行文件了。
下面分别讲述在Linux下和Windows下的配置方法。
(1)Linux下tftp服务配置
Linux下tftp的服务器服务是由xinetd所设定的,默认情况下是处于关闭状态。
首先,要修改tftp的配置文件,开启tftp服务,如下所示:
在这里,主要要将“disable=yes”改为“no”,另外,从“server_args”可以看出,tftp 服务器端的默认根目录为“/tftpboot”,用户若需要可以更改为其他目录。
接下来,重启xinetd服务,使刚才的更改生效,如下所示:
[root@sunq tftpboot]# service xinetd restart
关闭xinetd:[ 确定 ]
启动xinetd:[ 确定 ]
接着,使用命令“netstat -au”以确认tftp服务是否已经开启,如下所示:
[root@sunq tftpboot]# netstat -au
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address Stateudp 0 0 *:32768 *:*
udp 0 0 *:831 *:*
udp 0 0 *:tftp *:*
udp 0 0 *:sunrpc *:*
udp 0 0 *:ipp *:*
这时,用户就可以把所需要的传输文件放到“/tftpboot”目录下,这样,主机上的tftp服务就可以建立起来了。
接下来,用直连线(注意:不可以使用网线)把目标板和宿主机连起来,并且将其配置成一个网段的地址,再在目标板上启动tftp客户端程序(注意:不同的开发板所使用的命令可能会不同,读者可以查看帮助来获得确切的命令名及格式),如下所示:
首先,单击tftpd32下方的设置按钮,进入设置界面,如图5.14所示,在这里,主要配置tftp服务器端地址,也就是本机的地址。
接下来,重新启动tftpd32软件使刚才的配置生效,这样服务器端的配置就完成了,这时,就可以用直连线连接目标机和宿主机,且在目标机上开启tftp服务进行文件传输,这时,tftp 服务器端如图5.15和图5.16所示。
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
图5.14 tftpd32配置界面图5.15 tftp文件传输
图5.16 tftp服务器端显示情况
小知识tftp是一个很好的文件传输协议,它的简单易用吸引了广大用户。但它同时也存在着较大的安全隐患。由于tftp不需要用户的身份认证,因此给了黑客的可乘之机。读者一定还记得在2003年8月12日爆发的全球冲击波(Worm.Blaster)病毒,这种病毒就是模拟一个tftp服务器,并启动一个攻击传播线程,不断地随机生成攻击地址进行入侵。因此在使用tftp时一定要设置一个单独的目录作为tftp服务的根目录,如上文所述的“/tftpboot”等。
2.串口下载
使用串口下载需要配合特定的下载软件,如优龙公司提供的DNW软件等,一般在Windows下进行操作。虽然串口下载的速度没有网络下载快,但由于它很方便,不需要额外的连线和设置IP等操作,因此也广受用户的青睐。下面就以DNW软件为例,介绍串口下载的方式。
与其他串口通信的软件一样,在DNW中也要设置“波特率”、“端口号”等。打开“Configuration”下的“Options”界面,如图5.17所示。
图5.17 DNW配置界面
在配置完之后,单击“Serial Port”下的“Connect”,再将开发板上电,选择“串口下载”,接着再在“Serial Port”下选择“Transmit”,这时,就可以进行文件传输了,如图5.18和图5.19所示。这里DNW默认串口下载的地址为0x30200000。
图5.18 DNW串口下载图《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
图5.19 DNW串口下载情形图
5.1.4 编译嵌入式Linux内核
在做完了前期的准备工作之后,在这一步,读者就可以编译嵌入式移植Linux的内核了。在这里,本书主要介绍嵌入式Linux内核的编译过程,在下一节会进一步介绍嵌入式Linux 中体系结构相关的内核代码,读者在此之后就可以尝试嵌入式Linux操作系统的移植。
编译嵌入式Linux内核都是通过make的不同命令来实现的,它的执行配置文件就是在第3章中讲述的Makefile。Linux内核中不同的目录结构里都有相应的Makefile,而不同的Makefile又通过彼此之间的依赖关系构成统一的整体,共同完成建立依存关系、建立内核等功能。
内核的编译根据不同的情况会有不同的步骤,但其中最主要分别为3个步骤:内核配置、建立依存关系、建立内核,其他的为一些辅助功能,如清除文件等。读者在实际编译时若出现错误等情况,可以考虑采用其他辅助功能。下面分别讲述这3步主要的步骤。
(1)内核配置
第一步内核配置中的选项主要是用户用来为目标板选择处理器架构的选项,不同的处理器架构会有不同的处理器选项,比如ARM就有其专用的选项如“Multimedia capabilities port drivers”等。因此,在此之前,必须确保在根目录中Makefile里“ARCH”的值已设定了目标板的类型,如:
ARCH := arm
接下来就可以进行内核配置了,内核支持4种不同的配置方法,这几种方法只是与用
户交互的界面不同,其实现的功能是一样的。每种方法都会通过读入了一个默认的配置文件—根目录下“.config”隐藏文件(用户也可以手动修改该文件,但不推荐使用)。当然,用户也可以自己加载其他配置文件,也可以将当前的配置保存为其他名字的配置文件。这4种方式如下。
•make config:基于文本的最为传统的配置界面,不推荐使用。
•make menuconfig:基于文本选单的配置界面,字符终端下推荐使用。
•make xconfig:基于图形窗口模式的配置界面,Xwindow下推荐使用。
•make oldconfig:自动读入“.config”配置文件,并且只要求用户设定前次没有设定过的选项。
在这4种模式中,make menuconfig使用最为广泛,下面就以make menuconfig为例进行讲解,如图5.20所示。
从该图中可以看出,Linux内核允许用户对其各类功能逐项配置,一共有18类配置选项,这里就不对这18类配置选项进行一一讲解了,需要的读者可以参见相关选项的help。在menuconfig的配置界面中是纯键盘的操作,用户可使用上下键和“Tab”键移动光标以进入相关子项,图5.21所示为进入了“System Type”子项的界面,该子项是一个重要的选项,主要用来选择处理器的类型。
可以看到,每个选项前都有个括号,可以通过按空格键或“Y”键表示包含该选项,按“N”表示不包含该选项。
另外,读者可以注意到,这里的括号有3种,即中括号、尖括号或圆括号。读者可以用空格键选择相应的选项时可以发现中括号里要么是空,要么是“*”;尖括号里可以是空,“*”和“M”,分别表示包含选项、不包含选项和编译成模块;圆括号的内容是要求用户在所提供的几个选项中选择一项。
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建图5.20 make menuconfig配置界面
图5.21 System Type子项此外,要注意2.6和2.4内核在串口命名上的一个重要区别,在2.4内核中“COM1”对应的是“ttyS0”,而在2.6内核中“COM1”对应“ttySAC0”,因此在启动参数的子项要格外注意,如图5.22所示,否则串口打印不出信息。
一般情况下,使用厂商提供的默认配置文件都能正常运行,所以用户初次使用时可以不用对其进行额外的配置,在以后使用需要其他功能时再另行添加,这样可以大大减少出错的几率,有利于错误定位。在完成配置之后,就可以保存退出,如图5.23所示。
图5.22 启动参数配置子项《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
图5.23 保存退出
(2)建立依赖关系
由于内核源码树中的大多数文件都与一些头文件有依赖关系,因此要顺利建立内核,内核源码树中的每个Makefile就必须知道这些依赖关系。建立依赖关系往往发生在第一次编译内核的时候,它会在内核源码树中每个子目录产生一个“.depend”文件。运行“make dep”即可。
(3)建立内核
建立内核可以使用“make zImage”或“make bzImage”,这里建立的为压缩的内核映像。通常在Linux中,内核映像分为压缩的内核映像和未压缩的内核映像。其中,压缩的内核映像通常名为zImage,位于“arch/$(ARCH)/boot”目录中。而未压缩的内核映像通常名为vmlinux,位于源码树的根目录中。
到这一步就完成了内核源代码的编译,之后,读者可以使用上一小节所讲述的方法把内核压缩文件下载到开发板上运行。
小知识
在嵌入式Linux的源码树中通常有以下几个配置文件,“.config”、“autoconf.h”、“config.h”,其中“.config”文件是make menuconfig默认的配置文件,位于源码树的根目录中。“autoconf.h”和“config.h”是以宏的形式表示了内核的配置,当用户使用make menuconfig做了一定的更改之后,系统自动会在“autoconf.h”和“config.h”中做出相应的更改。它们位于源码树的“/include/linux/”下。
5.1.5 Linux 内核目录结构
Linux 内核的目录结构如
• /include 子目录包含包含文件,这个模块利用其• /init 子目录包含的开始的起点。
• /arch 子目录包含了如:arm 、i386、alpha 。
• /drivers 子目录包含块设备和SCSI 设备。
• /fs 子目录包含了所vfat 等。
• /net 子目录包含• /mm 子目录包含了所• /ipc 子目录包含了进• /kernel 子目录包含5.1.6 制作文件系统读者把上一节中所化的工作之后,并不能正常
图5.25 系统启动错误
5.24 Linux 内核目录结构
可以看到,系统启动时发生了加载文件系统的错误。要记住,上一节所编译的仅仅是内核,文件系统和内核是完全的两个部分。读者可以回忆一下第2章讲解的Linux启动过程的分析(嵌入式Linux是Linux裁减后的版本,其精髓部分是一样的),其中在head.S中就加载了根文件系统。因此,加载根文件系统是Linux启动中不可缺少的一部分。本节就来讲解嵌入式Linux中文件系统和根文件系统的制作方法。
制作文件系统的方法有很多,可以从零开始手工制作,也可以在现有的基础上添加部分内容加载到目标板上去。由于完全手工制作工作量比较大,而且也很容易出错,因此,本节将主要介绍把现有的文件系统加载到目标板上的方法,主要包括制作文件系统镜像和用NFS 加载文件系统的方法。
1.制作文件系统镜像
读者已经知道,Linux支持多种文件系统,同样,嵌入式Linux也支持多种文件系统。虽然在嵌入式中,由于资源受限的原因,它的文件系统和Linux的文件系统有较大的区别(前者往往是只读文件系统),但是,它们的总体架构是一样的,都是采用目录树的结构。在嵌入
可以看到,mkcramfs在制作文件镜像的时候对文件进行了压缩。
读者可以先在本机上通过mount进行验证,如下所示:
[root@localhost fs]# mkdir sunq
[root@localhost fs]# mount -o loop FS2410XP_camare_demo4.cramfs ./sunq [root@localhost fs]# ls sunq
bin dev etc home lib linuxrc proc Qtopia ramdisk sbin tmp usr var 接下来,就可以烧入到开发板的相应部分了。
2.NFS文件系统
NFS为Network FileSystem的简称,最早是由Sun公司提出发展起来的,其目的就是让不同的机器、不同的操作系统之间可以彼此共享文件。NFS可以让不同的主机通过网络将远端的NFS服务器共享出来的文件安装到自己的系统中,从客户端看来,使用NFS的远端文件就像是使用本地文件一样。在嵌入式中使用NFS会使应用程序的开发变得十分方便,并且
在这里,主机名或IP是可供共享的客户端主机名或IP,若对所有的IP都可以访问,则可用“*”表示。
这里的参数有很多中组合方式,常见的参数如表5.1所示。
表5.1 常见参数
选项参数含义
rw 可读写的权限
ro 只读的权限
no_root_squash NFS客户端分享目录使用者的权限,即如果客户端使用的是root用户,那么对于这个共享的目录而言,该客户端就具有root的权限
sync 资料同步写入到内存与硬盘当中
async 资料会先暂存于内存当中,而非直接写入硬盘如在本例中,配置文件“/etc/exports”的代码如下:《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
[root@localhost fs]# cat /etc/exports
/root/workplace *(rw,no_root_squash)
在设定完配置文件之后,需要启动nfs服务和portmap服务,这里的portmap服务是允许NFS客户端查看NFS服务在用的端口,在它被激活之后,就会出现一个端口号为111的sun RPC(远端过程调用)的服务。这是NFS服务中必须实现的一项,因此,也必须把它开启。如下所示:
[root@localhost fs]# service portmap start
启动portmap: [确定]
[root@localhost fs]# service nfs start
启动NFS 服务: [确定]
关掉NFS 配额: [确定]
启动NFS 守护进程: [确定]
启动NFS mountd: [确定]
另外一个是showmount命令,它用于当前的挂载情况。其格式为:
showmount [选项] hostname
showmount的常见选项如表5.3所示。
表5.3 常见选项
选项参数含义
-a 在屏幕上显示目前主机与客户端所连上来的使用目录状态
-e 显示hostname中/etc/exports里设定的共享目录5.2 U-Boot移植
5.2.1 Bootloader介绍
1.概念
简单地说,Bootloader就是在操作系统内核运行之前运行的一段程序,它类似于PC机中的BIOS程序。通过这段程序,可以完成硬件设备的初始化,并建立内存空间的映射图的功能,从而将系统的软硬件环境带到一个合适的状态,为最终调用系统内核做好准备。
通常,Bootloader是严重地依赖于硬件实现的,特别是在嵌入式中。因此,在嵌入式世界里建立一个通用的Bootloader几乎是不可能的。尽管如此,仍然可以对Bootloader归纳出一些通用的概念来指导用户特定的Bootloader设计与实现。
(1)Bootloader所支持的CPU和嵌入式开发板
每种不同的CPU体系结构都有不同的Bootloader。有些Bootloader也支持多种体系结构的CPU,如后面要介绍的U-Boot就同时支持ARM体系结构和MIPS体系结构。除了依赖于CPU的体系结构外,Bootloader实际上也依赖于具体的嵌入式板级设备的配置。
(2)Bootloader的安装媒介
系统加电或复位后,所有的CPU通常都从某个由CPU制造商预先安排的地址上取指令。而基于CPU构建的嵌入式系统通常都有某种类型的固态存储设备(比如ROM、EEPROM或FLASH等)被映射到这个预先安排的地址上。因此在系统加电后,CPU将首先执行Bootloader 程序。
(3)Bootloader的启动过程分为单阶段和多阶段两种。通常多阶段的Bootloader能提供更为复杂的功能,以及更好的可移植性。
(4)Bootloader的操作模式。大多数Bootloader都包含两种不同的操作模式:“启动加载”模式和“下载”模式,这种区别仅对于开发人员才有意义。
•启动加载模式:这种模式也称为“自主”模式。也就是Bootloader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。这种模式是嵌入式产品发布时的通用模式。
•下载模式:在这种模式下,目标机上的Bootloader将通过串口连接或网络连接等通信手段从主机(Host)下载文件,比如:下载内核映像和根文件系统映像等。从主机下载的文件通常首先被Bootloader保存到目标机的RAM中,然后再被Bootloader写到目标机上的FLASH类固态存储设备中。Bootloader的这种模系统是在更新时使用。工作于这种模式下的Bootloader通常都会向它的终端用户提供一个简单的命令行接口。
(5)Bootloader与主机之间进行文件传输所用的通信设备及协议,最常见的情况就是,目标机上的Bootloader通过串口与主机之间进行文件传输,传输协议通常是xmodem/ ymodem/zmodem协议中的一种。但是,串口传输的速度是有限的,因此通过以太网连接并借助TFTP协议来下载文件是个更好的选择。
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建2.Bootloader启动流程
Bootloader的启动流程一般分为两个阶段:stage1和stage2,下面分别对这两个阶段进行讲解:
(1)Bootloader的stage1
在stage1中Bootloader主要完成以下工作。
•基本的硬件初始化,包括屏蔽所有的中断、设置CPU的速度和时钟频率、RAM初始化、初始化LED、关闭CPU内部指令和数据cache灯。
•为加载stage2准备RAM空间,通常为了获得更快的执行速度,通常把stage2加载到RAM空间中来执行,因此必须为加载Bootloader的stage2准备好一段可用的RAM空间范围。
•拷贝stage2到RAM中,在这里要确定两点:①stage2的可执行映像在固态存储设备的存放起始地址和终止地址;②RAM空间的起始地址。
•设置堆栈指针sp,这是为执行stage2的C语言代码做好准备。
(2)Bootloader的stage2
在stage2中Bootloader主要完成以下工作。
•用汇编语言跳转到main入口函数
由于stage2的代码通常用C语言来实现,目的是实现更复杂的功能和取得更好的代码可读性和可移植性。但是与普通C语言应用程序不同的是,在编译和链接Bootloader这样的程序时,不能使用glibc库中的任何支持函数。
•初始化本阶段要使用到的硬件设备,包括初始化串口、初始化计时器等。在初始化这些设备之前、可以输出一些打印信息。
•检测系统的内存映射,所谓内存映射就是指在整个4GB物理地址空间中有指出哪些地址范围被分配用来寻址系统的RAM单元。
•加载内核映像和根文件系统映像,这里包括规划内存占用的布局和从Flash上拷贝数据。
•设置内核的启动参数。
5.2.2 U-Boot概述
1.U-Boot简介
U-Boot(UniversalBootloader),是遵循GPL条款的开放源码项目。它是从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。但是U-Boot不仅仅支持嵌入式Linux系统的引导,而且还支持NetBSD、VxWorks、QNX、RTEMS、ARTOS、LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD、NetBSD、FreeBSD、4.4BSD、Linux、SVR4、Esix、Solaris、Irix、SCO、Dell、NCR、VxWorks,LynxOS、pSOS、QNX、RTEMS、ARTOS。这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。就目前为止,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。
2.U-Boot特点
U-Boot的特点如下。
•开放源码;
•支持多种嵌入式操作系统内核,如Linux、NetBSD、VxWorks、QNX、RTEMS、ARTOS、LynxOS;
•支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;
•较高的可靠性和稳定性;
•高度灵活的功能设置,适合U-Boot调试,操作系统不同引导要求,产品发布等;
•丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;
•较为丰富的开发调试文档与强大的网络技术支持。
3.U-Boot主要功能
U-Boot可支持的主要功能列表。
•系统引导:支持NFS挂载、RAMDISK(压缩或非压缩)形式的根文件系统。支持NFS挂载,并从FLASH中引导压缩或非压缩系统内核。
•基本辅助功能:强大的操作系统接口功能;可灵活设置、传递多个关键参数给操作系统,适合系统在不同开发阶段的调试要求与产品发布,尤其对Linux支持最为强劲;支持目标板环境参数多种存储方式,如FLASH、NVRAM、EEPROM;CRC32校验,可校验FLASH 中内核、RAMDISK镜像文件是否完好。
•设备驱动:串口、SDRAM、FLASH、以太网、LCD、NVRAM、EEPROM、键盘、USB、PCMCIA、PCI、RTC等驱动支持。
•上电自检功能:SDRAM、FLASH大小自动检测;SDRAM故障检测;CPU型号。
•特殊功能:XIP内核引导。
5.2.3 U-Boot源码导读
1.U-Boot源码结构
U-Boot源码结构如图5.26所示。
•board:和一些已有开发板有关的文件,比如Makefile
和U-Boot.lds等都和具体开发板的硬件和地址分配有关。
•common:与体系结构无关的文件,实现各种命令的C
文件。
图5.26 U-Boot源码结构《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
•cpu:CPU相关文件,其中的子目录都是以U-BOOT所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等;interrupt.c设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是U-BOOT启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为进入C 程序奠定基础。
•disk:disk驱动的分区处理代码。
•doc:文档。
•drivers:通用设备驱动程序,比如各种网卡、支持CFI的Flash、串口和USB总线等。
•fs:支持文件系统的文件,U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。
•include:头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。
•net:与网络有关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
#ifdef CONFIG_USE_IRQ
/* enable IRQ interrupts */
void enable_interrupts (void)
{
unsigned long temp;
__asm__ __volatile__("mrs %0, cpsr\\n"
"bic %0, %0, #0x80\\n"
"msr cpsr_c, %0"
: "=r" (temp)
:
: "memory");
}
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建 __u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
(4)memsetup.S
这个文件是用于配置开发板参数的,如下所示:
5.2.4 U-Boot移植主要步骤
1.配置主板
阅读Makefile文件,在Makefile文件中添加两行,如下所示:
s3c2410_config: unconfig @./mkconfig $(@:_config=) arm arm920t s3c2410
其中ARM是CPU的种类,arm920t是ARM CPU对应的代码目录,s3c2410是自已主板对应的目录。
(l)在board目录中建立s3c2410目录,并复制smdk2410目录中的内容(cp smdk2410/* s3c2410)。
•在include/configs/目录下复制smdk2410.h(cp smdk2410.h s3c2410.h)。
•修改ARM编译器的目录名及前缀。
•完成之后,可以测试配置。
#make s3c2410_config
#make
(2)修改程序连接地址
在board/s3c2410中有一个config.mk文件,它是用于设置程序连接的起始地址,因为会在U-Boot中增加功能,所以留下6MB的空间,并修改33F80000为33A00000。
为了以后能用U-Boot的GO命令执行修改过的用loadb或tftp下载的U-Boot:在board/ s3c2410的memsetup.S中标记符”0:”上加入5句:
5.2.5 U-Boot常见命令
•?:得到所有命令列表。
•help:help usb,列出USB功能的使用说明。
•ping:测试与对方主机的网络是否正常,这里只能开发板PING别的机器。
•setenv:设置环境变量。
•saveenv:保存环境变量。在设置好环境变量以后,要保存变量值。
•ftp:tftp 32000000 vmlinux,把server(IP=环境变量中设置的serverip)中/tftpdroot/下的vmlinux通过TFTP读入到物理内存32000000处。
•kgo:启动没有压缩的linux内核,kgo 32000000。
•bootm:启动UBOOT TOOLS制作的压缩LINUX内核,bootm 3200000。
•protect:对FLASH进行写保护或取消写保护,protect on 1:0-3(就是对第一块FLASH《嵌入式Linux应用程序开发详解》——第5章、嵌入式Linux开发环境的搭建
的0-3扇区进行保护),protect off 1:0-3取消写保护。
•erase:删除FLASH的扇区,erase 1:0-2(就是对每一块FLASH的0-2扇区进行删除)。
•cp:在内存中复制内容,cp 32000000 0 40000(把内存中0x32000000开始的0x40000字节复制到0x0处)。
•mw:对RAM中的内容写操作,如mw 32000000 ff 10000是指把内存0x32000000开始的0x10000字节设为0xFF。
•md:修改RAM中的内容,如md 32000000指内存的起始地址为。
•usb:usb start是指启动usb功能;usb info是指列出设备;usb scan是指扫描usb storage (U盘)设备。
•fatls:列出DOS FA T文件系统,如:fatls usb 0是指列出第一块U盘中的文件。
•fatload:读入FAT中的一个文件,如:fatload usb 0:0 32000000 aa.txt。
•flinfo:列出flash的信息。
•loadb:准备用KERMIT协议接收来自kermit或超级终端传送的文件。
•nfs:nfs 32000000 192.168.0.2:aa.txt,把192.168.0.2(LINUX的NFS文件系统)中的NFS文件系统中的aa.txt读入内存0x32000000处。
5.3 实验内容——移植Linux内核
1.实验目的
通过移植Linux内核,熟悉嵌入式开发环境的搭建和Linux内核的编译配置。由于具体步骤在前面已经详细讲解过了,因此,相关部分请读者查阅本章前面内容。
2.实验内容
首先在Linux环境下配置minicom,使之能够正常显示串口的信息。然后再编译配置Linux2.6内核,并下载到开发板上运行。
3.实验步骤
(1)设置minicom,按键“CTRL-A O”配置相应参数。
(2)连接开发板与主机,查看串口是否有正确输出。
(3)查看Linux内核顶层的Makefile,确定相关参数是否正确。
(4)运行“make menuconfig”,进行相应配置。
(5)运行“make dep”。
(6)运行“make zImage”。
(7)将生成映像通过tftp或串口下载到开发板中。
(8)启动运行内核。
4.实验结果
开发板能够正确运行新生成的内核映像。
本章小结
本章详细讲解了嵌入式Linux开发环境的搭建,包括minicom和超级终端的配置,如何下载映像文件到开发板,如何移植嵌入式Linux内核以及如何移植U-Boot。这些都是操作性很强的内容,而且在嵌入式的开发中也是必不可少的一部分,因此希望读者确实掌握。
思考与练习
1.适当更改Linux内核配置,再进行编译下载查看结果。
2.配置NFS服务。
