armlinux移植文档.docx
《armlinux移植文档.docx》由会员分享,可在线阅读,更多相关《armlinux移植文档.docx(17页珍藏版)》请在冰豆网上搜索。
armlinux移植文档
移植文档
1、嵌入式linux简介
LINUX是一个类似UNIX的操作系统,其代码是完全重新开放的,内核功能强大,实现简洁。
它提供了类似UNIX的编程接口和系统调用,可以方便的将UNIX系统上的应用程序,移植到Linux上运行。
Linux具有一下特点:
1.可移植性:
Linux内核源代码是用C语言编写的,可以运行到各种平台。
2.支持多种处理器体系结构:
Linux内核能够支持的处理器要求是32位处理器,有没有MMU都可以。
没有MMU的处理器只有uClinux支持。
Linux-内核支持的绝大多数都是带MMU的。
3.开放源代码的优势:
Linux内核是开放源代码的,也就是说,用户可以免费获取,修改linux源码。
庞大的linux
社区和内核源代码工程,有很多各种各样的驱动程序和应用程序可以利用。
开发者可以免费得到社区的贡献、支持。
众所周知,Linux在嵌入式系统中的应用已经非常普遍。
为了进一步促进这方面的应用,在Linux中,引入了很多非常有利于嵌入式应用的功能。
这些新功能包括实时性能的增强、更方便的移植性、对大容量内存的支持、支持微控制器和I/O系统的改进等。
2、内核的新特征
1.改进了响应时间在内核以前,要想让Linux获得更好的响应能力,就需要一些特殊的补丁。
通常情况下,需要用户从厂商处购买补丁来改进中断性能和调度反应时间。
如今,内核把这些改进加入到了主流的内核当中,因此无需再对其进行特殊的配置。
2.抢占式内核
Linux内核在一定程度上使用了可抢占的模式。
因此,在一些时效性比较强的
事件中,Linux要比具有更好的响应能力。
当然了,它实际上并不是一个真正的RTOS,但是与以前的内核相比较,“停顿”的感觉要少得多。
3.高效的调度程序
在版本中,进程调度经过重新编写,去掉了以前版本中效率不高的算法。
调度程序
每次不再扫描所有的任务,而是在一个任务变成就绪状态时将其放到一个名为“当前队列”的队列之中。
当进程调度程序运行时,它只选择队列中最有利的任务来执行。
这样,调度就可以在一个恒定的时间里完成。
当任务执行时,它就会得到一个时间段,或在其转到另外一个线程之前得到一段时间的处理器使用权。
当它的时间段用完之后,任务就会被移到另外一个名为“过期”的队列中。
而在该队列中,任务会根据其优先级进行排序。
4.新的同步措施
多进程应用程序有时需要共享一些资源,比如共享内存或设备。
为了避免竞争的出现,
程序员会使用一个名为互斥的功能来确保同一时刻只有一个任务在使用资源。
到目前为止,Linux还是通过一个包含在内核中的系统调用来完成互斥的实现,并由该系统调用来决定一个线程是等待还是继续执行。
但当决定继续执行时,这个耗时的系统调用就不需要了
5.共享内存的改进
嵌入式系统有时也是一个有很多处理器的设备,比如在电信网络或大型存储系统中就是如此。
而不论是均衡或是松散连接的多处理器,一般都是共享内存的。
均衡多进程的设计是所有的处理器都有对内存有均等使用权,而限制使用内存的决定性因素是进程的效率。
为多程序提供了一种不同的途径,即所谓的NUMA(NonUniformMemoryAccess)。
这种方法中,内存和处理器是相互连接的,但是对于每一个处理器,一些内存是“关闭”的,而有的内存则是“更远”的。
这就意味着当内存竞争出现时,“更近”的处理器对就近的内存有更高的使用权。
6.POSIX线程、信号和计时器与POSIX线程一起,把POSIX信号和POSIX高精度计时器作为了主流内核的一个组成部分。
POSIX信号比以前Linux版本中使用的Unix模式的信号有了很大的改进。
新的POSIX信号不能被丢失,并且可以携带信息作为参数。
此外,POSIX信号也可以从一个POSIX线程传送至另外一个线程,而不是像Unix信号一样,只能从一个进程至另外一个进程。
嵌入式系统通常要求硬件能够在固定的时间安排下来运行任务。
POSIX计时器可以轻松地让任何一个任务都可以周期性地得到预定安排的时间。
计时器的时钟可以达到很高的精度,从而可以让软件工程师更加精确地控制任务的调度。
7.支持通用设计
嵌入式世界里的硬件设计通常都要经过定制,以满足特定的应用程序。
因此,设计人员经常需要使用原始的方式来解决设计上的问题。
比如,为特定目的制造的主板可能使用不同的IRQ管理器而不是使用类似的设计。
在内核中,就引入了一个名为子框架的概念。
在新的定义中,各组件被清晰地分开,并且可以独立进行更改或替换,而不会对其它的组件或软件包造成影响,或者影响非常小。
8.设备、总线和I/O现在Linux正在变成行业用户的第一选择。
内核包含了ALSA(AdvancedLinuxSoundArchitecture),该体系结构可以安全地使用USB和MIDI设备。
通过使用ALSA,系统可以同时播放和记录音频。
用于支持视频的Video4Linux系统,在中也焕然一新。
虽然其不能向后兼容,但却可用于最新的广播、电视、数码相机和其它的多媒体。
Linux使用的是USB,它要比一般的USB快40倍。
可以预见,在不久的将来,高速设备将非常普及,而在对USB支持方面,Linux可以说是一个先行者。
9.支持64位处理器和微控制器
使用内核,对于那些需要大量内存的嵌入式Linux开发人员就可以选择64位的处理
器。
也提供了对微处理控制器的支持。
3、linux内核源代码
由于linux内核版本不断升级更新,所以最好下载新版本的内核源码。
Linux官方发布的内核版本可以从以下网站获取:
获取linux内核源码之后,就可以仔细分析内核源码了。
Linux内核源代码非常庞大,随
着版本的发展不断增加新的内容。
初次接触linux内核,可以仔细阅读顶层目录的readme,它是linux内核的概述和编译命令说明。
内核源码的顶层目录下有许多子目录,分别存放内核子系统的各个源文件。
目录说明如下:
Linuxkernel的目录内容
Arch体系结构相关的代码
Drivers各种设备驱动程序
Fs文件系统
Include内核头文件
InitLinux初始化代码
Ipc进程间通讯的代码
KernelLinux内核核心代码
Lib各种库子程序
Mm内存管理代码
Net网络支持代码,主要是网络协议
Sound声音驱动的支持
Scripts使用的脚本
Usr用户的代码
4、交叉工具链介绍
交叉编译就是在一个平台上生成可以在另一个平台上执行的代码。
注意这里的平台,实际上包含两个概念:
体系结构(Architecture)、操作系统(OperatingSystem)。
同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。
举例来说,我们常说的x86Linux平台实际上是Intelx86体系结构和Linuxforx86操作系统的统称;而x86WinNT平台实际上是Intelx86体系结构和WindowsNTforx86操作系统的简称。
就本书所涉及到的目标硬件S3C2410而言,之所以使用交叉编译是因为在该硬件上无法安装我们所需的编译器,只好借助于宿主机,在宿主机上对即将运行在目标机上的应用程序进行编译,生成可在目标机上运行的代码格式。
在这里介绍在嵌入式系统开发中用得最多的GNU开发工具。
GNU交叉工具链,包括C编译器GCC,C++编译器G++,汇编器AS,链接器LD,二进制转换工具(OBJCOPY,OBJDUMP),调试工具(GDB,GDBSERVER,KGDB)和基于不同硬件平台的开发库。
在GNUGCC支持下用户可以使用流行的C/C++语言开发应用程序,满足生成高效率运行代码、易掌握的编程语言的用户需求。
这些工具都是按GPL版权声明发布,任何人可以从网上获取全部的源代码,无需使用任何费用。
关于GNU和公共许可证协议的详细资料,读者可以参看GNU网站的介绍,
。
运行于Linux操作系统下的自由软件GNUgcc编译器,不仅可以编译Linux操作系统下运行的应用程序,还可以编译Linux内核本身,甚至可以作交叉编译,编译运行于其它CPU上的程序。
在这里我们用的是arm-linux-工具链。
GCC交叉工具链的版本匹配是个大麻烦,版本的GCC工具链曾经统治过内核时代,它表现得极为稳定。
现在GCC-版本已经过时了,内核要求更高的工具链版本支持。
内核最后使用以上版本。
5、步骤
5.1、搭建嵌入式linux开发环境
嵌入linux系统在开发阶段,一般采用的是开发机和目标板的开发模式,在开发机上安
装交叉工具链,配置TFTP,NFS等的服务,在目标板上通过TFTP下载文件,通过NFS挂载跟文
件系统。
1.配置开发机(PC)的环境。
安装并启动TFTP服务
:
TFTP是简单的文件传输协议,适合目标板的bootloader使用。
在配置TFTP服务之前必须安装TFTP软件包,我们完整安装suseLinux后系统会自动安装这些软件包。
在这里我们把kernel/目录下的解压到当前目录。
使用命令:
hbuser@hblinux:
~/yizhi/kernel>tar-xjvf进入到解压后的目录:
hbuser@hblinux:
~/yizhi/kernel>cd
执行下列命令:
hbuser@hblinux:
~/yizhi/kernel/>./configure
hbuser@hblinux:
~/yizhi/kernel/>make
hbuser@hblinux:
~/yizhi/kernel/>makeinstall
即会安装tftp服务器
创建tftp服务目录
hbuser@hblinux:
~>mkdir/home/hbuser/tftp
手动修改TFTP配置文件:
Øsudovi/etc/tftp
将“isable=yes”选项改为“disable=no”,如下:
servicetftp
{
disable=no
socket_type=dgram
protocol=udp
wait=yes
user=root
server=/usr/sbin/
server_args=-s/home/hbuser/tftp
}
保存退出。
打开suse的控制面板:
yaST到networkservices网络服务点选TFTPServer
Continue继续初始化tftp——》skip跳过
初始化后启动tftp服务,是防火墙允许通过:
如下图操作!
然后finish完成!
通过以下命令启动tftp服务:
>sudo/etc/xinetdrestart
因为tftp是守护进程:
所以不能用
>psaux|grep–R“tftp”组合命令来检查,只能在触发tftp服务后才能检查到!
安装minicom串口工具(类似于windwos的超级终端)
关掉虚拟机下的linux不是暂停!
添加虚拟机的串口设备,注意添加的设备是com1,打开windows设备管理器,把串口驱动删除,重新搜索硬件安装驱动!
启动虚拟机下的linux即可!
解压kernel目录下的minicom-2[1].tar-zxvfminicom-2\[1\].进入到解压目录:
hbuser@hblinux:
~/yizhi/kernel>cd
hbuser@hblinux:
~/yizhi/kernel/>./configure
hbuser@hblinux:
~/yizhi/kernel/>make
hbuser@hblinux:
~/yizhi/kernel/>sudomakeinstall
root'spassword:
输入密码安装!
安装后插好串口线,打开开发板电源
输入启动命令启动minicom:
hbuser@hblinux:
~/yizhi/kernel/>sudominicom–s
即可启动minicom,配置minicom如下图:
(上下键选择)
lqqqqq[configuration]qqqqqqk
xFilenamesandpathsx
xFiletransferprotocolsx
xSerialportsetupx
xModemanddialingx
xScreenandkeyboardx
xSavesetupasdflx
xSavesetupas..x
xExitx
xExitfromMinicomx
mqqqqqqqqqqqqqqqqqqqqqqqqqqj
回车:
出现下图:
lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
xA-SerialDevice:
/dev/ttyS1x
xB-LockfileLocation:
/var/lockx
xC-CallinProgram:
xD-CalloutProgram:
xE-Bps/Par/Bits:
1152008N1
xF-HardwareFlowControl:
Yes
xG-SoftwareFlowControl:
No
xChangewhichsetting?
Mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
选A更改:
设备为:
/dev/ttyS0回车
选F把硬件加速流设置成“no”回车
设置之后的结果如下图:
lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
xA-SerialDevice:
/dev/ttyS0
xB-LockfileLocation:
/var/lock
xC-CallinProgram:
xD-CalloutProgram:
xE-Bps/Par/Bits:
1152008N1
xF-HardwareFlowControl:
No
xG-SoftwareFlowControl:
No
xChangewhichsetting?
Mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
回车!
保存
lqqqqq[configuration]qqqqqqk
xFilenamesandpathsx
xFiletransferprotocolsx
xSerialportsetupx
xModemanddialingx
xScreenandkeyboardx
xSavesetupasdflx
xSavesetupas..x
xExitx
xExitfromMinicomx
mqqqqqqqqqqqqqqqqqqqqqqqqqqj
回车
lqqqqq[configuration]qqqqqqk
xFilenamesandpathsx
xFiletransferprotocolsx
xSerialportsetupx
xModemanddialingx
xScreenandkeyboardx
xSavesetupasdflx
xSavesetupas..x
xExitx
xExitfromMinicomx
mqqqqqqqqqqqqqqqqqqqqqqqqqqj
回车,便可退出设置!
出现下图:
(uboot的启动信息)
安装ncurses库(支持图形编译):
解压kernel目录下的:
tar-zxvf进入到目录:
buser@hblinux:
~/yizhi/kernel>cd
hbuser@hblinux:
~/yizhi/kernel/>./configure
hbuser@hblinux:
~/yizhi/kernel/>sudomakeinstall
即可安装:
ncurses库。
安装交叉编译工具链:
如果没有安装交叉编译工具,可以按照如下步骤安装:
安装GCC交叉工具链:
一般我们在开发嵌入式linux过程中,会用到不同的交叉工具链,
我们这里安装版本的工具链,步骤如下:
#mkdir/usr/local/arm;如果目录存在,就不需要建立
将kernel目录下的工具链拷贝到该目录
解压它:
#tarjxvf然后,在需要使用交叉编译是,只要在终端输入如下命令:
#exportPATH=/usr/local/arm/版本/bin:
$PATH
在需要更改不同版本的工具链时,重新启动一个终端,然后再一次输入上面的命令即可。
2、移植到gec2410开发板
内核已经支持S3C24x0处理器的多种硬件板,这里我们用开发板提供的内核为例,实现内核的移植。
步骤:
(1)准备工作
(2)修改顶层Makefile
(3)修改内核源码
(4)配置编译内核
(5)下载到开发板上运行
2.1、准备工作
建立工作目录,下载源码,安装交叉工具链,步骤如下。
>mkdir/home/hbuser/build_kernel
将提供的kernel/拷贝到新建目录下解压
#tarjxvfPATH=/usr/local/arm/、修改顶层Makefile
修改内核目录树根下的的Makefile,指明体系结构是arm,交叉编译工具是arm-linux-;
>cd/home/hbuser/build_kernel/Makefile
找到ARCH和CROSS_COMPILE,修改
ARCH:
=arm
CROSS_COMPILE:
=/usr/local/arm/保存退出。
2.3、修改内核源码
这里注意,如果要用u-boot来引导linux内核,则需要修改内核源码;
(1)修改include/asm-arm/arch-s3c2410/文件,指定输入为串口0;
#viinclude/asm-arm/arch-s3c2410/
将第30行的:
“defineuart_base(S3C2410_PA_UART+0x4000)”改成“defineuart_base(S3C2410_PA_UART)”
(2)禁止内核的FlashECC校验
如果内核和根文件系统的烧写是通过u-boot的“nandwrite”命令来写到NandFlash
的,那么就要在内核源码的nand驱动中禁止的FlashECC校验。
这是因为u-boot通过的软件ECC算法产生ECC校验码,这与内核校验的ECC码不一样,内核中的ECC码是由S3C2410中NandFlash控制器产生的.所以,我们要禁止内核ECC校验。
(此步我们不需要做!
)
2.4、配置内核
>cp.config
注意:
文件是开发板提供的默认内核配置文件,我们这里首先把内核配置成默认配置,在此基础上用makemenuconfig进一步配置;
>makemenuconfig
出现如下配置菜单
在基础上,我们可以选择自己的配置选项,定制内核;(我们可以看看它的一些选项,了解配置选项)为了保证配置的正确性暂时不要修改!
保存退出,产生.config文件.
编译内核
>make
编译结束后,生成arch/arm/boot/zImage映象文件,这就是内核的映象文件。
2.5下载内核镜像到开发板运行
(1)连接好PC机与开发板,连接好串口线,网线,电源线,lcd屏。
(2)烧写u-boot到开发板中,配置好并启动minicom,如下:
>sudominicom–s
选择“Serialportsetup”选项,进一步设置,如前面minicom设置
保存设置,启动开发板,开发板会打印出u-boot的启动信息。
(3)拷贝内核映象文件到/tftproot目录,并启动TFTP服务;
>cp/home/hbuser/build_kernel/linux/arch/arm/boot/zImage/tftproot
>/etc/xinetdrestart
(4)设置开发板u-boot的环境变量;
在minicom中输入如下命令,设置uboot的serverip,ipaddr环境变量;
#setenvserverip.
UncompressingLinux.........................................................................done,bootingthekernel.
Linuxversion(gccversion#5TueSep25
15:
00:
04CST2007
CPU:
ARM920Tid(wb)[]revision0(ARMv4T)
CPU:
DVIVTwrite-backcache
CPU:
Icache:
16384bytes,associativity64,32bytelines,8sets
CPU:
Dcache:
16384bytes,associativity64,32bytelines,8sets
Machine:
SMDK2410
ATAG_INITRDisdeprecated;pleaseupdateyourbootloader.
Memorypolicy:
ECCdisabled,Datacachewriteback
S3C2410:
coreMHz,memoryMHz,peripheralMHz
Built1zonelists
Kernelcommandline:
root=/dev/mtdblock2load_ramdisk=0init=/linuxrcconsole=ttyS0,115200
devfs=mountdisplay=shp240
……
可以看到,内核已经在开发板上运行起来,但是在启动的最后停止了,原因是内核启动的第一个进程要加载根文件系统,但此时内存中并没有文件系统所以启动失败。
2.6烧写内核映象zImage和根文件系统;
重新启动开发板,进入u-boot的提示符下;
然后使用u-boot的命令来烧写,步骤如下;
(1)烧写内核映象zImage
#tftp0xzImage//通过tftp下载内核映象
#nanderase0x400000x1c0000//擦除内核分区
#nandwrite0x0x400000x1c0000//把下载的内核映象文件烧写到内核分区
(2)烧写根文件系统
提供的kernel目录下的文件拷贝到linux的/tftpboot目录下;
#tftp0x
#nanderase0x20