第 4 章 嵌入式 LINUX 内核移植
4.3 内核移植
4.3.1 内核配置
4.3.1.2 设置 NAND Flash 分区
由于我们的目标板使用的是 64M NAND Flash 作为 Flash 存储器,所以首先我们需要建 立一个 NAND Flash 分区表,该分区表用来定义开发板上 64M 空间划分,以及定义各分区 存放的起始地址以及大小等。该部分的实现在<arch/arm/mach-s3c2410/devs.c>源文件中,故 修改该文件,修改内容如下:
//首先添加相应的头文件
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <asm/arch/nand.h>
……
/*新建 64M 的 Nand Flash 分区表*/
static struct mtd_partition partition_info[]={
{/*1MB*/
name:"bootloader", size:0x00100000, offset:0x0, },
{/*3MB*/
name:"kernel", size:0x00300000, offset:0x00100000,
}, struct s3c2410_nand_set nandset ={
nr_partitions: 4 , //定义分区数 partitions: partition_info , //定义分区表 };
… …
上述代码的作用是建立一个 64M 的 Nand Flash 分区表,将其分为:bootloader(启动程 序),kernel(内核),rootfs(根文件系统)和 user(用户空间)四个分区。其中:name:代 表分区的名称;size:代表分区的大小;offset:代表分区在 Flash 中的起始地址。同时后面 定义 NAND Flash 的分区数据结构。
紧接着要建立内核对 NAND Flash 芯片的支持,同时加入对 NAND Flash 芯片的支持代 码到 NAND Flash 的驱动程序。具体代码实现如下<arch/arm/mach-s3c2410/devs.c>:
//建立 NAND Flash 的芯片支持数据结构 struct s3c2410_platform_nand superlpplatform={
tacls:0,
//修改 s3c_device_nand 结构体增加对 superlpplatform 设备的支持 struct platform_device s3c_device_nand = {
.name = "s3c2410-nand", .id = -1,
.num_resources = ARRAY_SIZE(s3c_nand_resource), .resource = s3c_nand_resource,
//添加以下内容用来支持 NAND Flash 芯片 .dev = {
.platform_data = &superlpplatform }
};
… …
上述代码的主要作用是完成内核对 NAND Flash 芯片驱动的支持,需要指出的是 TACLS、TWRPH0 和 TWRPH1,参考 S3C2410 用户手册,可以看到这三个参数控制的是 NAND Flash 信号线 CLE/ALE 与写控制信号 nWE 的时序关系。我们设的值为 TACLS=0,
TWRPH0=1,TWRPH1=0,其含义为:TACLS=1 个 HCLK 时钟,TWRPH0=2 个 HCLK 时 钟,TWRPH1=1 个 HCLK 时钟。其中 sets 定义支持的分区集,nr_sets 定义分区集数。最后 修改 s3c_device_nand 结构体变量,添加对 NAND Flash 设备驱动的支持。其中:name:为 设备名称;id:有效设备编号,如果只有一个定义为-1,如果多个则从 0 开始计算;
num_resources:定义有几个 NAND Flash 芯片资源;resource:定义 NAND Flash 芯片资源的 首地址。 static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_nand //添加此行来初始化新增的 NAND Flash 分区 };
… …
接下来还有一个问题就是要禁止 Flash ECC*(注 3)校验,由于通常我们使用的 BootLoader 通过软件已经产生 ECC 校验码,这与内核 ECC 校验码不一致,所以这里选择禁 止内核 ECC 校验。完成这个步骤需要修改的文件是 drivers/mtd/nand/s3c2410.c,具体操作如 下:
*注 3:在普通的内存上,常常使用一种技术,即 Parity,同位检查码(Parity check codes)被广泛地使 用在侦错码(error detectioncodes)上,它们增加一个检查位给每个资料的字元(或字节),并且能够 侦测到一个字符中所有奇(偶)同位的错误,但 Parity 有一个缺点,当计算机查到某个 Byte 有错误时,
并不能确定错误在哪一个位,也就无法修正错误。基于上述情况,产生了一种新的内存纠错技术,那就是 ECC,英文全称是 Error Checking and Correcting,即错误检查和纠正,从这个名称我们就可以看出它的 主要功能就是“发现并纠正错误”,它比奇偶校正技术更先进的方面主要在于它不仅能发现错误,而且能
static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
struct s3c2410_nand_mtd *nmtd, struct s3c2410_nand_set *set) {
struct nand_chip *chip = &nmtd->chip;
chip->IO_ADDR_R = (char *)info->regs + S3C2410_NFDATA;
chip->IO_ADDR_W = (char *)info->regs + S3C2410_NFDATA;
chip->hwcontrol = s3c2410_nand_hwcontrol;
chip->dev_ready = s3c2410_nand_devready;
chip->cmdfunc = s3c2410_nand_command;
chip->write_buf = s3c2410_nand_write_buf;
chip->read_buf = s3c2410_nand_read_buf;
chip->select_chip = s3c2410_nand_select_chip;
chip->chip_delay = 50;
chip->priv = nmtd;
chip->options = 0;
chip->controller = &info->controller;
nmtd->info = info;
nmtd->mtd.priv = chip;
nmtd->set = set;
if (hardware_ecc) {
chip->correct_data = s3c2410_nand_correct_data;
chip->enable_hwecc = s3c2410_nand_enable_hwecc;
chip->calculate_ecc = s3c2410_nand_calculate_ecc;
chip->eccmode = NAND_ECC_HW3_512;
chip->autooob = &nand_hw_eccoob;
} else {
chip->eccmode = NAND_ECC_NONE; //修改此行的赋值 }
}
… …
到此已经完成了新的内核对 NAND Flash 分区的支持,下面将介绍配置内核的主要选 项。