• 沒有找到結果。

第 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 分区的支持,下面将介绍配置内核的主要选 项。