ARM9嵌入式Linux开发-基于S3C2440的Linux内核移植

概述

所谓移植就是把程序代码从一种运行环境转移到另外一种运行环境,主要是从一种硬件平台转移到另外一种硬件平台上。由于开发板硬件的变化,内核移植是嵌入式linux系统中最常见的一项工作。内核移植主要是修改跟硬件平台相关的代码,添加驱动,一般不涉及linux内核通用的程序。和体系结构相关的代码在arch目录下按照不同的体系结构管理。

移植Linux内核需要熟悉内核的目录结构、启动流程以及裁剪、配置并编译内核的方法,最终将编译好的内核下载到开发板上运行起来。

将Linux运行在S3C2440上,即称为Linux在S3C2440上的移植。移植大致分3个层次:体系结构、处理器和板级移植。

通常所说的移植指的是Linux内核移植,而不是发行版本的移植。

移植前的准备工作:

(1)选择参考板

移植内核的第一步工作就是参考内核已经支持的目标板来移植,就如同使用模板开发程序,Linux内核在不断地更新,支持了各种体系结构的多种目标板,我们很容易从中找到跟自己硬件平台类似的目标板。

选择参考板时,参考版与开发板具是否具有有相同的处理器;参考板与开发板是否具有相同的外围接口电路;Linux内核是否已经支持了参考板,或者至少有参考板的补丁;参考板Linux设备驱动是否正常工作都是我们要考虑的。

因为半导体公司在发布一块新的处理器的时候,一般都会提供参考设计板和Linux BSP包,世界各地的Linux爱好者也在不断地更新Linux内核。通常我都可以找到跟自己硬件平台类似的参考板。

(2)编译测试参考板的Linux内核

  • 为了确信Linux对参考板的支持情况,最好是配置编译Linux内核,然后在目标板上运行一下。
  • 例如参考板是smdk2440,步骤如下:
    • 在顶层Makefile中设置ARCH、CROSS_COMPILE变量
      • ARCH:=arm
      • CROSS_COMPILE:=arm-linux-
    • 使用参考板的缺省内核配置, make arch/arm/configs/s3c2410_defconfig
    • 保存配置以后,执行make编译内核
    • 编译完成后,得到内核映像文件arch/arm/boot/zImage
    • 下载内核映像到目标板中,测试内核的运行情况

(3)分析参考板的BSP代码

  • 如果linux内核已经支持了参考板,下一步工作就是要熟悉参考板的BSP代码:
    • 分析平台相关的部分代码实现;
    • 分析内核编译组织方式;
    • 分析内核启动流程;
    • 分析驱动程序的实现。
  • 熟悉了参考板的这些代码之后,就可以动手修改内核源码

源码目录结构简介

源码获取

本文所使用的Linux内核源码版本是2.6.30.4,大家可以在http://www.kernel.org/pub/linux/kernel/v2.6/下载。     

在http://www.yaffs.net中可以下载YAFFS2的源码。

源码目录简介

Linux内核代码目录基本是安装功能块划分的,每个功能块的代码存放在一个目录下。如mm目录存放内存管理单元相关代码;ipc存放了进程间通信相关的代码;kernel存放进程调度相关代码等。

arch目录下每个平台的代码都采用了与内核代码相同的目录结构。以arch/arm目录为例,该目录下mm、lib、kernel、boot目录与内核目录下对应目录的功能相同。此外,还有一些以字符串mach开头的目录,对应不同处理器特定的代码。从arch目录结构可以看出,平台相关的代码都存放到arch目录下,并且使用与内核目录相同的结构。    

ARM9嵌入式Linux开发-基于S3C2440的Linux内核移植_第1张图片ARM9嵌入式Linux开发-基于S3C2440的Linux内核移植_第2张图片ARM9嵌入式Linux开发-基于S3C2440的Linux内核移植_第3张图片ARM9嵌入式Linux开发-基于S3C2440的Linux内核移植_第4张图片

plat-s3c24xx是专门用来保存SMDK2440开发板相关的程序

plat-s3c是s3c或者s3c24xx平台的通用函数

移植步骤

选择内核版本,下载内核源代码

建立交叉编译开发环境

选择参考板并编译测试

内核源码修改

内核配置(make xconfig)和定制

内核编译、下载和调试

其他驱动开发

内核源码修改

Linux2.6版本内核已经对ARM处理器有很好的支持,并且对三星公司的S3C2440提供一定支持。SMDK2440是内核支持的基于S3C2440的开发板。我们仅需修改部分源码就可以很好的支持我们的开发板。本课程所使用的开发板的主要硬件配置如下表:

ARM9嵌入式Linux开发-基于S3C2440的Linux内核移植_第5张图片

Linux2.6版本内核已经支持S3C2440处理器,跟硬件平台相关的程序基本上已经完整了;而S3C2440属于片上系统,处理器芯片具备串口、显示等外围接口的控制器,这样,参考板的设备驱动多数可以直接使用;但是,不同的开发板可以使用不同的Flash、以太网接口芯片、LCD屏等;这就需要根据硬件修改或者开发驱动程序。

1.在内核中增加对ARM的支持.在顶层Makefile中设置ARCH、CROSS_COMPILE变量

ARCH:=arm
CROSS_COMPILE:=arm-linux-

2.修改时钟频率.在“arch/arm/mach-s3c2440/mach-smdk2440.c”文件修改

static void __init smdk2440_map_io(void)
{
	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
	s3c24xx_init_clocks(16934400);
	s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}

3.修改机器ID.在arch/arm/tools/mach-types中修改

machine_is_xxx	   CONFIG_xxxx	MACH_TYPE_xxx	numbe
s3c2440	   ARCH_S3C2440	S3C2440		362

4.禁止Flash ECC校验.我们的内核都是通过U-Boot写到Nand Flash的,U-Boot通过的软件ECC算法产生ECC校验码,这与内核校验的ECC码不一样,内核中的ECC码是由S3C2440中Nand Flash控制器产生的。所以,我们在这里选择禁止内核ECC校验。修改drivers/mtd/nand/s3c2410.c文件:

找到s3c2410_nand_init_chip()函数,在该函数体最后加上一条语句:

chip->ecc.mode = NAND_ECC_NONE;

5.设置Flash分区.修改内核源码“arch/arm/plat-s3c24xx/common-smdk.c”文件,修改名为“smdk_default_nand_part[]”的结构体,该结构体存放的是Nand Flash的分区信息,其中的分区信息要和BootLoader中的分区信息对应,否则可能导致系统无法正常启动和运行。修改如下所示:

static struct mtd_partition smdk_default_nand_part[] = {
	[0] = {
		.name	= "Board U-Boot",
		.size	= 0x00080000,
		.offset	= 0,
	},
	[1] = {
		.name	= "Board kernel",
		.offset = 0x00240000,
		.size	= 0x00200000,
	},
	[2] = {
		.name	= "Board yaffs2",
		.offset = 0x00440000,
		.size	= 0x0fb40000,
	}
};	

6.在内核中增加对yaffs2文件系统的支持.  将下载的源码包导入到虚拟机中的linux环境中,解压得到yaffs2目录,将其和linux-2.6.30.4目录放置在一起,进入yaffs2目录,然后执行

./patch-ker.sh c m ../linux-2.6.30.4

此时,在内核fs目录下,新增“yaffs2”目录,同时fs/目录下面的Makefile文件和Kconfig文件也添加了yaffs2的配置和编译条件。

7.将RTC设备添加到平台设备初始化数组中.在“arch/arm/mach-s3c2440/mach-smdk2440.c”文件中的smdk2440_devices[]中增加&s3c_device_rtc。在内核中已经支持S3C2440的RTC,但是并没有添加到平台设备初始化数组中,所以系统启动时并不会初始化这一部分。

内核配置(make xconfig)和定制

我们使用默认的配置,并做适当的修改:

cd /root/桌面/linux-2.6.30.4
cp arch/arm/configs/s3c2410_defconfig .config
make xconfig

 

你可能感兴趣的:(ARM9嵌入式Linux开发)