1、1在线教务辅导网:在线教务辅导网:http:/教材其余课件及动画素材请查阅在线教务辅导网教材其余课件及动画素材请查阅在线教务辅导网QQ:349134187 或者直接输入下面地址:或者直接输入下面地址:http:/2第五章 嵌入式Linux启动引导程序、内核、文件系统3BootLoader的基本概念 Boot Loader 就是在操作系统内核运行之前运行的一段引导系统启动的程序。通过这段小程序的作用是初始化硬件设备、建立内存空间的映射图,并将系统的软硬件环境带到一个合适的状态,以便为调用操作系统内核准备好正确的环境。在嵌入式世界,Boot Loader 是严重地依赖于硬件而实现的,没有Bootl
2、oader,嵌入式系统就不能启动。由于作者在这方面的功力还不够,所以无法向读者介绍针对TQ2440开发板的u-boot移植,只介绍一下u-boot的使用基础和概念。Bootloader完成的主要功能就是将操作系统调进内存中执行,然后将控制权交给操作系统,嵌入式系统中常见的Bootloader有Vivi、Blob、Redboot、U-Boot等。4内核移植的平台内核移植的平台 1.首先验证所下载内核的完整性2.安装编译内核时所需要的工具:3.编译前的准备编译前的准备4.内核源代码的修改 修改平台输入时钟修改平台输入时钟Makefile文件文件、机器机器代代码加码加入入NAND FLASH的分区信
3、息的分区信息、添加内核对添加内核对yaffs2的支持的支持、修改看门狗驱动、修改看门狗驱动 5.输入make进行编译5fhfh:$gpg-verify linux-2.6.30.4.tar.bz2.signgpg:于2009年07月31日星期五 07时13分44秒 CST 创建的签名,使用DSA,钥匙号 517D0F0Egpg:完好的签名,来自于“Linux Kernel Archives Verification Key”gpg:警告:这把密钥已经被它的持有者吊销了!gpg:这表明这个签名有可能是伪造的。gpg:吊销原因:密钥已泄漏gpg:吊销注释:Key was used to autos
4、igning;autosigning server was compromised.gpg:警告:这把密钥未经受信任的签名认证!gpg:没有证据表明这个签名属于它所声称的持有者。主钥指纹:C75D C40A 11D7 AF88 9981 ED5B C86B A06A 517D 0F0E如果主钥指纹和ftpadminkernel.org 邮箱与http:/www.kernel.org/signature.html网站的信息一样如图5-1所示,则表示这个包是完整的。67安装编译内核时所需要的工具:fhfh:$sudo apt-get install libncurses5-dev fhfh:$su
5、do apt-get install ncurses-docfhfh:$sudo apt-get install kernel-packagefhfh:$mkdir/home/fh/kernel (建立放置内核的目录)fhfh:$cp linux-2.6.30.4.tar.bz2/home/fh/kernel(复制内核)fhfh:$cd/home/fh/kernel、fhfh:/kernel$tar jxvf linux-2.6.30.4.tar.bz2(解压内核)fhfh:/kernel$cd/home/fh/kernel/linux-2.6.30.4(进入内核目录,实际上源代码是需要根据具
6、体的硬件修改的,只是TQ2440的配套光盘中给的2.6.30.4内核源代码已经修改好了。)fhfh:/kernel/linux-2.6.30.4$make clean (清除以前的旧数据)fhfh:/kernel/linux-2.6.30.4$make mrproper (清理以前编译时留下的临时文件)8内核源代码的修改 1.修改根目录下的修改根目录下的Makefile文件文件 Linux内核源码目录下的Makefile文件控制内核的编译,虽然我们在x86平台上进行编译,但是我们的目标平台是ARM,故必须进行交叉编译,将编译器改为arm-linux-,处理器的架构改为arm。tq2440的配套
7、光盘中给的2.6.30.4内核源代码中的命令:vi Makefile修改:(193行)ARCH=arm (194行)CROSS_COMPILE=arm-linux-原因:指明体系结构为arm,采用的交叉编译器为arm-linux-,一定要改完Makefile文件再执行make menuconfig,否则,默认的配置平台就是针对x86架构的PC普通电脑。92.修改平台输入时钟修改平台输入时钟命令:fhfh:/kernel/linux-2.6.30.4$vi arch/arm/mach-s3c2440/mach-smdk2440.c修改:(163行)smdk2440_map_io()中的s3c24
8、xx_init_clocks(16934400)修为 s3c24xx_init_clocks(12000000)原因:TQ2440开发板使用的是12MHz的外部时钟。3.修改机器代码修改机器代码命令:fhfh:/kernel/linux-2.6.30.4$vi arch/arm/tools/mach-types修改:(379行)s3c2440这一行最后的数字改为168原因:在内核文件arch/arm/mach-s3c2440/mach-smdk2440.c中的 MACHINE_START(S3C2440,”SMDK2440”)中要使用该机器码,同时它还应该与uboot中的机器码一致,因为ubo
9、ot源码中为168,所以要改成与uboot一致;104.修改修改common-smdk.c文件,加入文件,加入NAND FLASH的分区信息的分区信息命令:fhfh:/kernel/linux-2.6.30.4$vi arch/arm/plat-s3c24xx/common-smdk.c1)修改内容如下:(109行开始)static struct mtd_partition smdk_default_nand_part=0=.name =uboot,.offset=0 x00000000,.size =0 x00040000,1=.name =kernel,.offset=0 x0020000
10、0,.size=0 x00300000,2=.name =yaffs2,.offset=0 x00500000,.size =MTDPART_SIZ_FULL ;即将NAND flash分为3个分区,名称分别为uboot,kernel和yaffs2,偏移量分别为0,2M和5M,大小分别为256kb,3M和251M(MTDPART_SIZ_FULL就是剩余的全部空间),注 意:大小必须为128KB的整数倍,这是和uboot相关的。11 2)然后,修改同文件的下面代码(140行)static struct s3c2410_platform_nand smdk_nand_info=.tacls =1
11、0,.twrph0 =25,.twrph1 =10,.nr_sets=ARRAY_SIZE(smdk_nand_sets),.sets =smdk_nand_sets,;其中修改的值由NAND flash芯片手册查询得到的,简单的说,这些设置就是要按照NAND FLASH芯片的读写时序而已。12 3)修改s3c2410.c文件fhfh:/kernel/linux-2.6.30.4$vi drivers/mtd/nand/s3c2410.c最后,修改drivers/mtd/nand/s3c2410.c中752行s3c2410_nand_init_chip函数的语句改为(752行)chip-ecc
12、.mode =NAND_ECC_NONE;(原来为NAND_ECC_SOFT)这里不采用NAND flash的软件ECC校验码,因为在初始化的时候,uboot中有校验码,然后在后面yaffs2文件系统内核移植的时候,要选上采用S3C2440硬件校验码。13添加内核对添加内核对yaffs2的支持的支持 YAFFS(Yet Another Flash File System)是专门为NAND Flash存储器设计的嵌入式文件系统,遵循 GPL(General Public License)协议。在移植前,首先要为内核添加yaffs2文件系统的支持,首先下载yaffs2文件系统的补丁,可到官方下载页
13、下载,但是现在都用git工具下载了。1)需要使用git工具,如果没有安装,请先输入sudo apt-get install git2)下载yaffs2补丁fhfh:/kernel$git clone git:/www.aleph1.co.uk/yaffs2 Cloning into yaffs2.remote:Counting objects:6875,done.remote:Compressing objects:100%(4105/4105),done.remote:Total 6875(delta 5452),reused 3478(delta 2700)Receiving object
14、s:100%(6875/6875),3.40 MiB|541 KiB/s,done.Resolving deltas:100%(5452/5452),done.fhfh:/kernel$ls linux-2.6.30.4 linux-2.6.30.4.tar.bz2.sign yaffs2143)给2.6.30.4内核打上yaffs2的补丁,先进入yaffs2目录,fhfh:/kernel$cd yaffs2输入下面命令:fhfh:/kernel/yaffs2$./patch-ker.sh c m/home/fh/kernel/linux-2.6.30.4/Updating/home/fh/k
15、ernel/linux-2.6.30.4/fs/KconfigUpdating/home/fh/kernel/linux-2.6.30.4/fs/Makefile再进入内核根目录的fs目录,就可以看到一个yaffs2目录,说明已经为内核打上了支持yaffs2的补丁。注意:以后的操作都是在内核源代码的根目录下执行的。156)修改看门狗驱动drivers/watchdog/s3c2410_wdt.c 程序修改如下加粗部分(49行)#define CONFIG_S3C2410_WATCHDOG_ATBOOT (1)/启动看门狗,原来是(0)(50行)#define CONFIG_S3C2410_WA
16、TCHDOG_DEFAULT_TIME (15)/设置时间默认15秒没喂狗,CPU就重启(55行)static int soft_noboot=0;(56行)static int debug=0;167.打补丁_gnu_mcount_nc_patch,解决EABI编译器与arm s3c2440处理器编译错误有兴趣的读者请参看以下网址,http:/sourceware.org/ml/libc-ports/2008-04/msg00009.html_gnu_mcount_nc_patch.patch.gz脚本见配书光盘首先将_gnu_mcount_nc_patch.patch.gz脚本拷贝到内核的
17、根目录下fhfh:/my_experiment/5$cp _gnu_mcount_nc_patch.patch.gz linux-2.6.30.4/fhfh:/my_experiment/5/linux-2.6.30.4$gunzip-dc _gnu_mcount_nc_patch.patch.gz|patch-p1(注意:_gnu脚本最前面是两个下划线;-p1 中的最后一个是数字1)patching file arch/arm/include/asm/ftrace.hpatching file arch/arm/kernel/armksyms.cpatching file arch/arm/
18、kernel/entry-common.S178.修改与网卡相关的两个文件1)修改drivers/net/dm9000.c网卡驱动文件 在原文件39行#include 之后,但在#include dm9000.h之前,加入以下加粗部分:#if defined(CONFIG_ARCH_S3C2410)#include#endif加入的内容后,在文件的1192行 u32 id_val 之后,但在/*Init network device*/之前,加入以下加粗部分:#if defined(CONFIG_ARCH_S3C2410)unsigned int oldval_bwscon=*(volatil
19、e unsigned int*)S3C2410_BWSCON;unsigned int oldval_bankcon4=*(volatile unsigned int*)S3C2410_BANKCON4;#endif18 在1208行 dev_dbg(&pdev-dev,dm9000_probe()n);之后但在/*setup board info structure*/之前,加入以下加粗部分:#if defined(CONFIG_ARCH_S3C2410)*(volatile unsigned int*)S3C2410_BWSCON)=(oldval_bwscon&(3mii.mdio_wr
20、ite =dm9000_phy_write;之后,但在 mac_src=eeprom;之前,加入以下加粗部分:#if defined(CONFIG_ARCH_S3C2410)printk(Now use the default MAC address:10:23:45:67:89:abn);mac_src=EmbedSky;ndev-dev_addr0=0 x10;ndev-dev_addr1=0 x23;ndev-dev_addr2=0 x45;ndev-dev_addr3=0 x67;ndev-dev_addr4=0 x89;ndev-dev_addr5=0 xab;#else20 在14
21、10行 set using ifconfign,ndev-name);这一行之后,但在 platform_set_drvdata(pdev,ndev);这一行之前,加入以下加粗部分:#endif 在1424行out:之后,但在dev_err(db-dev,not found(%d).n,ret);之前加入以下加粗部分:#if defined(CONFIG_ARCH_S3C2410)*(volatile unsigned int*)S3C2410_BWSCON =oldval_bwscon;*(volatile unsigned int*)S3C2410_BANKCON4=oldval_bank
22、con4;#endif212)编辑arch/arm/mach-s3c2440/mach-smdk2440.c文件加入dm9000的网卡信息 在第48行#include 之后,但在static struct map_desc smdk2440_iodesc _initdata=之前,加入以下加粗部分:#include 在/.lpcsel=(0 xCE6)&7)|1/proc/sys/kernel/hotplug /用mdev来处理内核的热插拔事件。mdev-s /mdev 利用mdev.conf配置文件为插入的设备在/dev下创建设备节点文件。TQ2440_wdg&/执行看门狗应用程序,不让CP
23、U重启ifconfig lo 127.0.0.1 /配置回路为127.0.0.1ifconfig eth0 192.168.1.6 netmask 255.255.255.0 up /配置网卡IProute add default gw 192.168.1.1 /配置网卡的路由/bin/hostname-F/etc/sysconfig/HOSTNAME /设置主机名 修改权限:chmod 777 etc/init.d/rcS368.创建etc/sysconfig/HOSTNAME文件fhfh:/busybox/busybox-1.19.4/_install$mkdir etc/sysconfi
24、gfhfh:/busybox/busybox-1.19.4/_install$vi etc/sysconfig/HOSTNAME该文件中的内容只有如下一行:TQ2440 37创建etc/fstab文件fhfh:/busybox/busybox-1.19.4/_install$vi etc/fstab#device mount-point type options dump fsck orderproc /proc proc defaults 0 0tmpfs /tmp tmpfs defaults 0 0sysfs /sys sysfs defaults 0 0tmpfs /dev tmpfs
25、 defaults 0 0var /dev tmpfs defaults 0 0ramfs /dev ramfs defaults 0 03810.创建 etc/mdev.conf文件vi etc/mdev.confsda-z*0-9 0:0 0660(mount-t vfat-o iocharset=utf8/dev/$MDEV/mnt/udisk)sda-z*0-9 0:0 0660*(umount/mnt/udisk)创建U盘的挂接点mkdir mnt/udisk11.创建etc/profile文件 Shell启动过程中会根据文件etc/profile配置登陆环境,profile文件是终
26、端登录之后首先运行的脚本,etc/profile配置的实例如下:fhfh:/busybox/busybox-1.19.4/_install$vi etc/profile export set HOME=/rootUSER=id-unLOGNAME=$USERPS1=uh W#PATH=$PATHHOSTNAME=/bin/hostnameexport USER LOGNAME PS1 PATH3912.创建 etc/resolv.conf文件fhfh:/busybox/busybox-1.19.4/_install$vi etc/resolv.conf nameserver 202.96.12
27、8.166nameserver 192.168.1.1/我的路由器地址4013.创建/dev目录下所需要的节点文件 目录下建立节点文件/dev/console(终端),/dev/null(内核“黑洞”)在linux内核源码文件init/main.c中有打开设备文件dev/console的操作如下:static noinline int init_post(void)_releases(kernel_lock)if(sys_open(const char _user*)/dev/console,O_RDWR,0)0)printk(KERN_WARNING Warning:unable to op
28、en an initial console.n);内核启动执行到这里时,mdev还没有构建dev目录,如果没有创建设备文件dev/console就将会打印警告Warning:unable to open an initial console。在内核启动的过程中要将产生的一些垃圾信息丢弃就需要空设备dev/null。sudo mknod-m 660 dev/console c 5 1sudo mknod-m 660 dev/null c 1 3411.编写看门狗应用程序TQ2440_wdg.cfhfh:/busybox/busybox-1.19.4/_install$vi TQ2440_wdg.
29、cTQ2440_wdg.c的完整源代码如下:#include#include#include#include#include#include#include#include int main(int argc,char*argv)int fd=0;fd=open(/dev/watchdog,O_RDONLY);if(fd 0)perror(cannot open watchdog device file/dev/watchdog);return-1;for(;)ioctl(fd,WDIOC_KEEPALIVE);sleep(3);/每隔3秒钟喂狗一次,不让看门狗重启CPU close(fd);
30、return 0;422.交叉编译看门狗应用程序fhfh:/busybox/busybox-1.19.4/_install$arm-linux-gcc TQ2440_wdg.c-o TQ2440_wdg3.拷贝可执行的看门狗程序到/bin目录下fhfh:/busybox/busybox-1.19.4/_install$cp TQ2440_wdg bin/4.使用TQ2440配套的yaffs文件系统制作工具将_install目录制作成根文件系统fhfh:/busybox/busybox-1.19.4/_install$cd.fhfh:/busybox/busybox-1.19.4$mkyaffs2image _install root.binfhfh:/busybox/busybox-1.19.4$chmod 755 root.binfhfh:/busybox/busybox-1.19.4$cp root.bin/home/fh/tftpboot/5.通过tftp将root.bin根文件系统烧写进TQ2440开发板的NAND flash中,烧写过程参考第一章,记得先将启动开关打到NOR.43将启动开关拨回到NAND,启动TQ2440开发板就能从串口的minicom中看到如图所示的开发板登录界面,回车就直接进入系统。