Timesy公司在其24,25期的播客里,向大家讲述了怎样把一个Linux内核植入到一个新的硬件中。笔者以支持ARM的硬件产品为例,教给大家如何去选择内核,交互性编译器,以及怎样启用引导程序,识别机器ID及设备映射。


寻找合适的内核(24期开始)
     笔者从kernel.org下载主体版本内核。一般,该版本不包括主板外围设备的驱动,但是如果内核支持大多数或者是研发者仅使用外围设备的一部分,那么他们就会使用这种内核。笔者还会使用最新内核版本,其中包括最新修复的优点,功能更新,安全更新等。一旦选定了内核的大版本,就不会再更换版本。
     如果有太多不支持的硬件,那么建议采用芯片厂家推荐的内核。如果版本过期了,他们会在内核树之外编译驱动代码,以用于特殊的主板。不过最起码的是会在内核页眉文件和厂商提供的主板驱动之间作协调。
其它的内核资源还包括致力于特殊处理器,特征,功能或者是主板的开源工程。最后,开发者可能需要从kernel.org, semi vendor,以及开源站点三个地方来获取资源。


像一个程序员那样去编译内核
     研发者可以使用一些工具把内核和整个系统联接在一起。交互性编辑器就是其中之一,或者是GCC版本,再或者是试用一些交互性工具的方案。由于很多使用者反映越来越难找到针对特定处理器优化的编译器,那些针对各种处理器的商业编译程序越来越收到欢迎。优化对提高硬件设备的性能速度很重要,一般研发者没有必要使用C语言函数库,因为内核是独立的,所以已经包含了printf和printk。


内部架构和功能模块
     一旦内核和工具链准备完毕,研发者就会着手于内核的内部架构。首先是以文件系统模块开始,由于内核中编译的文件系统模块通常占用很多内存,所以需要去掉。一般研发者没有必要修改文件系统,但是他们可以添加一些自己需要的模块。
在内存管理之后,将是支持程序管理和进程管理的功能模块。然后,研发者就要着手于设备控制了,它一般包括网络,特征和模块类型。不过幸运的是,semi的厂商已经对内核支持进行了处理,而且很难被更改。


引导程序(25期开始)
     接下来是植入内核,也就是配置引导程序。它将引导内核进入内存,然后开始运行。如果内核被压缩了,开发者可能会运行一个编译过的解压缩内核,所以引导程序知道内核应该放到哪个位置。一些程序,尤其是Gzip,会占用很多内存,它们会扩展内核,然后重新运行启动编码。在这之后,内核高水平的启动程序如配置设备,这些程序会映射中断处理器,启动内存管理器。


面向不同处理器的机器代码
     下一步是在Linux内核树里找合适的机器代码。在"arch"子目录里,有一些特殊架构和处理器的文件夹,研发者可以重新使用和修改里面的所有代码。其中在ARM文件夹里,用户可以找到MAC子目录,它包括特殊的处理器子目录,内有初始化的机器代码。研发者也可以看一下ARM文件夹里包括的其它子目录,它们主要储存了用于特殊平台的定义和文件页眉。
     内存管理器已经启用了特殊架构的机器代码,所以任何一个地址都是一个有效的物理地址。引导程序留下了一些痕迹以便于开发者观察结果,典型的方法就是在寄存器中留下特定的值。


设备映射
     为了映射设备,开发者可以:为新的驱动修改内核;在性能上修改已经存在的驱动;再或者是采用第三方驱动设备。首先,设备要先注册。每一台设备都有唯一的标识符,内核就用这个来为设备分配特定的连接代码。对于ARM的用户来说,设备ID被存储在单一的文件里,路径为arch/arm/tools/mac。如果涉及到的平台做得很全面,那研发者就不用再来修改设备ID了。不过如果是一个新的主板,那就需要加入新的ID。
     有时,引导程序在注册表里存储着设备ID的值,.所以,当导入时,内核能够检测出ID。内核根据这个值,可以给每一个设备执行不同的初始化程序。开发者也可以用一个二进制内核模块来支持多种设计。


ARM目录架构
      如果用户需要修改、删除、或者是替换文件,那么植入进程就插入了很多内核子目录。例如,在Mm子目录里提供了内存管理的独立代码,主要是用于初始化缓存区内未被内存直接存取的程序。
     内核子目录还包括主初始化代码,这个主要用于内核的启动程序,比如说定义了不同的API的系统代码,还有用于内核初始化的汇编语言。如果研发者想在设备驱动上更深一步的工作,在其它子目录里的部分代码可以满足他们的需求。在"lips"子目录里,包括字符串的处理、内存复制以及输入/输出命令。如果有一些特殊的中断处理或者是调度需要,那么目录里会有一些可以修改的帮助功能。
     研发者可能要准备连接设备的串口。如果研发者想改变主板的串口,那就需要看一下把串口映射到物理存储地址的代码。代码通常分别处在子目录和因不同处理器而异的目录中。


设备检测
     初始化串口之后,Linux内核开始检测设备ID,然后调用一些函数。还有一个设备启动架构,它定义了一些信息,如中断映射的维护、指示等,另外还有设备初使化的进程名称。其实在理论上,研发者可以复制默认的输入/输出映射表,但是如果主板要求改变特殊的引导参数时,那么就需要改变默认的函数。有一个函数调用了一个设备启动代码,它定义了设备和中断如何被调用。对中断的定义通常在include文件(也可以翻成包含文件)以及因处理器而异的irq头文件中。如果开发者想接收一个新的设备或者是改变设备的连接,那他们就专需要重组中断映射表

      开发者应该检查一下内存映射,它用来定义设备如何与处理器交换信息。开发者应该坚持用默认值,除非他们想让系统总线来连接不同的外设,这就需要重新定义内存映射表。总的来说,在从零开始编译代码之前,最好还是着眼于主板提供的信息。

 

为保护翻作者权益,转载本站点内容时请注明来自www.linuxeden.com-Linux伊甸园。如不注明,www.linuxeden.com将根据《互联网著作权行政保护办法》追究其相应法律责任。(责任编辑:bolibei)

本站文章仅代表作者观点,本站仅传递信息,并不表示赞同或反对.转载本站点内容时请注明来自www.linuxeden.com-Linux伊甸园。如不注明,www.linuxeden.com将根据《互联网著作权行政保护办法》追究其相应法律责任。