Linux3.8.3内核移植-Nand/yaffs2移植
1、增加6410 nand驱动支持
linux内核,nand驱动已经对2410母体支持的很完善,从下列文件可以看出
eric@eric-PC:~/Documents/linux-3.8.3/drivers/mtd/nand$ ls s3c*
s3c2410.c
但是并没有对6410有很好的支持,现在就增加6410相关支持
1、复制s3c_nand.c到linux-3.8.3/drivers/mtd/nand目录下
eric@eric-PC:~/Documents/linux-3.8.3/drivers/mtd/nand$ ls s3c*
s3c2410.c s3c_nand.c
2、修改Kconfig,在2410定义后面,添加S3C6410支持
config MTD_NAND_S3C6410
tristate "NAND Flash support for Samsung S3C6410 SoCs"
depends on (ARCH_S3C64XX || ARCH_S5P64XX || ARCH_S5PC1XX)&&MTD_NAND
help
This enables the NAND flash controller on the S3C64xx
No board specific support is done by this driver, each board
must advertise a platform_device for the driver to attach.
config MTD_NAND_S3C_DEBUG
bool "Samsung S3C NAND driver debug"
depends on MTD_NAND_S3C6410
help
Enable debugging of the S3C6410 NAND driver
config MTD_NAND_S3C_HWECC
bool "Samsung S3C NAND Hardware ECC"
depends on MTD_NAND_S3C6410
help
Enable the use of the controller's internal ECC generator when
using NAND. Early versions of the chips have had problems with
incorrect ECC generation, and if using these, the default of
software ECC is preferable.
3、修改Makefile,将s3c_nand.c编译进去
obj-$(CONFIG_MTD_NAND_S3C6410) += s3c_nand.o#eric++ 2017-12-16
4、添加6410 寄存器定义
eric@eric-PC:~/Documents/linux-3.8.3/arch/arm/plat-samsung/include/plat$ gedit regs-nand.h
后面追加:
#if 1
//add eric 2017-12-16
/* for s3c_nand.c */
#define S3C_NFCONF S3C2410_NFREG(0x00)
#define S3C_NFCONT S3C2410_NFREG(0x04)
#define S3C_NFCMMD S3C2410_NFREG(0x08)
#define S3C_NFADDR S3C2410_NFREG(0x0c)
#define S3C_NFDATA8 S3C2410_NFREG(0x10)
#define S3C_NFDATA S3C2410_NFREG(0x10)
#define S3C_NFMECCDATA0 S3C2410_NFREG(0x14)
#define S3C_NFMECCDATA1 S3C2410_NFREG(0x18)
#define S3C_NFSECCDATA S3C2410_NFREG(0x1c)
#define S3C_NFSBLK S3C2410_NFREG(0x20)
#define S3C_NFEBLK S3C2410_NFREG(0x24)
#define S3C_NFSTAT S3C2410_NFREG(0x28)
#define S3C_NFMECCERR0 S3C2410_NFREG(0x2c)
#define S3C_NFMECCERR1 S3C2410_NFREG(0x30)
#define S3C_NFMECC0 S3C2410_NFREG(0x34)
#define S3C_NFMECC1 S3C2410_NFREG(0x38)
#define S3C_NFSECC S3C2410_NFREG(0x3c)
#define S3C_NFMLCBITPT S3C2410_NFREG(0x40)
#define S3C_NF8ECCERR0 S3C2410_NFREG(0x44)
#define S3C_NF8ECCERR1 S3C2410_NFREG(0x48)
#define S3C_NF8ECCERR2 S3C2410_NFREG(0x4c)
#define S3C_NFM8ECC0 S3C2410_NFREG(0x50)
#define S3C_NFM8ECC1 S3C2410_NFREG(0x54)
#define S3C_NFM8ECC2 S3C2410_NFREG(0x58)
#define S3C_NFM8ECC3 S3C2410_NFREG(0x5c)
#define S3C_NFMLC8BITPT0 S3C2410_NFREG(0x60)
#define S3C_NFMLC8BITPT1 S3C2410_NFREG(0x64)
#define S3C_NFCONF_NANDBOOT (1<<31)
#define S3C_NFCONF_ECCCLKCON (1<<30)
#define S3C_NFCONF_ECC_MLC (1<<24)
#define S3C_NFCONF_ECC_1BIT (0<<23)
#define S3C_NFCONF_ECC_4BIT (2<<23)
#define S3C_NFCONF_ECC_8BIT (1<<23)
#define S3C_NFCONF_TACLS(x) ((x)<<12)
#define S3C_NFCONF_TWRPH0(x) ((x)<<8)
#define S3C_NFCONF_TWRPH1(x) ((x)<<4)
#define S3C_NFCONF_ADVFLASH (1<<3)
#define S3C_NFCONF_PAGESIZE (1<<2)
#define S3C_NFCONF_ADDRCYCLE (1<<1)
#define S3C_NFCONF_BUSWIDTH (1<<0)
#define S3C_NFCONT_ECC_ENC (1<<18)
#define S3C_NFCONT_LOCKTGHT (1<<17)
#define S3C_NFCONT_LOCKSOFT (1<<16)
#define S3C_NFCONT_8BITSTOP (1<<11)
#define S3C_NFCONT_MECCLOCK (1<<7)
#define S3C_NFCONT_SECCLOCK (1<<6)
#define S3C_NFCONT_INITMECC (1<<5)
#define S3C_NFCONT_INITSECC (1<<4)
#define S3C_NFCONT_nFCE1 (1<<2)
#define S3C_NFCONT_nFCE0 (1<<1)
#define S3C_NFCONT_INITECC (S3C_NFCONT_INITSECC | S3C_NFCONT_INITMECC)
#define S3C_NFSTAT_ECCENCDONE (1<<7)
#define S3C_NFSTAT_ECCDECDONE (1<<6)
#define S3C_NFSTAT_BUSY (1<<0)
#define S3C_NFECCERR0_ECCBUSY (1<<31)
#endif
5、修改nand_base.c,添加218bit ecc支持
实际上,256M的K9F2G08U并不需要218bit ecc,,但为了兼容更大容量的nand ,将此部分也一并完善。
eric@eric-PC:~/Documents/linux-3.8.3/drivers/mtd/nand$ gedit nand_base.c
94行添加:
//eric++2017-11-19
static struct nand_ecclayout nand_oob_218 = {
.eccbytes = 104,
.eccpos = {
24,25,26,27,28,29,30,31,32,33,
34,35,36,37,38,39,40,41,42,43,
44,45,46,47,48,49,50,51,52,53,
54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,
74,75,76,77,78,79,80,81,82,83,
84,85,86,87,88,89,90,91,92,93,
94,95,96,97,98,99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,
114,115,116,117,118,119,120,121,122,123,
124,125,126,127},
.oobfree =
{
{.offset = 2,
.length = 22}
}
};
nand_scan_tail函数中添加
case 218://eric++2017-12-16
chip->ecc.layout = &nand_oob_218;
break;
6、修改nand初始化函数
eric@eric-PC:~/Documents/linux-3.8.3/arch/arm/mach-s3c64xx$ gedit mach-x6410.c
static void __init x6410_machine_init(void)中添加:
s3c_device_nand.name = "s3c6410-nand"; //eric++ 2017-12-16
7、make menuconfig,选择6410 nand驱动器
进入以下目录:
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
<*> NAND Device Support --->
选择如下选项,并取消之前默认的NAND Flash support for Samsung S3C SoCs
<*> NAND Flash support for Samsung S3C6410 SoCs
[*] Samsung S3C NAND driver debug
[*] Samsung S3C NAND Hardware ECC
保存并退出。
8、make uImage
出现错误信息:
drivers/mtd/nand/s3c_nand.c:68:23: error: plat/nand.h: No such file or directory
修改 s3c_nand.c
//#include <plat/nand.h> //eric++ 2017-12-16
#include <linux/platform_data/mtd-nand-s3c2410.h> //eric++ 2017-12-16 包含struct s3c2410_platform_nand定义
重新make uImage,并启动
********Nandflash:Type=SLC ChipName:samsung-K9F2G08U0B or hynix-HY27UF082G2B******
S3C NAND Driver is using hardware ECC.
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit), 256MiB, page size: 2048, OOB size: 64
Driver must set ecc.strength when using hardware ECC
------------[ cut here ]------------
kernel BUG at drivers/mtd/nand/nand_base.c:3520!
Internal error: Oops - BUG: 0 [#1] ARM
Modules linked in:
发现以上bug,追踪drivers/mtd/nand/nand_base.c:3520,发现,应该是chip->ecc.strength没有定义导致的。
if (mtd->writesize >= chip->ecc.size) {
if (!chip->ecc.strength) {
pr_warn("Driver must set ecc.strength when using hardware ECC\n");
BUG();
}
break;
}
9、增加chip->ecc.strength定义,在文件s3c_nand.c中添加定义
#if defined(CONFIG_MTD_NAND_S3C_HWECC)
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.hwctl = s3c_nand_enable_hwecc;
nand->ecc.calculate = s3c_nand_calculate_ecc;
nand->ecc.correct = s3c_nand_correct_data;
nand->ecc.strength = 4; //eric++ 2017-12-16
重新make uImage,即可解除bug.
2、yaffs2移植
yaffs2下载地址
最好使用和linux3.8.3同一时期的版本,不要追求太新的版本,否则会导致各种兼容性的的问题。linux3.8.3是2013年3月的版本,在此我们选用的是2013-1-18版本的yaffs2。
1、下载,并解压到linux根目录下
eric@eric-PC:~/Documents/linux-3.8.3/yaffs2-5dce9cd$ ls
direct yaffs_allocator.h yaffs_mtdif_multi.c yaffs_tagsmarshall.c
Kconfig_multi yaffs_attribs.c yaffs_mtdif_single.c yaffs_tagsmarshall.h
Kconfig_single yaffs_attribs.h yaffs_nameval.c yaffs_trace.h
linux-tests yaffs_bitmap.c yaffs_nameval.h yaffs_verify.c
Makefile yaffs_bitmap.h yaffs_nand.c yaffs_verify.h
Makefile.kernel yaffs_checkptrw.c yaffs_nand.h yaffs_vfs_multi.c
moduleconfig.h yaffs_checkptrw.h yaffs_packedtags1.c yaffs_vfs_single.c
mtdemul yaffs_ecc.c yaffs_packedtags1.h yaffs_yaffs1.c
patches yaffs_ecc.h yaffs_packedtags2.c yaffs_yaffs1.h
patch-ker.sh yaffs_getblockinfo.h yaffs_packedtags2.h yaffs_yaffs2.c
README-linux yaffs_guts.c yaffs_summary.c yaffs_yaffs2.h
README-linux-patch yaffs_guts.h yaffs_summary.h yportenv.h
utils yaffs_linux.h yaffs_tagscompat.c yportenv_multi.h
yaffs_allocator.c yaffs_mtdif.h yaffs_tagscompat.h yportenv_single.h
eric@eric-PC:~/Documents/linux-3.8.3/yaffs2-5dce9cd$
2、为linux 内核增加yaffs2支持(打补丁)
eric@eric-PC:~/Documents/linux-3.8.3/yaffs2-5dce9cd$ ./patch-ker.sh c m /home/eric/Documents/linux-3.8.3/
Updating /home/eric/Documents/linux-3.8.3//fs/Kconfig
Updating /home/eric/Documents/linux-3.8.3//fs/Makefile
eric@eric-PC:~/Documents/linux-3.8.3/yaffs2-5dce9cd$
打补丁之后:ls目录下多了yaffs2文件夹,说明已经补丁成功打好
eric@eric-PC:~/Documents/linux-3.8.3/fs$ ls
... yaffs2 ...
3、make menuconfig,选择新增的yaffs2文件系统(只选择yaffs2即可 ,取消其他无用的文件系统例如ext3、cramfs、romfs)
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
<*> Caching block device access to MTD devices
File systems --->
[*] Miscellaneous filesystems --->
<*> yaffs2 file system support
4、文件系统已经建立好了,此时将系统进行分区:
修改arch_x6410.c:
static struct mtd_partition x6410_nand_part[] = {
/* [0] = {
.name = "uboot",
.size = SZ_1M,
.offset = 0,
},
[1] = {
.name = "kernel",
.size = SZ_2M,
.offset = SZ_1M,
},
[2] = {
.name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = SZ_1M + SZ_2M,
},
*/
[0] = {
.name = "uboot",
.size = SZ_1M,
.offset = 0,
},
[1] = {
.name = "kernel",
.size = (5 * SZ_1M),
.offset = SZ_1M,
},
[2] = {
.name = "rootfs",
.size = (200*SZ_1M),
.offset = (1+5) * SZ_1M,
},
[3] = {
.name = "user",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
},
};
5、make uImage ,启动
yaffs: dev is 1048576 name is "ram0" rw
yaffs: passed flags ""
yaffs: dev is 1048576 name is "ram0" rw
yaffs: passed flags ""
List of all partitions:
1f00 1024 mtdblock0 (driver?)
1f01 5120 mtdblock1 (driver?)
1f02 204800 mtdblock2 (driver?)
1f03 51200 mtdblock3 (driver?)
No filesystem could mount root, tried: yaffs yaffs2
有此可以看出yaffs2文件系统已经移植成功,但是还没有成功挂载。