第六章 Linux移植.docx
《第六章 Linux移植.docx》由会员分享,可在线阅读,更多相关《第六章 Linux移植.docx(40页珍藏版)》请在冰豆网上搜索。
第六章Linux移植
第六章Linux移植
一、解压Linux内核源代码
#cd/work/linux-2.6.20.tar.bz2
#tar–jxflinux-2.6.20.tar.bz2
等待几分钟,源文件解压完毕。
二、修改Makefile文件
在/work/linux-2.6.20目录下找到Makefile文件,把(约在第185行)
ARCH?
=$(SUBARCH)
CROSS_COMPILE?
=
修改为
ARCH?
=arm
CROSS_COMPILE?
=/usr/local/arm/3.4.1/bin/arm-linux-
说明:
ARCH?
=arm
这一句指定编译内核的处理器类型。
CROSS_COMPILE?
=/usr/local/arm/3.4.1/bin/arm-linux-
这一句指定交叉编译工具所在位置。
三、配置Linux内核
1、配置默认内核
#cd/work/linux-2.6.20
#makes3c2410_defconfig
#makezImage
等待N长时间后,应该可以看到如下信息:
Kernel:
arch/arm/boot/zImageisready
说明我们所配置的基本内核已经成功编译通过。
说明
·如果能够正确编译通过,仅说明交叉工具安装设置正确。
如果编译没有通过,仔细检查前面的步骤,直到编译成功为止。
还不行?
一百遍啊一百遍!
·为什么要用makezImage呢?
因为实际中发现,直接makeuImage出来的镜像文件地址有错误,导致在UBoot中无法正确引导。
是我的个人原因还是所有的源代码都一样,有待考证。
2、测试默认内核
编译成功了,是不是代表就一定正确呢?
不见得!
不相信?
那么我们就来测试一下。
把编译好的内核发布到TFTP上
#cp/work/linux-2.6.20/arch/arm/boot/zImage/tftpboot
启动开发板,在UBoot提示符下
[CNOS2410]>tftp0x30008000zImage
[CNOS2410]>go0x30008000
##Startingapplicationat0x30008000...
UncompressingLinux.............................................................
...................................done,bootingthekernel.
Error:
unrecognized/unsupportedmachineID(r1=0x33e07a90).
Availablemachinesupport:
ID(hex)NAME
中间省略
Pleasecheckyourkernelconfigand/orbootloader.
呵呵,出错了。
为什么呢?
Error:
unrecognized/unsupportedmachineID
这一句是说内核不支持UBoot传递给它的机器ID。
那么怎么解决呢?
Pleasecheckyourkernelconfigand/orbootloader.
请检查你的内核配置和(或)UBoot。
UBoot我们已经移植好,能不动它就尽量不动它。
那么就修改内核吧。
反正还没有改过呢。
3、修改内核
怎么改?
对内核不熟悉,不要紧。
网络上高手一大把。
要学会使用搜索引擎。
XX一下,你就知道!
果然,发现了高手的踪影。
解决方法如下:
在/work/linux-2.6.20/arch/arm/kernel/head.S中,在(约第74行)
__INIT
.typestext,%function
ENTRY(stext)
后添加如下语句
/*********修改MACHINEID*********/
movr0,#0
movr1,#0xc1
ldrr2,=0x30000100
/*********修改MACHINEID*********/
原理嘛,就是把SMDK2410的MACHINEID直接赋值为000000c1。
重新编译内核,再来测试,相信自己,一定能行。
#makezImage
#cp/work/linux-2.6.20/arch/arm/boot/zImage/tftpboot
重新启动开发板
[CNOS2410]>tftp0x30008000zImage
[CNOS2410]>go0x30008000
##Startingapplicationat0x30008000...
UncompressingLinux.............................................................
...................................done,bootingthekernel.
Linuxversion2.6.20(root@localhost.localdomain)(gccversion3.4.1)#2MonApr
2719:
01:
21CST2009
CPU:
ARM920T[41129200]revision0(ARMv4T),cr=00007177
Machine:
SMDK2410
Warning:
badconfigurationpage,tryingtocontinue
Memorypolicy:
ECCdisabled,Datacachewriteback
CPUS3C2410A(id0x32410002)
S3C2410:
core202.800MHz,memory101.400MHz,peripheral50.700MHz
S3C24XXClocks,(c)2004SimtecElectronics
CLOCK:
Slowmode(1.500MHz),fast,MPLLon,UPLLon
CPU0:
DVIVTwrite-backcache
CPU0:
Icache:
16384bytes,associativity64,32bytelines,8sets
CPU0:
Dcache:
16384bytes,associativity64,32bytelines,8sets
Built1zonelists.Totalpages:
4064
Kernelcommandline:
root=/dev/hda1roinit=/bin/bashconsole=ttySAC0
irq:
clearingsubpendingstatus00000002
PIDhashtableentries:
64(order:
6,256bytes)
timertcon=00500000,tcnta509,tcfg00000200,00000000,usec00001e4c
Console:
colourdummydevice80x30
Dentrycachehashtableentries:
2048(order:
1,8192bytes)
Inode-cachehashtableentries:
1024(order:
0,4096bytes)
Memory:
16MB=16MBtotal
Memory:
13104KBavailable(2692Kcode,283Kdata,120Kinit)
Mount-cachehashtableentries:
512
CPU:
Testingwritebuffercoherency:
ok
中间省略
Root-NFS:
NoNFSserveravailable,givingup.
VFS:
UnabletomountrootfsviaNFS,tryingfloppy.
VFS:
Cannotopenrootdevice"hda1"orunknown-block(2,0)
Pleaseappendacorrect"root="bootoption
Kernelpanic-notsyncing:
VFS:
Unabletomountrootfsonunknown-block(2,0)
稀里哗啦地出来一大堆东西,是不是很激动?
别激动得太早。
这里面到底说的是什么呢?
大概是说内核已经功能启动了。
但是,但是。
告诉你一个不好的消息。
它挂了!
挂了是什么意思?
说得直白一点就是死了。
但为什么死在这里了。
让我们来解剖一下,看看有什么蛛丝马迹。
Root-NFS:
NoNFSserveravailable,givingup.
这句是说,没有NFS服务,放弃。
什么意思呢?
因为我们并没有在UBoot中配置NFS信息。
VFS:
UnabletomountrootfsviaNFS,tryingfloppy.
这句是说,不能通过NFS加载根文件系统,尝试从软盘加载。
当然也不会有结果。
因为根本没软盘。
VFS:
Cannotopenrootdevice"hda1"orunknown-block(2,0)
这句是说不能打开根设备”hda1”。
“hda1“从哪来?
看前面。
Kernelcommandline:
root=/dev/hda1roinit=/bin/bashconsole=ttySAC0
这就是Linux内核启动时的命令行参数,它指定Linux内核从哪加载根文件系统。
Pleaseappendacorrect"root="bootoption
这句是说请增加正确的”root=”启动选项。
Kernelpanic-notsyncing:
VFS:
Unabletomountrootfsonunknown-block(2,0)
这句是说,Linux内核找了N久都找不到根文件系统,疯了。
马上死给你看。
4、设置根文件系统
那么多问题,怎么解决?
找不着头绪?
当不了高明的医生,那就做个庸医吧。
什么招数?
头痛医头,脚痛医脚。
可Linux已经死了!
怎么办。
死马当活马医。
看它为什么死的?
找不到根文件系统。
好办。
那就给它一个吧。
骗骗它,让它死得瞑目。
我们没有根文件系统啊。
不要紧,能骗过它就行。
随便找一个,只要是它能认识的。
你没有?
?
?
?
送你一个。
在哪?
在附件里,K9.img就是了。
怎么给呢?
当然是从boot选项给了。
要重新编译内核?
真是太痛苦了。
不是说UBoot可以传递命令行参数给Linux内核的吗?
有道理。
那就设置UBoot参数吧。
重新启动开发板:
[CNOS2410]>setenvbootargsroot=/dev/ramrwinitrd=0x30500000,4Minit=/linuxrcconsole=ttySAC0,115200mem=64M
[CNOS2410]>saveenv
注意:
这个UBoot命令用于设置传递给Linux内核的参数,必须写成一行,不得换行。
说明:
root=/dev/ramrw
这个参数是说Linux内核从/dev/ram加载根文件系统。
rw表示可读写。
initrd=0x30500000
这个参数是说根文件系统所在的内存位置。
4M表示根文件系统的大小。
init=/linuxrc
这个参数是说Linux启动成功后,最先执行的命令。
console=ttySAC0,115200
这个参数是说输出终端是ttySAC0。
115200表示波特率.
mem=64M
这个参数是指内存的大小。
光给Linux内核说”有根文件系统了”,它会相信吗?
当然相信,可是当它找了N久之后发现你骗它。
照样会死给你看。
还是满足一下它吧。
我们说在0x30500000这里有根文件系统,那么就放在这里吧。
#cp/work/K9.img/tftpboot
重新启动开发板:
[CNOS2410]>tftp0x30500000K9.img
[CNOS2410]>tftp0x30008000zImage
[CNOS2410]>go0x30008000
看看效果!
Root-NFS:
NoNFSserveravailable,givingup.
VFS:
UnabletomountrootfsviaNFS,tryingfloppy.
VFS:
Cannotopenrootdevice"hda1"orunknown-block(2,0)
Pleaseappendacorrect"root="bootoption
Kernelpanic-notsyncing:
VFS:
Unabletomountrootfsonunknown-block(2,0)
晕了,还是挂了。
Linux内核还是找不到根文件系统。
什么原因?
Kernelcommandline:
root=/dev/hda1roinit=/bin/bashconsole=ttySAC0
原来UBoot的bootargs参数并没有传递给Linux内核。
难怪会找不到。
注意:
uImage用bootm命令来引导,这个命令会做许多事情,包括把启动参数拷贝到合适的位置,在把控制权交给内核的时候用theKernel(arg,arg1,arg2);三个参数会放在r0,r1,r2中,分别为0,machinenumber,存放bootargs的地址。
用go命令来引导,只是把pc设为内核入口地址,并不拷贝bootargs,而且只传递两个参数。
原因知道了。
是zImage不支持bootargs变量。
那么用uImage是不是就能解决问题呢?
我们来测试一下。
#mkimage-Aarm-Olinux-Tkernel-Cnone-a30008000-e30008040-nlinux-2.6.20-d/tftpboot/zImage/tftpboot/uImage
说明:
·不使用Linux内核的makeuImage来生成uImage.原因见前述部分。
·mkimage参数:
-A==>setarchitectureto'arch'处理器类型:
arm
-O==>setoperatingsystemto'os'操作系统:
linux
-T==>setimagetypeto'type'镜像类型:
kernel
-C==>setcompressiontype'comp'压缩类型:
none不压缩
-a==>setloadaddressto'addr'(hex)加载地址:
0x30008000
-e==>setentrypointto'ep'(hex)入口地址:
0x30008040
-n==>setimagenameto'name'镜像名称:
linux-2.6.20
-d==>useimagedatafrom'datafile'输入文件名:
/tftpboot/zImage
重新启动开发板:
[CNOS2410]>tftp0x30500000K9.img
[CNOS2410]>tftp0x30008000uImage
[CNOS2410]>bootm0x30008000
注意:
启动zImage用go命令,启动uImage用bootm命令。
看看效果。
##Bootingimageat30008000...
ImageName:
linux-2.6.13
Created:
2009-04-2711:
57:
12UTC
ImageType:
ARMLinuxKernelImage(uncompressed)
DataSize:
1466160Bytes=1.4MB
LoadAddress:
30008000
EntryPoint:
30008040
VerifyingChecksum...OK
XIPKernelImage...OK
Startingkernel...
UncompressingLinux.............................................................
...................................done,bootingthekernel.
Linuxversion2.6.20(root@localhost.localdomain)(gccversion3.4.1)#2MonApr
2719:
01:
21CST2009
CPU:
ARM920T[41129200]revision0(ARMv4T),cr=00007177
Machine:
SMDK2410
Memorypolicy:
ECCdisabled,Datacachewriteback
CPUS3C2410A(id0x32410002)
S3C2410:
core202.800MHz,memory101.400MHz,peripheral50.700MHz
S3C24XXClocks,(c)2004SimtecElectronics
CLOCK:
Slowmode(1.500MHz),fast,MPLLon,UPLLon
CPU0:
DVIVTwrite-backcache
CPU0:
Icache:
16384bytes,associativity64,32bytelines,8sets
CPU0:
Dcache:
16384bytes,associativity64,32bytelines,8sets
Built1zonelists.Totalpages:
16256
Kernelcommandline:
root=/dev/ramrwinitrd=0x30500000,4Mmem=64Minit=/linuxrcconsole=ttySAC0,115200
irq:
clearingsubpendingstatus00000002
PIDhashtableentries:
256(order:
8,1024bytes)
timertcon=00500000,tcnta509,tcfg00000200,00000000,usec00001e4c
Console:
colourdummydevice80x30
Dentrycachehashtableentries:
8192(order:
3,32768bytes)
Inode-cachehashtableentries:
4096(order:
2,16384bytes)
Memory:
64MB=64MBtotal
Memory:
57728KBavailable(2692Kcode,283Kdata,120Kinit)
Mount-cachehashtableentries:
512
CPU:
Testingwritebuffercoherency:
ok
中间省略
RAMDISK:
ext2filesystemfoundatblock0
RAMDISK:
Loading4096KiB[1disk]intoramdisk...done.
VFS:
Mountedroot(ext2filesystem).
Freeinginitmemory:
120K
route:
SIOC[ADD|DEL]RT:
Nosuchprocess
route:
SIOC[ADD|DEL]RT:
Networkisunreachable
#
开心吧!
终于成功了。
Linux活了。
在SHELL下,可以输入命令了:
#ls
binetcliblost+foundprocusr
devhellolinuxrcmntsbin
#./hello
HelloWorld1times!
HelloWorld2times!
HelloWorld3times!
HelloWorld4times!
HelloWorld5times!
HelloWorld6times!
HelloWorld7times!
HelloWorld8times!
#
看起来是好像是没问题了。
根目录下的hello测试程序也可以正常运行。
但是,事情并没有想象中的那么简单。
不相信,PING一下主机:
#ping192.168.1.1
PING192.168.1.1(192.168.1.1):
56databytes
ping:
sendto:
Networkisunreachable
#
网络不可到达?
没设IP?
#ifconfig
#
根本没反应。
网络出问题了!
我们开发板上的网络芯片是DM9000。
看启动信息:
dm9000EthernetDriver
驱动在内核里已经配置了。
是不是UBoot没设置好?
既然如此,那我们就设置好UBoot.
重新启动开发板:
[CNOS2410]>setbootargsroot=/dev/ramrwinitrd=0x30500000,4Mip=192.168.1.40:
1
92.168.1.20:
192.168.1.1:
255.255.255.0:
cnos2410:
eth0:
onmem=64Minit=/linuxrccon
sole=ttySAC0,115200
[CNOS2410]>save
注意:
这个UBoot命令用于设置传递给Linux内核的参数,必须写成一行,不得换行。
说明:
bootargs中关于IP的设置格式:
ip=开发板IP:
主机IP:
网关IP:
子网掩码:
开发板名称:
网卡名称