sbc_2410开发板内核2.6.30.4移植

来源:互联网 发布:rbf神经网络算法介绍 编辑:程序博客网 时间:2024/05/01 02:12

大概又过了一个星期了,没想到内核的移植是如此的繁琐,今天下午5:20的时候,我终于看到了刚开始的启动界面,我和燕齐开心不已啊。废话少说,我要把我和他的开发过程记录一下。

首先是下载2.6.30.4的内核源码,同时使用的编译器是4.3.3,有了这两个东西后就是使用已有的文件系统yaffs2文件镜像,我使用的天嵌公司的文件系统镜像,因为我的板子的nandflash是64MB的,一定要使用相应的文件系统镜像。

1.然后我们先来调下内核,首先是解压缩:

  解压缩内核压缩文件后进入到目录中,然后修改Makefile,找到
  ARCH ?=
  CROSS_COMPILE ?=

  这里我们填写我们对应的开发板的是ARM和编译器4.3.3的路径,这样我们才可以对内核配置和编译的

2.接着我们配置系统时钟,我们来到文件路径打开文件arch/arm/mach-s3c2410/mach-s3c2410.c,然后搜索smdk2410_map_io函数里面改时钟,我们在s3c24xx_init_clock(12000000),红色的部分就是我们开发板    arm的时钟。在我之前做的uboot里面可以确认到的,在include/configs/sbc2410x.h文件中有个#define CONFIG_SYS_CLK_FREQ 12000000这个就是平台的输入时钟。

3.接着来到内核的目录下,打makemenuconfig之后就会出现我们的配置菜单,我们在最后的load选项进行load,吧arch/arm/configs/s3c2410_configs的配置load进内核里,然后就在内核配置菜单里面发现多了一项system_type,我们在里面选择s3c2410machines选项里面选择smdk2410/A9M2410,由于我们的sbc2410的板子设计和smdk2410的板子设计基本一样,这样我们就可以通过这个选项来支持我们的板子了。退出的时候选择保存。

4.接下来就是机器码的修改,我们可以先把上面配置好的内核先make,然后把镜像通过tftp 0x30008000 zImage;go 0x30008000使其跑到内核先启动调试一下先,串口的打印信息如此啊:

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

这个就告诉我们的uboot传到内核的机器码不对,这样我们以通过0x000007cf换算成十进制数,然后来到内核如下文件进行修改:arch/arm/tools/mach-types找到s3c2410 ARCH_S3C2410 S3C2410 362 把后面的数字换成你转换的十进制数。

为什么要这样改呢?

vim arch/arm/mach-s3c2410/mach-smdk2410.c
在最后一段有这句 MACHINE_START(S3C2410 , ”SMDK2410”)
这里S3C2410就是machine ID的代号

5.关于nandflash的如何分区,网上很多资料,如下:

arch/arm/plat-s3c24xx/common-smdk.c

还有要配置MTD的相关选项,这个在内核配置选项单里面配置的,如下:

打开配置进入Device Drivers
Memory Technology Device ......... 前面是个M~ 说明这个模块是动态加载的,而我们编译的zImage里面只有静态模块
将MTD选为静态加载,然后进入MTD配置中看看还有什么需要选的
NAND Device Support 这个也是动态,选为静态加载
进入NAND Device Support
原来连NAND Flash support for S3C2410/S3C2440 SoC都没选,马上选为静态加载

Direct char device access to MTD devices
Common interface to block layer for MTD ‘translation layers’
Caching block device access to MTD devices
这样我们就配置完了。

注意:如果你什么都配置好了,加上文件系统yaffs2在内核中的支持和配置都完成的话,还是挂不上文件系统的,你看看提示信息里面有没有说识别不了你用来放文件系统镜像的分区(一般我们都用mtdblock2)这样你就要注意你的打印信息里面是否有这句话linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0"这个是你在配置内核时要求对内核传递的参数,如果不是/dev/mtdblock2的话,你就必须改回来。

6.现在我们要为文件系统yaffs2使linux对其支持的话,我们先要下载一个yaffs文件的压缩文件,我们解开后,我们来到yaffs2的目录下的时候我们会发现一个补丁文件./patch-ker.sh,我们执行它,就可以再我们的内核的fs目录下建立yaffs2的目录树,其实这个是yaffs2在linux下的驱动。怎么使用这个补丁,你看看yaffs2目录下的readme文件吧。自己试试看。我们会发现fs文件的makefile和kconfig中都有对yaffs2支持加上了相应的选项了。这样我们就可以直接来到内核配置桌面上配置支持yaffs2的相关选项了。

到Kernel Features,需要选上:
Use the ARM EABI to compile the kernel
Allow old ABI binaries to run with thie Kernel

为什么呢?~ Google了一下,原来友善的根文件系统在编译的时候也启用了EABI特性,内核和文件系统需要对上
文件系统用了EABI 内核也要用EABI 内核不用EABI 也只能读取不用EABI的文件系统
然后在配置的 File systems->Miscellaneous filesystems 中选上 “YAFFS2 filesystem support”  “Autoselect yaffs2 format”  “Cache short names in RAM”

7.uboot的烧写必须要支持yaffs的烧写方式,这样我们才可以正确烧写,我们要在增加uboot的nand write.yaffs和nand read.yaffs的命令,方法如下:

8.我们执行如下命令:tftp 0x30008000 zImage;nand erase 0x200000 0x200000;nand write 0x30008000 0x200000 0x200000(这个是烧写内核的)

                              tftp 0x30008000 wenjian.bin;nand erase 0x400000 0x3bf8000;nand write.yaffs 0x30008000 0x400000 0x3801360(这个是烧写文件系统的)

注意:这里的分区是我的分区方式,但是为什么我在烧写文件系统的时候起始位置一样,大小却不一样呢?这个和我板子的nandflash的硬件有关系,由于我的nandflash的读写方式是按512+16字节对齐的,所以我在烧的时候要非常注意要和这个字节对齐。

9.最后我们要修改串口的驱动,如果你的文件系统是自己制作的话,你就可以不用修改,由于天嵌的板子什么东西都要用他的tq2440,所以我就要把串口驱动对应的设备名改为这个名字,要不文件系统的初始化进程就无法找到这个串口设备来输出它的对应信息设置和用户交互不了,我们来到driver/serial/samsung.c文件来修改我们的设备名,我们找到structuart_driver结构体对应的我们板子串口变量名为:s3c24xx_uart_drv。我们看到了dev_name=s3c2410_serial0,把它改为tq2440_serial0,这样我们文件系统的初始化进程就可以找到我们的串口设备了。

 

 

1、在commom/cmd_nand.c中增加"nand write.yaffs..." 的使用说明,代码添加如下:

U_BOOT_CMD(nand, 5, 1, do_nand,
    "nand    - NAND sub-system/n",
    "info                  - show available NAND devices/n"
    "nand device [dev]     - show or set current device/n"
    "nand read[.jffs2]     - addr off|partition size/n"
    "nand write[.jffs2]    - addr off|partiton size - read/write `size' bytes starting/n"
    "    at offset `off' to/from memory address `addr'/n"
   
"nand read.yaffs addr off size - read the `size' byte yaffs image starting/n"
    "    at offset `off' to memory address `addr'/n"
    "nand write.yaffs addr off size - write the `size' byte yaffs image starting/n"
    "    at offset `off' from memory address `addr'/n"

    "nand erase [clean] [off size] - erase `size' bytes from/n"
    "    offset `off' (entire device if not specified)/n"
    "nand bad - show bad blocks/n"
……………………

……………………

然后,在 nand 命令的处理函数 do_nand 中增加对"nand yaffs..."的支持。do_nand 函数仍在 commom/cmd_nand.c 中实现,代码修改如下:

……………………

……………………

opts.quiet      = quiet;

                ret = nand_write_opts(nand, &opts);

            }

}

else if (  s != NULL && !strcmp(s, ".yaffs")){    
            if (read) {
               
                nand_read_options_t opts;
                memset(&opts, 0, sizeof(opts));
                opts.buffer = (u_char*) addr;
                opts.length = size;
                opts.offset = off;
                opts.readoob = 1;
                opts.quiet      = quiet;
                ret = nand_read_opts(nand, &opts);
            } else {
               
                nand_write_options_t opts;
                memset(&opts, 0, sizeof(opts));
                opts.buffer = (u_char*) addr;
                opts.length = size;
                opts.offset = off;
               
                opts.noecc = 1;
                opts.writeoob = 1;
                opts.blockalign = 1;
                opts.quiet      = quiet;
                opts.skipfirstblk = 1;
                ret = nand_write_opts(nand, &opts);
            }   

 } else {

             if (read)

                 ret = nand_read(nand, off, &size, (u_char *)addr);

             else

                ret = nand_write(nand, off, &size, (u_char *)addr);

        }

…………………

…………………

2include/nand.h 中进行如下修改,增加 skipfirstblk 成员:

struct nand_write_options {
u_char *buffer;

………………

………………

int pad;

int blockalign;

int skipfirstblk;

}

3drivers/nand/nand_util.c 修改 nand_write_opts 函数,增加对 skipfirstblk 成员的支持:

int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts)

{

    int imglen = 0;

………………

………………

int result;

    int skipfirstblk = opts->skipfirstblk;

………………

………………

 

} while (offs < blockstart + erasesize_blockalign);

         }


        if (skipfirstblk) {     
            mtdoffset += erasesize_blockalign;
            skipfirstblk = 0;
            continue;
        }

 readlen = meminfo->oobblock;

………………

进行上面移植后,u-boot 已经支持 yaffs 文件系统映象的烧写,由于前面设置"opts.noecc=1" 不使用ECC校验码,烧写时会提示很多提示信息,可以修改 drivers/nand/nand_base.c 文件中的 nand_write_page 函数,将其注释掉。

    case NAND_ECC_NONE:
        //printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended/n");

主要修改smdk_default_nand_part[]
{
 [0] = {
  .name = “uboot”,
  .size = 0x00004000,
  .offset = 0,
},
[1] = {
 .name = “Kernel”,
 .offset = 0x200000,
 .size = 0x200000,
},
[2] = {
 .name = “yaffs2”,
 .offset = 0x400000,
 .size = 0x3bf8000,
},
};