跳至主要内容

【转】Linux2.6基于嵌入式应用的裁剪

1Linux 2.6内核针对嵌入式开发显著特点
实时可靠性是嵌入式应用较为普遍的要求,尽管Linux 2.6 并不是一个真正的实时操作系统,但其改进的特性能够满足响应需求。Linux 2.6 已经在内核主体中加入了提高中断性能和调度响应时间的改进,其中有三个最显著的改进:采用可抢占内核、更加有效的调度算法以及同步性的提高[4]。在企业服务器以及嵌入式系统应用领域,Linux 2.6 都是一个巨大的进步。在嵌入式领域,Linux 2.6 除了提高其实时性能,系统的移植更加方便,同时添加了新的体系结构和处理器类型――包括对没有硬件控制内存管理方案的 MMU-less系统的支持,可以支持大容量内存模型、微控制器,同时还改善了I/O子系统,增添更多的多媒体应用功能[4]
1.1 可抢占内核

在先前的内核版本中(包括2.4内核)不允许抢占以核心态运行的任务(包括通过系统调用进入内核模式的用户任务),只能等待它们自己主动释放CPU。这样必然导致一些重要任务延时以等待系统调用结束。
一个内核任务可以被抢占,为的是让重要的用户应用程序可以继续运行。这样做最主要的优势是极大地增强系统的用户交互性。
2.6内核并不是真正的RTOS(Real Time Operation System),其在内核代码中插入了抢占点,允许调度程序中止当前进程而调用更高优先级的进程,通过对抢占点的测试避免不合理的系统调用延时。2.6内核在一定程度上是可抢占的,2.4内核具备更好的响应性。但也不是所有的内核代码段都可以被抢占,可以锁定内核代码的关键部分,确保CPU的数据结构和状态始终受到保护而不被抢占。
软件需要满足最终时间限制与虚拟内存请求页面调度之间是相互矛盾的。慢速的页错误处理将会破坏系统的实时响应性,2.6内核可以编译无虚拟内存系统避免这个问题,这是解决问题的关键,但要求软件设计者有足够的内存来保证任务的执行。
1.2 有效的调度程序

2.6版本的 Linux内核使用了由 Ingo Molnar开发的新的调度器算法,称为O(1)算法,如图1所示。它在高负载情况下执行得极其出色,并且当有很多处理器并行时也可以很好地扩展[2]。过去的调度程序需要查找整个ready task队列,并且计算它们的重要性以决定下一步调用的task,需要的时间随task数量而改变。O(1)算法则不再每次扫描所有的任务,task就绪时被放入一个活动队列中,调度程序每次从中调度适合的task,因而每次调度都是一个固定的时间。任务运行时分配一个时间片,当时间片结束,该任务将放弃处理器并根据其优先级转到过期队列中。活动队列中任务全部调度结束后,两个队列指针互换,过期队列成为当前队列,调度程序继续以简单的算法调度当前队列中的任务。这在多处理器的情况更能提高SMP的效率,平衡处理器的负载,避免进程在处理器间的跳跃。
1 O(1)调度算法
1.3 同步原型与共享内存

多进程应用程序需要共享内存和外设资源,为避免竞争采用了互斥的方法保证资源在同一时刻只被一个任务访问。Linux内核用一个系统调用来决定一个线程阻塞或是继续执行来实现互斥,在线程继续执行时,这个费时的系统调用就没有必要了。Linux2.6所支持的Fast User-Space Mutexes 可以从用户空间检测是不是需要阻塞线程,只在需要时执行系统调用终止线程。它同样采用调度优先级来确定将要执行的进程[4]多处理器嵌入式系统各处理器之间需要共享内存,对称多处理技术对内存访问采用同等优先级,在很大程度上限制了系统的可量测性和处理效率。Linux2.6则提供了新的管理方法――NUMA(Non Uniform Memory Access)NUMA根据处理器和内存的拓扑布局,在发生内存竞争时,给予不同处理器不同级别权限以解决内存抢占瓶颈,提高吞吐量。
1.4 POSIX线程及NPTL新的线程模型基于一个1:1的线程模型(一个内核线程对应一个用户线程),包括内核对新的 NPTL(Native POSIX Threading Library)的支持,这是对以前内核线程方法的明显改进。2.6内核同时还提供POSIX signalsPOSIX high-resolution timersPOSIX signals不会丢失,并且可以携带线程间或处理器间的通信信息。嵌入式系统要求系统按时间表执行任务,POSIX timer可以提供1kHz的触发器使这一切变得简单,从而可以有效地控制进度。
1.5 微控制器的支持Linux2.6内核加入了多种微控制器的支持。无MMU的处理器以前只能利用一些改进的分支版本,uClinux,2.6内核已经将其整合进了新的内核中,开始支持多种流行的无MMU微控制器,DragonballColdFireHitachi H8/300Linux在无MMU控制器上仍旧支持多任务处理,但没有内存保护功能。同时也加入了许多流行的控制器的支持,S3C2410等。
1.6 面向应用嵌入式应用有用户定制的特点,硬件设计都针对特定应用开发,这给系统带来对非标准化设计支持的问题(IRQ的管理)。为了更好地实现,可以采用部件化的操作系统。Linux2.6采用的子系统架构将功能模块化,可以定制而对其他部分影响最小。同时Linux2.6提供了多种新技术的支持以实现各种应用开发,Advanced Linux Sound Architecture(ALSA)Video4Linux,对多媒体信息处理更加方便;USB2.0的支持,提供更高速的传输,增加蓝牙无线接口、音频数据链接和面向链接的数据传输L2CAP,满足短距离的无线连接的需要;而且在2.6内核中还可以配置成无输入和显示的纯粹无用户接口系统。
2、应用研究S3C2410开发板上移植嵌入式Linux 2.6.11.7内核系统,应用于构建H.264多媒体系统。
2.1 建立交叉编译环境RedHat9的主机上进行内核移植开发,首先需要建立交叉编译环境。由于2.6内核中采用了一些新的特性和指令,需要采用较新的工具集,采用binutils-2.15gcc-3.4.2glibc-2.2.5linux-2.6.8glibc-linuxthreads-2.2.5来建立交叉编译工具链,建立之后将工具链路径加入系统路径$PATH中。
2.2 内核修改Linux 2.6.11.7内核加入了对S3C2410芯片的支持,不再需要任何补丁文件。修改内核源码中Makefile的交叉编译选项ARCH=arm,CROSS_COMPILE=arm-linux-。针对硬件配置,需要在arch/arm/mach-s3c2410/devs.c或者smdk2410.c中添加FLASH的分区信息s3c_nand_info,如表1
1 NAND FLASH分区表
分区名    起始地址     大
Vivi      0x00000000   0x00020000
Param      0x00020000   0x00010000
Kernel     0x00030000   0x001c0000
Root      0x00200000   0x00200000
Usr       0x00400000   0x03c00000
然后在s3c_device_nand中增加.dev={.platform_data=&s3c_nand_info},arch/arm/mach-s3c2410/mach-smdk2410.c中的__initdata部分增加&s3c_device_nand,使内核在启动时初始化NAND FLASH信息。
2.3 内核编译加载对内核进行适当的配置是一个量体裁衣的过程。由于2.6内核会根据本地系统配置进行初始设置,可以导入内核源码默认s3c2410的配置文件,方便加载内核基本配置,然后再选择所需选项。对MTD配置选择支持MTD设备驱动以及NAND FLASH驱动;选择支持要用到的各类文件系统(DEVFSTMPFSCRAMFSYAFFSEXT2NFS)以及网络设备和协议,本系统加载了网络芯片CS8900以及USB支持;H.264多媒体系统中还需要加载Frame buffer以支持LCD显示功能。使用交叉编译工具编译内核源码后, 会在arch/arm/boot/下生成名为zImage的内核映像,Boot loader的命令提示模式下使用下载命令完成内核加载到开发板的存储设备FLASH中。编译过程(相对以前版本的编译过程,2.6内核编译有所简化):
make mrproper
make menuconfig(字符界面,或者用make xconfig图形界面,但需要Qt库的支持,make gconfig则需要GTK库的支持)
make
make bzImage
2.4 文件系统Linux采用文件系统组织系统中的文件和设备,为设备和用户程序提供统一接口。Linux 支持多种文件系统,本系统使用CRAMFS格式的只读根文件系统,而将FLASH中的USER区使用支持可读写的YA FFS文件系统格式,方便添加自己的应用程序。
在根文件系统中,为保护系统的基本设置不被更改,采用CRAMFS格式。采用DEVFS来实现基本设备的建立挂载,同时使用BusyBox也是一个缩小根文件系统的办法,提供了系统的基本指令;还需要建立一些必备的目录,添加所需配置文件,fstabinittab;还有一个重要的工作就是添加系统应用必备的动态函数库。使用生成工具mkcramfs 将整个根文件目录里的内容制作成映像文件。
mkcramfs rootfs rootfs.ramfs
YAFFS文件系统格式的支持需要将驱动加入到内核代码树下fs/yaffs/,修改内核配置文件,就可以在内核编译中加载对该文件系统的支持。使用mkyaffs工具将NAND FLASH分区格式化为YAFFS分区,mkyaffsimage生成的应用程序镜像烧写进YAFFS分区,在启动时通过写入fstab自动加载YAFFS分区即可。
2.5 网络设备驱动系统中采用CS8900A10M网络芯片,它使用S3C2410nGCS3IRQ_EINT9,相应修改linux/arch/arm/mach-s3c2410/irq.c,并在mach-smdk2410.csmdk2410_iodesc[]中增加{SMDK2410_ETH_IO,S3C2410_CS2, SZ_1M, MT_DEVICE},内核源码中加入芯片的驱动程序drivers/net/arm/cs8900.hcs8900.c,并且配置网络设备驱动的MakefileKconfig文件,加入CS8900A的配置选项,这样可以在内核编译时加载网络设备的驱动。
Linux2.6应用的同时,也要看到其与以前版本内核比较存在的一些问题。在内核的编译时间、内核镜像大小、内核占用RAM空间大小、系统启动时间相对Linux2.4而言都存在不同程度的不足,但在硬件条件日益进步的现今可以接受,而且一部分也是由于功能加强必然带来的。虽然Linux并非一个真正的实时操作系统,2.6内核的改进能够满足大部分的应用需求,所以Linux2.6内核将会在嵌入式系统领域大展身手。
参考文献
1Alessandro Rubini,Jonathan Corbet,魏永明,骆刚,君译.Linux设备驱动[M].北京:中国电力出版社,2004
2Anand K Santhanam. 走向Linux2.6[EB/OL]. Dec. 2003.
http://www-128.ibm.com/deve loperworks/cn/linux/ l-inside/index.html
3S3C2410X 32-Bit RISC Microprocessor User′s Manual[Z]. SAMSUNG Electronics. Revision 1.2
4Brandon White. Linux 2.6: A Breakthrough for Embedded Systems[EB/OL].http://linuxdevices.com/articles/AT7751365763.html Sep.9,2003
5Karim Yaghmour. Building Embedded Linux Systems[M]. O'Reilly. April, 2003

评论

此博客中的热门博文

【转】AMBA、AHB、APB总线简介

AMBA 简介 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大。数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SOC设计中得到了广泛应用。在基于IP复用的SoC设计中,片上总线设计是最关键的问题。为此,业界出现了很多片上总线标准。其中,由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标准片上结构。AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。   AMBA 片上总线        AMBA 2.0 规范包括四个部分:AHB、ASB、APB和Test Methodology。AHB的相互连接采用了传统的带有主模块和从模块的共享总线,接口与互连功能分离,这对芯片上模块之间的互连具有重要意义。AMBA已不仅是一种总线,更是一种带有接口模块的互连体系。下面将简要介绍比较重要的AHB和APB总线。 基于 AMBA 的片上系统        一个典型的基于AMBA总线的系统框图如图3所示。        大多数挂在总线上的模块(包括处理器)只是单一属性的功能模块:主模块或者从模块。主模块是向从模块发出读写操作的模块,如CPU,DSP等;从模块是接受命令并做出反应的模块,如片上的RAM,AHB/APB 桥等。另外,还有一些模块同时具有两种属性,例如直接存储器存取(DMA)在被编程时是从模块,但在系统读传输数据时必须是主模块。如果总线上存在多个主模块,就需要仲裁器来决定如何控制各种主模块对总线的访问。虽然仲裁规范是AMBA总线规范中的一部分,但具体使用的算法由RTL设计工程师决定,其中两个最常用的算法是固定优先级算法和循环制算法。AHB总线上最多可以有16个主模块和任意多个从模块,如果主模块数目大于16,则需再加一层结构(具体参阅ARM公司推出的Multi-layer AHB规范)。APB 桥既是APB总线上唯一的主模块,也是AHB系统总线上的从模块。其主要功能是锁存来自AHB系统总...

【转】GPIO编程模拟I2C入门

ARM编程:ARM普通GPIO口线模拟I2C  请教个问题: 因为需要很多EEPROM进行点对点控制,所以我现在要用ARM的GPIO模拟I2C,管脚方向我设 置的是向外的。我用网上的RW24C08的万能程序修改了一下,先进行两根线的模拟,SDA6, SCL6,但是读出来的数不对。我做了一个简单的实验,模拟SDA6,SCL6输出方波,在示波 器上看到正确方波,也就是说,我的输出控制是没问题的。 哪位大哥能指点一下,是否在接收时管脚方向要设为向内?(不过IOPIN不管什么方向都可 以读出当前状态值的阿) 附修改的RW24C08()程序: #define  SomeNOP() delay(300); /**/ /* *********************************  RW24C08   **************************************** */ /**/ /* ----------------------------------------------------------------------------- ---  调用方式:void I2CInit(void)   函数说明:私有函数,I2C专用 ------------------------------------------------------------------------------- -- */ void  I2CInit( void ) ... {  IO0CLR  =  SCL6;      // 初始状态关闭总线  SomeNOP();  // 延时   I2CStop();  // 确保初始化,此时数据线是高电平 }   /**/ /* ---------------------------------------------------------------------------- ----  调用方式:void I2CSta...

【转】cs8900网卡的移植至基于linux2.6内核的s3c2410平台

cs8900网卡的移植至基于linux2.6内核的s3c2410平台(转) 2008-03-11 20:58 硬件环境:SBC-2410X开发板(CPU:S3C2410X) 内核版本:2.6.11.1 运行环境:Debian2.6.8 交叉编译环境:gcc-3.3.4-glibc-2.3.3 第一部分 网卡CS8900A驱动程序的移植 一、从网上将Linux内核源代码下载到本机上,并将其解压: #tar jxf linux-2.6.11.1.tar.bz2 二、打开内核顶层目录中的Makefile文件,这个文件中需要修改的内容包括以下两个方面。 (1)指定目标平台。 移植前:         ARCH?= $(SUBARCH) 移植后: ARCH            :=arm (2)指定交叉编译器。 移植前: CROSS_COMPILE ?= 移植后: CROSS_COMPILE   :=/opt/crosstool/arm-s3c2410-linux-gnu/gcc-3.3.4-glibc-2.3.3/bin/arm-s3c2410-linux-gnu- 注:这里假设编译器就放在本机的那个目录下。 三、添加驱动程序源代码,这涉及到以下几个方面。(1)、从网上下载了cs8900.c和cs8900.h两个针对2.6.7的内核的驱动程序源代码,将其放在drivers/net/arm/目录下面。 #cp cs8900.c ./drivers/net/arm/ #cp cs8900.h ./drivers/net/arm/ 并在cs8900_probe()函数中,memset (&priv,0,sizeof (cs8900_t));函数之后添加如下两条语句: __raw_writel(0x2211d110,S3C2410_BWSCON); __raw_writel(0x1f7c,S3C2410_BANKCON3); 注:其原因在"第二部分"解释。 (2)、修改drivers/net/arm/目录下的Kconfig文件,在最后添加如...