1、【学习目标】了解嵌入式Linux系统的移植l了解Bootloader的原理l掌握嵌入式交叉编译环境的搭建l学会编译Linux内核 l学会搭建Linux的文件系统11/21/20221一、嵌入式Linux系统的移植二、Bootloader的构成原理三、嵌入式交叉编译环境的搭建四、Linux内核和文件系统的烧写五、Linux内核 的配置和编译六、linux文件系统的搭建七、NFS文件系统的配置和使用11/21/20222一、嵌入式Linux系统的移植 Linux操作系统的移植主要包括移植操作系统的移植主要包括移植Bootloader、移植、移植Linux内核、移植相应内核、移植相应的驱动程序和构建
2、文件系统。的驱动程序和构建文件系统。11/21/20223嵌入式系统与主机的连接方式 JTAG接口接口 JTAG仿真器与主机连接,将引导程序固化到仿真器与主机连接,将引导程序固化到FLASH中。中。串口串口 主机通过主机通过minicom或或Windows超级终端等工具获超级终端等工具获得目标板程序运行、调试信息。得目标板程序运行、调试信息。网络网络 一般采用一般采用NFS、TFTP等协议传输文件。等协议传输文件。USB 主机为主机为USB主设备端,目标板为主设备端,目标板为USB从设备端,从设备端,用于下载程序到目标板中。用于下载程序到目标板中。11/21/20224Windows超级终端的
3、使用11/21/20225minicom的使用11/21/20226二、Bootloader的构成原理 简单地说,简单地说,Bootloader就是在操作系统内核运行就是在操作系统内核运行之前运行的一段程序,它类似于之前运行的一段程序,它类似于PC机中的机中的BIOS程序。通过这段程序,可以完成硬件设备的初始程序。通过这段程序,可以完成硬件设备的初始化,并建立内存空间的映射关系,从而将系统的化,并建立内存空间的映射关系,从而将系统的软硬件环境带到一个合适的状态,为最终加载系软硬件环境带到一个合适的状态,为最终加载系统内核做好准备。统内核做好准备。通常,通常,Bootloader比较依赖于硬件平
4、台,建立一比较依赖于硬件平台,建立一个通用的个通用的Bootloader是一件比较困难的事情。是一件比较困难的事情。11/21/20227Bootloader的操作模式(一)系统加电或者复位以后,系统加电或者复位以后,CPU从厂家预设的从厂家预设的某个地址上取指执行,某个地址上取指执行,Bootloader通常被通常被固化在这个地址上。在嵌入式开发时,通固化在这个地址上。在嵌入式开发时,通常要使用各种命令操作常要使用各种命令操作Bootloader,一般,一般使用串口来连接使用串口来连接PC和开发板,通过串口输和开发板,通过串口输入各种命令和观察运行结果。用户使用产入各种命令和观察运行结果。用
5、户使用产品时,不需操作品时,不需操作Bootloader。11/21/20228Bootloader的操作模式(二)启动加载(启动加载(Boot Loading)模式:)模式:上电后,上电后,Bootloader将操作系统从固态存将操作系统从固态存储设备中加载到储设备中加载到RAM中执行,用户不需介中执行,用户不需介入操作。是最终产品发布的模式,也叫入操作。是最终产品发布的模式,也叫“自主自主”模式。模式。下载(下载(Down Loading)模式:)模式:开发人员使用各种命令,通过串口、网口、开发人员使用各种命令,通过串口、网口、USB等方式从主机下载内核镜像和文件系等方式从主机下载内核镜像
6、和文件系统等,将其固化至固态存储设备。统等,将其固化至固态存储设备。11/21/20229Bootloader的启动流程 由于由于Bootloader的实现依赖于的实现依赖于CPU的体系的体系结构,因此大多数结构,因此大多数Bootloader都分为都分为Stage1和和Stage2两大部分。依赖于两大部分。依赖于CPU体体系结构的代码,如设备初始化代码等,通系结构的代码,如设备初始化代码等,通常都放在常都放在Stage1中,而且通常都用汇编语中,而且通常都用汇编语言来实现,以达到短小精悍的目的。而言来实现,以达到短小精悍的目的。而Stage2则通常用则通常用C语言来实现,这样可以语言来实现,
7、这样可以实现复杂的功能,而且代码具有更好的可实现复杂的功能,而且代码具有更好的可读性和可移植性。读性和可移植性。11/21/202210Bootloader的启动流程Stage1 基本的硬件初始化,包括屏蔽所有的中断、设置基本的硬件初始化,包括屏蔽所有的中断、设置CPU的速度和时钟频率、的速度和时钟频率、RAM初始化、初始化外初始化、初始化外围设备、关闭围设备、关闭CPU内部指令和数据内部指令和数据cache等。等。为加载为加载stage2准备准备RAM空间,通常为了获得更快空间,通常为了获得更快的执行速度,通常把的执行速度,通常把stage2加载到加载到RAM空间中来空间中来执行,因此必须为
8、加载执行,因此必须为加载Bootloader的的stage2准备准备好一段可用的好一段可用的RAM空间。空间。拷贝拷贝stage2到到RAM中,在这里要确定两点:中,在这里要确定两点:stage2的可执行映像在固态存储设备的存放起的可执行映像在固态存储设备的存放起始地址和终止地址;始地址和终止地址;RAM空间的起始地址。空间的起始地址。设置堆栈指针设置堆栈指针sp,这是为执行,这是为执行stage2的的C语言代语言代码做好准备。码做好准备。11/21/202211Bootloader的启动流程Stage2 用汇编语言跳转到用汇编语言跳转到main入口函数(入口函数(bl main)由于由于st
9、age2的代码通常用的代码通常用C语言来实现,目的是实现更复语言来实现,目的是实现更复杂的功能和取得更好的代码可读性和可移植性。但是与普杂的功能和取得更好的代码可读性和可移植性。但是与普通通C语言应用程序不同的是,在编译和链接语言应用程序不同的是,在编译和链接Bootloader这这样的程序时,不能使用样的程序时,不能使用glibc库中的任何支持函数。库中的任何支持函数。初始化本阶段要使用到的硬件设备,包括初始化串口、初初始化本阶段要使用到的硬件设备,包括初始化串口、初始化计时器等。在初始化这些设备之前、可以输出一些打始化计时器等。在初始化这些设备之前、可以输出一些打印信息。印信息。检测系统的
10、内存映射,所谓内存映射就是指在整个检测系统的内存映射,所谓内存映射就是指在整个4GB物物理地址空间中指出哪些地址范围被分配用来寻址系统的内理地址空间中指出哪些地址范围被分配用来寻址系统的内存。存。加载内核映像和根文件系统映像,这里包括规划内存占用加载内核映像和根文件系统映像,这里包括规划内存占用的布局和从的布局和从Flash上拷贝数据。上拷贝数据。设置内核的启动参数。设置内核的启动参数。11/21/202212三、嵌入式交叉编译环境的搭建 交叉开发模式就是指在主机上编辑、编译交叉开发模式就是指在主机上编辑、编译程序,然后在目标板上运行、验证程序的程序,然后在目标板上运行、验证程序的过程。在裁减
11、和定制过程。在裁减和定制Linux内核用于嵌入式内核用于嵌入式系统之前,由于一般嵌入式开发系统的资系统之前,由于一般嵌入式开发系统的资源有限,通常都要在源有限,通常都要在PC上建立一个用于目上建立一个用于目标机的交叉编译工具链,用该交叉编译工标机的交叉编译工具链,用该交叉编译工具链在具链在PC上编译目标机上要运行的程序。上编译目标机上要运行的程序。11/21/202213交叉编译工具链的组成 binutils:是一组二进制处理工具的集合,是一组二进制处理工具的集合,包括连接器,汇编器和其他用于目标文件包括连接器,汇编器和其他用于目标文件和档案的工具,如和档案的工具,如objdump、as、ld
12、等。等。gcc:用来生成交叉编译器,主要生成:用来生成交叉编译器,主要生成arm-linux-gcc交叉编译工具。交叉编译工具。glibc:主要是提供用户程序所使用的一些:主要是提供用户程序所使用的一些基本的函数库。基本的函数库。11/21/202214交叉编译工具链的安装(一)安装交叉编译器,只需将该编译器的解压安装交叉编译器,只需将该编译器的解压缩文件放在指定的目录下边,缩文件放在指定的目录下边,linux2.6.12 内核使用的编译器为内核使用的编译器为3.4.1 版本。版本。指定目录为:指定目录为:/usr/local/arm 根目录下执行根目录下执行 tar-jxvf cross-3
13、.4.1.tar.bz2 11/21/202215交叉编译工具链的安装(二)在使用的时候有两种方式:(以编译在使用的时候有两种方式:(以编译hello.c 程程序为例,生成可执行文件序为例,生成可执行文件hello)1./usr/local/arm/3.4.1/bin/arm-linux-gcc hello.c o hello2.编辑编辑/etc/bashrc 文件,在最后增加路径:文件,在最后增加路径:export PATH=/usr/local/arm/3.4.1/bin:$PATH 这样就把这样就把/usr/local/arm/3.4.1/bin 添加到命令的添加到命令的默认路径,在编译
14、的时候则可直接用如下的命令:默认路径,在编译的时候则可直接用如下的命令:arm-linux-gcc hello.c o hello11/21/202216四、Linux内核和文件系统的烧写 1.Bootloader的的Linux启动设置启动设置 2.USB驱动及驱动及DNW软件的安装软件的安装 3.内核和文件系统的烧写内核和文件系统的烧写11/21/202217Bootloader的Linux启动设置 进入进入Bootloader 菜单,选择菜单,选择7 进入参数设进入参数设置菜单,将参数置菜单,将参数0的值改为的值改为2(1 为分区为分区application中的程序,中的程序,2 为自启动
15、为自启动linux,3 为自启动为自启动wince)。)。11/21/202218USB驱动及DNW软件的安装(一)驱动程序:驱动程序:PC机需要安装的驱动程序机需要安装的驱动程序USB驱动驱动_用于用于DNW下载程序下载程序.rar 设备名称:设备名称:Witech SEC SOC Test Board 11/21/202219USB驱动及DNW软件的安装(二)DNW 软件是三星公司为软件是三星公司为S3C2440A 芯片配置的芯片配置的一款专用软件,可以在一款专用软件,可以在Windows 下用下用USB方式方式来烧写来烧写FLASH。文件位置:文件位置:实用工具实用工具串口工具串口工具D
16、NW Configuration:COM1,115200,Download Address:0 x3080000011/21/202220内核和文件系统的烧写 11/21/202221五、Linux内核的配置和编译 Linux内核是指内核是指Linux源代码经过编译和链源代码经过编译和链接生成的映像文件(接生成的映像文件(Image)。通常编译)。通常编译嵌入式嵌入式Linux内核都是通过不同的内核都是通过不同的make命命令来实现的令来实现的,它的执行配置文件就是它的执行配置文件就是Makefile,而不同的而不同的Makefile又通过互相的又通过互相的依赖关系构成一个统一的整体去完成建立
17、依赖关系构成一个统一的整体去完成建立依存关系、建立内核等功能。依存关系、建立内核等功能。11/21/202222Linux内核的获取 文件位置:文件位置:Linuxlinux2.6.12内核源码包内核源码包 解压文件:解压文件:tar-jxvf linux-2.6.12-090915.tar.bz211/21/202223Linux内核的配置(一)Linux内核的配置系统由内核的配置系统由3部分组成:部分组成:(1)Makefile:分布在:分布在Linux内核源代码中的内核源代码中的Makefile,定义,定义Linux内核的编译规则;内核的编译规则;(2)配置文件()配置文件(config
18、.in):给用户提供配):给用户提供配置选择的功能。置选择的功能。(3)配置工具,包括配置命令解释器(对配)配置工具,包括配置命令解释器(对配置脚本中使用的命令进行解释)和配置用户界置脚本中使用的命令进行解释)和配置用户界面(提供基于字符界面、基于面(提供基于字符界面、基于Xwindow图形界图形界面的用户配置界面)。面的用户配置界面)。11/21/202224Linux内核的配置(二)在内核中,在内核中,Makefile的作用是根据配置的的作用是根据配置的情况构造出需要编译的文件列表,然后分情况构造出需要编译的文件列表,然后分别编译,并把目标文件链接在一起,最终别编译,并把目标文件链接在一起
19、,最终形成形成Linux内核的二进制文件。内核的二进制文件。11/21/202225Linux内核的配置(三)Linux内核中的内核中的Makefile以及与以及与 Makefile 直接相关的文件有:直接相关的文件有:Makefile:顶层:顶层 Makefile,是整个内核配置、编译的总体,是整个内核配置、编译的总体控制文件。控制文件。.config:内核配置文件,包含由用户选择的配置选项,:内核配置文件,包含由用户选择的配置选项,用来存放内核配置后的结果(如用来存放内核配置后的结果(如 make config)。)。arch/*/Makefile:位于各种:位于各种 CPU 体系目录下的
20、体系目录下的 Makefile,如如 arch/arm/Makefile,是针对特定平台的,是针对特定平台的 Makefile。各个子目录下的各个子目录下的 Makefile:比如:比如 drivers/Makefile,负责,负责所在子目录下源代码的管理。所在子目录下源代码的管理。Rules.make:规则文件,被所有的:规则文件,被所有的 Makefile 使用。使用。11/21/202226Linux内核的配置(四)内核配置方法有以下几种:内核配置方法有以下几种:(1)make config:基于文本的最为传统的配置界基于文本的最为传统的配置界面面,进入命令行进入命令行,可以一行一行的配
21、置可以一行一行的配置,该方法较烦该方法较烦琐。琐。(2)make menuconfig:基于文本菜单的配置界基于文本菜单的配置界面面,是字符终端下常用的方式。是字符终端下常用的方式。(3)make xconfig:基于图形窗口模式的配置界基于图形窗口模式的配置界面面,Xwindow下推荐使用。下推荐使用。(4)make oldconfig:自动读入自动读入“config”配置文配置文件件,并且只要求用户设定前次没有设定过的选项。并且只要求用户设定前次没有设定过的选项。11/21/202227Linux内核的配置(五)四种方法中,四种方法中,make xconfig界面最友好,界面最友好,可以使
22、用鼠标选择相应的选项;如果不是可以使用鼠标选择相应的选项;如果不是使用使用Xwindow,使用,使用make menuconfig,需要用空格键进行选取。选择相应的配置需要用空格键进行选取。选择相应的配置时,有时,有3种选择:种选择:Y 将该功能编译至内核将该功能编译至内核 N 不将该功能编译至内核不将该功能编译至内核 M 将该功能编译成在需要时可以动态插将该功能编译成在需要时可以动态插入到内核的模块入到内核的模块11/21/202228Linux内核的配置(六)每种模式都有其优缺点,动态加载模块有每种模式都有其优缺点,动态加载模块有利于减小内核长度,减少消耗内存,但是利于减小内核长度,减少消
23、耗内存,但是必须通过手动调用这些模块;如果编译至必须通过手动调用这些模块;如果编译至内核,虽然方便快捷,但会使内核越来越内核,虽然方便快捷,但会使内核越来越大,消耗更多系统资源。因此,要将常用大,消耗更多系统资源。因此,要将常用功能直接编译到内核,如网卡和光驱。功能直接编译到内核,如网卡和光驱。11/21/202229Linux内核的配置(七)进行配置时,大部分选项可以使用默认值,只有小部分要进行配置时,大部分选项可以使用默认值,只有小部分要根据需要选择。比较重要的选项如下:根据需要选择。比较重要的选项如下:Code Maturity Level Option(内核成熟级别选项)(内核成熟级别
24、选项)Loadable Module Support(可加载模块支持)(可加载模块支持)General Setup(通用设置)(通用设置)Memory Technology Devices(内存技术设备)(内存技术设备)Block Devices(块设备)(块设备)Network Device Support(网络设备支持)(网络设备支持)Character Devices(字符设备)(字符设备)File systems(文件系统)(文件系统)Console Drivers(控制台设备)(控制台设备)11/21/202230Linux建立依赖关系 由于内核源码树中的大多数文件都与一些由于内核源
25、码树中的大多数文件都与一些头文件有依赖关系,因此要顺利建立内核,头文件有依赖关系,因此要顺利建立内核,内核源码树中的每个内核源码树中的每个Makefile都必须知道都必须知道这些依赖关系。建立依赖关系通常在第一这些依赖关系。建立依赖关系通常在第一次编译内核的时候(或者源码目录树的结次编译内核的时候(或者源码目录树的结构发生变化的时候)进行,它会在内核源构发生变化的时候)进行,它会在内核源码树中每个子目录产生一个码树中每个子目录产生一个“.depend”文文件。运行件。运行“make dep”即可。在编译即可。在编译linux2.6版本的内核通常不需要这个过程,版本的内核通常不需要这个过程,直接
26、输入直接输入“make”即可。即可。11/21/202231Linux内核的建立 Linux中内核映像分为压缩的内核映像和未中内核映像分为压缩的内核映像和未压缩的内核映像。压缩的内核映像通常命压缩的内核映像。压缩的内核映像通常命名为名为zImage,位于,位于“arch/arm/boot”,未未压缩的内核映像通常名为压缩的内核映像通常名为vmlinux,位于源,位于源码树的根目录中。码树的根目录中。命令:命令:make zImage11/21/202232Linux内核源码目录结构 /include子目录包含了建立内核代码时所需的大部分包含子目录包含了建立内核代码时所需的大部分包含文件,这个模
27、块利用其他模块重建内核。文件,这个模块利用其他模块重建内核。/init子目录包含了内核的初始化代码,这里的代码是内核子目录包含了内核的初始化代码,这里的代码是内核工作的起始入口。工作的起始入口。/arch子目录包含了所有处理器体系结构特定的内核代码。子目录包含了所有处理器体系结构特定的内核代码。如:如:arm、i386、alpha。/drivers子目录包含了内核中所有的设备驱动程序,如块子目录包含了内核中所有的设备驱动程序,如块设备和设备和SCSI设备。设备。/fs子目录包含了所有的文件系统的代码,如:子目录包含了所有的文件系统的代码,如:ext2,vfat等。等。/net子目录包含了内核的
28、网络相关代码。子目录包含了内核的网络相关代码。/mm子目录包含了所有内存管理代码。子目录包含了所有内存管理代码。/ipc子目录包含了进程间通信代码。子目录包含了进程间通信代码。/kernel子目录包含了内核核心代码。子目录包含了内核核心代码。11/21/202233六、Linux文件系统的搭建 嵌入式嵌入式Linux支持多种文件系统,虽然在嵌入式中,支持多种文件系统,虽然在嵌入式中,由于资源受限的原因,它的文件系统和由于资源受限的原因,它的文件系统和PC机机Linux的文件系统有较大的区别,但是,它们的的文件系统有较大的区别,但是,它们的总体架构是一样的,都是采用目录树的结构。在总体架构是一样
29、的,都是采用目录树的结构。在嵌入式中常见的文件系统有嵌入式中常见的文件系统有cramfs、romfs、jffs、yaffs等等。Yaffs(Yet Another Flash File System)文件)文件系统是专门针对系统是专门针对NAND 闪存设计的嵌入式文件系闪存设计的嵌入式文件系统,目前有统,目前有YAFFS 和和YAFFS2 两个版本,两个两个版本,两个版本的主要区别之一在于版本的主要区别之一在于YAFFS2 能够更好的支能够更好的支持大容量的持大容量的NAND FLASH芯片。芯片。11/21/202234Linux文件系统的建立 文件位置:文件位置:Linuxlinux2.6
30、.12文件系统源码及制作工具文件系统源码及制作工具 解压文件:解压文件:tar-jxvf qte_yaffs.tar.bz2 用用mkyaffs2image工具来制作文件系统:工具来制作文件系统:./mkyaffs2image qte_yaffs qte.yaffs11/21/202235七、NFS文件系统的配置和使用 NFS为为Network File System的简称,最早的简称,最早是由是由Sun公司提出发展起来的,其目的就公司提出发展起来的,其目的就是让不同的机器、不同的操作系统之间通是让不同的机器、不同的操作系统之间通过网络可以彼此共享文件。过网络可以彼此共享文件。NFS可以让不可
31、以让不同的主机通过网络将远端的同的主机通过网络将远端的NFS服务器共服务器共享出来的文件安装到自己的系统中,从客享出来的文件安装到自己的系统中,从客户端看来,使用户端看来,使用NFS的远端文件就像是使的远端文件就像是使用本地文件一样。在嵌入式中使用用本地文件一样。在嵌入式中使用NFS会会使应用程序的开发变得十分方便,并且不使应用程序的开发变得十分方便,并且不用反复地进行烧写映像文件。用反复地进行烧写映像文件。11/21/202236NFS介绍(一)NFS的使用分为服务端和客户端,其中服务端是提供要共享的文件而客户端则通过挂载(“mount”)这一动作来实现对共享文件的访问操作。在嵌入式开发中,
32、通常NFS服务端在宿主机上运行,而客户端在目标板上运行。NFS服务端是通过读入它的配置文件“/etc/exports”来决定所共享的文件目录的。在这个配置文件中,每一行都代表一项要共享的文件目录以及所指定的客户端对它的操作权限。客户端可以根据相应的权限,对该目录下的所有目录文件进行访问。11/21/202237NFS介绍(二)/etc/exports 中使用的NFS配置命令:共享的目录 客户端主机名称或IP 参数1,参数2 主机名或IP是可供共享的客户端主机名或IP,若对所有的IP都可以访问,则可用“*”表示。11/21/202238NFS配置和使用(一)/etc/exports文件:/project *(rw,no_root_squash)NFS服务启动:service nfs restart11/21/202239NFS配置和使用(二)开发板IP设置(单次设置):ifconfig eth0 192.168.56.200 up启动自动设置IP:Linux 的启动脚本位于/etc/init.d/rcS修改其中的ifconfig eth0 行11/21/202240NFS配置和使用(三)挂载/projectmount-o nolock 192.168.56.101:/project/mnt取消挂载umount/mnt 11/21/202241