linux2.6.31在TX2440A上的移植

来源:互联网 发布:韩国高考 知乎 编辑:程序博客网 时间:2024/06/14 01:26

第一篇博客就总结一下linux的移植吧奋斗,最近在参照相广超老师的视频教程移植linux以及学习yaffs2根文件系统的制作,跟着视频操作了之后,开发板并不能成功加载文件系统难过,所以觉得需要总结一下移植经验,与人分享,也为以后移植做个参考。

内核源码:linux-2.6.31.tar.bz2(官网地址)

编译工具:arm-linux-gcc-4.3.3.tar.bz2(网上搜,还不知道有没有官网可以下载各种版本的,哪位朋友知道留言告诉我哈大笑

 

《》解压linux源码

   #tar xjvf linux-2.6.31.tar.bz2

 

《》修改Makefile的183行,指定处理器架构以及编译工具

   ARCH ?= arm

   CROSS_COMPILE ?= arm-linux-

 

《》修改时钟:

    修改arch/arm/mach-s3c2440/mach-smdk2440.c的163行

   static void __init smdk2440_map_io(void)

    {

       s3c24xx_init_clocks(12000000); //输入时钟为12MHz

    }

 

《》修改机器码(要与bootloader的匹配)

    在u-boot和kernel中都会有一个机器码(即:MACH_TYPE),

    只有这两个机器码一致时才能引导内核,否则就会出现如下mach的错误信息:

       Error: unrecognized/unsupported machine ID (r1 = 0x0000270f).

       Available machine support:

       ID (hex)   NAME

       0000016a SMDK2440

       Please check your kernel config and/or bootloader.

 

    我使用的是UBOOT,在uboot源码目录的include/asm-arm/mach-types.h中

    定义了uboot的机器码,找到S3C2440对应的机器码是168

       #define MACH_TYPE_TOTO                361

       #define MACH_TYPE_S3C2440             168

       #define MACH_TYPE_KS8695P             363

 

    那么我们也把linux中的机器码修改成168就可以了

    在arch/arm/tools/mach-types文件中找到s3c2440对应的机器码(379行)

    改为168

       s3c2440                 ARCH_S3C2440           S3C2440               168

 

《》配置内核

   make menuconfig

    在配置菜单中选择"Load an AlternateConfiguration File" ,输入2440的默认

    配置文件:arch/arm/configs/s3c2410_defconfig,这个文件就是S3C24XX

    系列开发板板级支持包(BSP)然后选择 OK,按回车。

 

进入"System Type"选项单,里面的选项保持默认在"S3C24XXMachine"选项中只配置这几项(其他的选项取消):

   S3C2410 Machine --->

   [*] SMDK2410/A9M2410

   S3C2440 Machine --->

   [*] SMDK2440

   [*] SMDK2440 with S3C2440 cpu moudle

配置完后,回到主菜单,选择这一项"Save an Alternate Configuration File" ,输入要保存的配置文件名称:.config (默认)或自己取名:TX2440A_config,退出。

编译内核: #make zImage

 

    编译完后,会在arch/arm/boot下生成zImage内核镜像文件,可以修改该目录下的Makefile, 在第57行下面添加:

   @cp -f arch/arm/boot/zImage zImage

   @echo ' Kernel: $@ is ready '

    这样执行make zImage后,就把生成的zImage拷到内核根目录下。

    如果希望在在执行make distclean时,也同时把zImage删除,可以修改内核根目录下Makefile 的第1247行,在后面加上:

   -type f -print | xargs rm -f rm zImage

    把 zImage 镜像烧进 NandFlash 跑一下,看是否正常打印出信息,如果第一步能正常引导内核,那就开始进行第二步,添加驱动。

    注意,系统启动最后可能会出现这个错误:

   Kernel panic - not syncing: Attempted to kill init!

    然后出打印出一些很乱的东西。因为用4.x.x版本的交叉编译器使用EABI,但内核默认是不支持EABI编译的,所以编译出的系统会报错,

    但用3. x.x版本的编译器就不会出现这个问题。解决办法是,配置内核支持EABI编译:

   Kernel Features --->

   [*] Use the ARM EABI to compile the kernel

   [*] Allow old ABI binaries to run with this kernel (EXPERIMENTA)

 

《》支持NandFlash

    这里我们要使NandFlash驱动同时支持 64M,256M 或更高容量。

    修改arch/arm/plat-s3c24xx/common-smdk.c文件,在第 110 行:

   static struct mtd_partition smdk_default_nand_part[] = {

   #if defined(CONFIG_64M_NAND)

   [0] = {

   .name = "boot",

   .offset = 0,

   .size = SZ_1M,

   },

   [1] = {

   .name = "kernel",

   .offset = SZ_1M + SZ_128K,

   .size = SZ_4M,

   },

   [2] = {

   .name = "yaffs2",

    .offset = SZ_1M + SZ_128K + SZ_4M,

   .size = SZ_64M - SZ_4M - SZ_1M - SZ_128K,

    }

   #elif defined(CONFIG_256M_NAND)

   [0] = {

   .name = "boot",

   .offset = 0,

   .size = SZ_1M,

   },

   [1] = {

   .name = "kernel",

   .offset = SZ_1M + SZ_128K,

   .size = SZ_4M,

   },

   [2] = {

   .name = "yaffs2",

   .offset = SZ_1M + SZ_128K + SZ_4M,

   .size = SZ_256M - SZ_4M - SZ_1M - SZ_128K,

    }

   #endif

   };

    这个分区名字可以随便起。

 

    接下来修改Nand读写匹配时间,这个改不改应该问题都不大,我认为是根据Nand的读写特性

    相关的,也就是查芯片资料得到的值,每种Nand的值都不一样,还是在这个文件中第140行:

   static struct s3c2410_platform_nand smdk_nand_info = {

   .tacls = 10,

   .twrph0 = 25,

   .twrph1 = 10,

   .nr_sets = ARRAY_SIZE(smdk_nand_sets),

   .sets = smdk_nand_sets,

   };

    修改 Kconfig 文件,在配置时选择NAND类型,修改driver/mtd/nand/Kconfig,在172行,添加:

   choice

   prompt "Nand Flash Capacity Select"

   depends on MTD

   config 64M_NAND

   boolean "64M NAND For TX-2440A"

   depends on MTD

   config 256M_NAND

   boolean "256M NAND For TX-2440A"

   depends on MTD

   endchoice

    配置内核,支持 NandFlash

   Device Drivers --->

   <*> Memory Technology Device (MTD) support --->

   [*] MTD partitioning support

   <*> NAND Device Support --->

   <*> NAND Flash support for S3C2410/S3C2440 SoC

   [*] S3C2410 NAND Hardware ECC <—这个一定要选上

   Nand Flash Capacity Select(256M Nand For TX-2440A)--->

    启动时输出:

   S3C24XX NAND Driver, (c) 2004 Simtec Electronics

   s3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns

   s3c24xx-nand s3c2440-nand: NAND hardware ECC

   NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB3,3V 8-bit)

   Scanning device for bad blocks

   Creating 3 MTD partitions on "NAND 256MiB 3,3V 8-bit":

   0x000000000000-0x000000100000 : "boot"

   0x000000120000-0x000000520000 : "kernel"

   0x000000520000-0x000010000000 : "yaffs2"

 

《》支持yaffs2文件系统

    下载yaffs2源码(去官网下载,yaffs2文件系统官网下载),最好下载10年附近的版本,因为linux2.6.31就是09年中旬的嘛,

    解压,进入yaffs2目录:

   #tar xzvf yaffs2.tar.gz

   #cd /yaffs2/

    给内核打上yaffs2文件系统的补丁,执行:

   #./patch-ker.sh c /………/linux-2.6.31/ <—这个是你的内核源码的目录

    这时内核源码fs目录下多了一个yaffs2目录,同时Makefile文件和Kconfig文件也增加了yaffs2的配置和编译条件。

    配置对 yaffs2 支持

    这部分配置的比较多,可根据自己的需要进行配置,把不用的文件系统都去掉,下面是几个主要的配置:

   File systems --->

   DOS/FAT/NT Filesystems --->

   <*> MSDOS fs support

   <*> VFAT (Windows95) fs support

   Miscellaneous filesystems --->

   <*> YAFFS2 file system support

   [*] Autoselect yaffs2 format     这个一定要选上,因为下一步就是加载我们制作好的yaffs2文件系统

    说明:现在内核已经支持NandFlash和yaffs2文件系统,将内核烧入NandFlash后,再烧入yaffs2

    文件系统,可以使用制作好的文件系统,也可以自己制作,详细的制作文件系统方法,请看后续。

    启动时(成功挂载文件系统)输出:

   yaffs: dev is 32505858 name is "mtdblock2"

   yaffs: passed flags ""

   yaffs: Attempting MTD mount on 31.2, "mtdblock2"

   yaffs: auto selecting yaffs2

   yaffs_read_super: isCheckpointed 0

   VFS: Mounted root (yaffs filesystem) on device 31:2.

Freeing initmemory: 196K

 

《》一个错误的解决办法

经过以上的修改及配置,把制作好的镜像(uboot,llinux内核,yaffs2文件系统)全部烧进开发板的NandFlash中,重启开发板,内核启动后出现一个错误委屈

end_request: I/O error, dev mtdblock2,sector 0 Buffer I/O error on device mtdblock2, logical block 0

原因分析:由于内核是通过uboot烧写到nandflash中,因此uboot产生的ecc校验码与内核的ecc校验码不同,所以需要关闭内核的ecc校验偷笑

解决方法:

打开内核源码目录的drivers/mtd/nand/s3c2410.c文件

在s3c2410_nand_init_chip()函数中修改如下:

把NAND_ECC_HW和NAND_ECC_SOFT替换成NAND_ECC_NONE,

即关闭ecc校验

       if(hardware_ecc) {

              chip->ecc.calculate= s3c2410_nand_calculate_ecc;

              chip->ecc.correct   = s3c2410_nand_correct_data;

              chip->ecc.mode         = NAND_ECC_NONE;//NAND_ECC_HW;

 

              switch(info->cpu_type) {

              caseTYPE_S3C2410:

                     chip->ecc.hwctl         = s3c2410_nand_enable_hwecc;

                     chip->ecc.calculate= s3c2410_nand_calculate_ecc;

                     break;

 

              caseTYPE_S3C2412:

                    chip->ecc.hwctl     = s3c2412_nand_enable_hwecc;

                    chip->ecc.calculate =s3c2412_nand_calculate_ecc;

                     break;

 

              caseTYPE_S3C2440:

                    chip->ecc.hwctl     = s3c2440_nand_enable_hwecc;

                    chip->ecc.calculate = s3c2440_nand_calculate_ecc;

                     break;

 

              }

       }else {

//            chip->ecc.mode         = NAND_ECC_SOFT;

              chip->ecc.mode         = NAND_ECC_NONE;

       }

 

至此,错误解决,开发可以正常挂载文件系统了吐舌头

下一步就是用busybox制作yaffs2文件系统啦,请参照下一篇博客再见

0 0
原创粉丝点击