移植Linux2.6.24.7到博创2410-S(s3c2410s),包括AX88796移植

一、下载并解压Linux2.6.24.7内核源码
从网上下载linux-2.6.24.7内核源码到/arm2410s目录下,并解压

#tar xzvf linux2.6.24.7.tar.gz
# cd linux2.6.24.7

进入内核解压后的目录

注:以后示例中,只要是相对路径全部是相对于/arm2410s/linux2.6.24.7/此目录

 

二、修改内核源码根目录下的Makefile文件

#vi Makefile

修改Makefile中的ARCHCROSS_COMPILE变量,修改为

 

ARCH        = arm
CROSS_COMPILE    = arm-linux-                                 //该值是交叉编译器的前缀,具体值因人而异

 

 注:arm和arm-linux-后面不能有空格,否则make menuconfig时会出现“/arm2410s/linux-2.6.24.7/arch/arm: 是一个目录”错误。

 


三、设置nand flash分区信息

修改arch/arm/plat-s3c24xx/common-smdk.c文件,修改Nand Flash的分区信息和Nand Flash的硬件信息(这部分信息应该与vivi中的flash(mtd)分区对应起来,不可随便设置)。

 (LED 器件的初始化也在这个文件里,但是博创的平台没有那四个LED管,所以要不要那些程序都无所谓。我就把它们放在那里,反正启动时不会有影响,也没有出错信息。)

修改的内容如下:

 

static struct mtd_partition smdk_default_nand_part[] = {

[0] = {

.name = "vivi",

.size = SZ_128K,

.offset = 0,

},

[1] = {

.name = "param",

.offset = SZ_128K,

.size = SZ_1M-SZ_128K,

},

[2] = {

.name = "kernel",

.offset = SZ_1M,

.size = SZ_1M * 3,

},

[3] = {

.name = "root",

.offset = SZ_4M,

.size = SZ_4M * 5,

},

[4] = {

.name = "user",

.offset = SZ_4M * 6,

.size = SZ_4M * 10,

},

};

 

 

注意:请不要画蛇添足地在进行自定义nand flash分区时仍然按照以前内核的移植步骤,在devs.c中自己添加分区信息,不然系统启动时会有出错信息:

kobject_add failed for s3c2410-nand with -EEXIST, don't try to register things with the same name in the same directory.
[<c00290a8>] (dump_stack+0x0/0x14) from [<c0110a9c>] (kobject_shadow_add+0x160/0x1a8)
[<c011093c>] (kobject_shadow_add+0x0/0x1a8) from [<c0110af8>] (kobject_add+0x14/0x18)
[<c0110ae4>] (kobject_add+0x0/0x18) from [<c015117c>] (device_add+0xa0/0x568)
[<c01510dc>] (device_add+0x0/0x568) from [<c0155180>] (platform_device_add+0x100/0x150)
[<c0155080>] (platform_device_add+0x0/0x150) from [<c01551f0>] (platform_device_register+0x20/0x24)
 r7:c0022a10 r6:c0020a1c r5:00000000 r4:c02cab30
[<c01551d0>] (platform_device_register+0x0/0x24) from [<c01553f8>] (platform_add_devices+0x24/0x6c)
 r4:00000000
[<c01553d4>] (platform_add_devices+0x0/0x6c) from [<c0011df4>] (smdk_machine_init+0x84/0x98)
 r8:c03b8000 r7:00000000 r6:c0020a1c r5:00000000 r4:c0021404
[<c0011d70>] (smdk_machine_init+0x0/0x98) from [<c0011178>] (smdk2410_init+0x1c/0x24)
[<c001115c>] (smdk2410_init+0x0/0x24) from [<c000f0bc>] (customize_machine+0x20/0x2c)
[<c000f09c>] (customize_machine+0x0/0x2c) from [<c0008914>] (kernel_init+0xb8/0x284)
[<c000885c>] (kernel_init+0x0/0x284) from [<c003d688>] (do_exit+0x0/0x76c)

我一开始就犯了这个毛病。具体情况请参阅:http://blog.chinaunix.net/u/17218/showart_262438.html以及/arch/arm/plat-s3c24xx文件夹下的common-smdk.c和devs.c。

 

 


四、 禁止nand flash的ECC校验

 

 

 修改文件drivers/mtd/nand/s3c2410.c文件,查找函数s3c2410_nand_init_chip(),在函数的最后一行,添加chip->ecc.mode=NAND_ECC_NONE;

 

 

 

 

五、支持启动时挂载devfs

 

Devfslinux-2.6.12及其以前版本的设备文件系统,但是在linux-2.6.13及其以后的版本中用得是udev。但是,为了能够使内核能够支持devfs以及在启动时并在/sbin/init运行之前能自动挂载/devdevfs文件系统,修改fs/Kconfig文件,修改方式如下:

查找menu “Pseudo filesystems”

在其后添加以下内容:

#add code -->

config DEVFS_FS

bool "/dev file system support (OBSOLETE)"

default y

config DEVFS_MOUNT

bool "Automatically mount at boot"

default y

depends on DEVFS_FS

#add code --

 

 

 

六、增加yaffs2文件系统的支持  

 1、下载Yaffs2
       URL:http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/

2、解压Yaffs2并将其加入Linux内核(打补丁的方式)
       #tar xzvf yaffs2.tar.gz      

       #cd yaffs2
      
#./patch-ker.sh c /arm2410s/linux-2.6.24.7/

 

 

 

 

七、博创2410S所配网卡AX88796NE2000兼容网卡)驱动的移植。

1、修改arch/arm/Kconfig文件,增加ISA总线支持,使其在make menuconfig 时出现NE2000的网卡配置选项。

    config ARCH_S3C2410

    bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"

    select GENERIC_GPIO

    select ISA       #add code

    help

      Samsung S3C2410X CPU based systems, such as the Simtec Electronics

      BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or

      the Samsung SMDK2410 development board (and derivatives).

2、修改include/asm-arm/arch-s3c2410/map.h文件。加入AX88796的地址映射。

/**********************add code********************/ 

#define S3C2410_VA_ISA_NET   S3C2410_ADDR(0x02100000)

#define S3C2410_PA_ISA_NET   __phys_to_pfn(0x10000000)

#define S3C2410_SZ_ISA_NET   SZ_1M

/**********************add code********************/

    说明:

    a、根据网上的资料,“#define S3C2410_VA_ISA_NET   S3C2410_ADDR(0x02100000)”的地址可以自己修改,只要不和别的虚拟地址冲突就行。我有试过将起改成“#define S3C2410_VA_ISA_NET   (0xd1000000)”,也就是博创的2.4.18的定义,也可以正常启动。

    b“#define S3C2410_PA_ISA_NET   __phys_to_pfn(0x10000000)”这句困扰了我很久。一开始我的定义是“#define S3C2410_PA_ISA_NET   (0x10000000)”,所以启动后系统就死在了网卡的初始化上,出现Unable to handle kernel paging request at virtual address 的错误。后来我上网查找资料,才知道:原来实地址与虚地址的映射结构 smdk2410_iodesc 里有所变化。第二个参数从原来的 unsigned long physical 变为 unsigned long pfn (Page Frame Number 页帧号)。而从 smdk2410_iodesc 传入的S3C2410_PA_ISA_NET 仍然是一个 physical 值,因此出现以上的错误。只要在物理地址前加上__phys_to_pfn就可以解决这个问题。较详细的讲解请看我的参考资料

 

 

3、修改arch/arm/mach-s3c2410/mach-smdk2410.c文件。在smdk2410_iodesc 中加入AX88796的地址信息。

     static struct map_desc smdk2410_iodesc[] __initdata = {

  /* nothing here yet */

 

/**********************add code********************/

 

        {

                .virtual        = S3C2410_VA_ISA_NET,

                .pfn          = S3C2410_PA_ISA_NET,

                .length        = S3C2410_SZ_ISA_NET,

                .type          = MT_DEVICE,

        }

/**********************add code********************/

 

 

};

 

 

 

4、修改网卡驱动的主要文件drivers/net/ne.c

 (1)添加头文件和定义

#include <asm/system.h>

#include <asm/io.h>

 

/**********************add code********************/

 

#include <linux/irq.h>

#include <asm/arch-s3c2410/map.h>

#include <asm/arch-s3c2410/regs-mem.h>

#include <asm/arch-s3c2410/irqs.h>

#include <asm/arch-s3c2410/hardware.h>

#include <asm/arch-s3c2410/regs-gpio.h>

 

#define AX88796_BASE   (vAX88796_BASE+0x200)

#define AX88796_IRQ    IRQ_EINT2

#define pAX88796_BASE    S3C2410_PA_ISA_NET

#define vAX88796_BASE    S3C2410_VA_ISA_NET

#define EXTINT_OFF  (IRQ_EINT4 - 4)

 

 

/**********************add code********************/

 

......

     static struct { const char *name8, *name16; unsigned char SAprefix[4];}

bad_clone_list[] __initdata 中增加AX88796 MAC地址前三位(不一定需要):

         {"AX88796", "NE2000-compatible", {0x08, 0x08, 0x08}},       //add code 

 

 (2)、确保定义总线宽度为16位。

    

#if defined(CONFIG_PLAT_MAPPI)

#  define DCR_VAL 0x4b

#elif defined(CONFIG_PLAT_OAKS32R)  || /

   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)

#  define DCR_VAL 0x48      /* 8-bit mode */

#else

#  define DCR_VAL 0x49

#endif

     修改为

#if 0

#if defined(CONFIG_PLAT_MAPPI)

#  define DCR_VAL 0x4b

#elif defined(CONFIG_PLAT_OAKS32R)  || /

   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)

#  define DCR_VAL 0x48      /* 8-bit mode */

#else

#endif

#endif

#  define DCR_VAL 0x49

    

 (3)do_ne_probe函数中增加配置总线参数、基地址和中断的语句(其参数参考 刘淼 的书)

static int __init do_ne_probe(struct net_device *dev)

{

     unsigned long base_addr = dev->base_addr;

#ifdef NEEDS_PORTLIST

     int orig_irq = dev->irq;

#endif

 

/**********************add code********************/

 

static int once=0;

     if (once) {

      return -ENXIO;

}

     unsigned int value;

 

value = __raw_readl(S3C2410_BWSCON);

value &= ~(S3C2410_BWSCON_WS2|S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_32);

value |= (S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_16);

__raw_writel(value, S3C2410_BWSCON);

value=0;

value = (S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh4|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMCnorm);

__raw_writel(value,S3C2410_BANKCON2);

set_irq_type(AX88796_IRQ,IRQ_TYPE_LEVEL_LOW );

s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);

s3c2410_gpio_pullup(S3C2410_GPF2, 0);

if(base_addr==0){

     dev->base_addr = base_addr = AX88796_BASE ;

  dev->irq = AX88796_IRQ;

  once++;

  }

 

/**********************add code********************/

 

     SET_MODULE_OWNER(dev);

 

     /* First check any supplied i/o locations. User knows best. <cough> */

     if (base_addr > 0x1ff) /* Check a single specified location. */

         return ne_probe1(dev, base_addr);

     else if (base_addr != 0)    /* Don't probe at all. */

         return -ENXIO;

......

(4)、修改ne_probe1函数

     增加自定义的网卡MAC地址(这个地址可以自行修改,但是MAC也有一定的规则,最重要的是千万不要把它配置为广播或组播地址,请参考网络的相关书籍):

static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)

{

     int i;

     unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0};   //add code

     unsigned char SA_prom[32];

     int wordlength = 2;

......

     增加网卡MAC地址的配置语句,屏蔽通过EEPROM配置网卡的语句

......

         struct {unsigned char value, offset; } program_seq[] =

         {

              {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/

              {0x48,   EN0_DCFG},    /* Set byte-wide (0x48) access. */

              {0x00,   EN0_RCNTLO},  /* Clear the count regs. */

              {0x00,   EN0_RCNTHI},

              {0x00,   EN0_IMR}, /* Mask completion irq. */

              {0xFF,   EN0_ISR},

              {E8390_RXOFF, EN0_RXCR},    /* 0x20  Set to monitor */

              {E8390_TXOFF, EN0_TXCR},    /* 0x02  and loopback mode. */

              {32, EN0_RCNTLO},

              {0x00,   EN0_RCNTHI},

              {0x00,   EN0_RSARLO},  /* DMA starting at 0x0000. */

              {0x00,   EN0_RSARHI},

              {E8390_RREAD+E8390_START, E8390_CMD},

         };

 

         for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)

              outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);

 

     }

 

/**********************add code********************/

 

{

 unsigned char *ep;

 ep = (unsigned char * ) &ne_defethaddr[0];

 ne_defethaddr[5]++;

 

 for(i=0;i<6;i++) {

  SA_prom[i] = ep[i];

}

 

 SA_prom[14] = SA_prom[15]=0x57;

 wordlength =2;

}

 

/**********************add code********************/

 

#if 0    //add code

 

     for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {

         SA_prom[i] = inb(ioaddr + NE_DATAPORT);

         SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);

         if (SA_prom[i] != SA_prom[i+1])

              wordlength = 1;

     }

#endif   //add code

     if (wordlength == 2)

     {

#if 0   //add code

         for (i = 0; i < 16; i++)

              SA_prom[i] = SA_prom[i+i];

 

         /* We must set the 8390 for word mode. */

         outb_p(DCR_VAL, ioaddr + EN0_DCFG);

         start_page = NESM_START_PG;

 

         /*

          * Realtek RTL8019AS datasheet says that the PSTOP register

          * shouldn't exceed 0x60 in 8-bit mode.

          * This chip can be identified by reading the signature from

          * the  remote byte count registers (otherwise write-only)...

          */

         if ((DCR_VAL & 0x01) == 0 &&         /* 8-bit mode */

             inb(ioaddr + EN0_RCNTLO) == 0x50 &&

             inb(ioaddr + EN0_RCNTHI) == 0x70)

              stop_page = 0x60;

         else

              stop_page = NESM_STOP_PG;

#endif   //add code

 

/**********************add code********************/

 

         outb_p(0x49, ioaddr + EN0_DCFG);

         start_page = NESM_START_PG;

         stop_page = NESM_STOP_PG;

 

 /**********************add code********************/

 

     } else {

         start_page = NE1SM_START_PG;

         stop_page  = NE1SM_STOP_PG;

     }

......

     屏蔽自定检测中断号的语句(参考 刘淼 的书)

 

......

#if 0  //add code

     if (dev->irq < 2)

     {

         unsigned long cookie = probe_irq_on();

         outb_p(0x50, ioaddr + EN0_IMR);  /* Enable one interrupt. */

         outb_p(0x00, ioaddr + EN0_RCNTLO);

         outb_p(0x00, ioaddr + EN0_RCNTHI);

         outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */

         mdelay(10);        /* wait 10ms for interrupt to propagate */

         outb_p(0x00, ioaddr + EN0_IMR);      /* Mask it again. */

         dev->irq = probe_irq_off(cookie);

         if (ei_debug > 2)

              printk(" autoirq is %d/n", dev->irq);

     } else if (dev->irq == 2)

         /* Fixup for users that don't know that IRQ 2 is really IRQ 9,

            or don't know which one to set. */

         dev->irq = 9;

#endif   //add code

     if (! dev->irq) {

         printk(" failed to detect IRQ line./n");

         ret = -EAGAIN;

         goto err_out;

     }

 

     

 

七、配置内核
   1、载入s3c2410的默认配置文件,以简化配置过程
    # cp arch/arm/configs/s3c2410_defconfig .config
    # make menuconfig
   2、手动配置内核,在s3c2410_defconfig基础上,增加以下配置选项:
    General setup  > 
        [*] Configure standard kernel features (for small systems)  >   
    选上这项,否则文件系统中的一些选项不会出现

   Loadable module support >

     [*] Enable loadable module support

     [*] Automatic kernel module loading 

   System Type >

     [*] S3C2410 DMA support

   Boot options >

      Default kernel command string:noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 mem=64M 

注:
mtdblock3代表第5个flash分区,用来作根文件系统rootfs;
console=ttySAC0,115200使kernel启动期间的信息全部输出到串口0上,波特率为115200;
2.6内核对于串口的命名改为ttySAC0,但这不影响用户空间的串口编程。
用户空间的串口编程针对的仍是/dev/ttyS0等
mem=64M表示内存是64M,如果是32则设为32M
    Networking  --->
       Networking options  --->  
          <*> Packet socket 
          [*]   Packet socket: mmapped IO

 Floating point emulation >

[*] NWFPE math emulation 

 Device Drivers >

    Network device support  --->

Memory Technology Devices (MTD) >

      [*] MTD partitioning support

           [*] Command line partition table parsing

   RAM/ROM/Flash chip drivers >

       <*> Detect flash chips by Common Flash Interface (CFI) probe

       <*> Detect nonCFI AMD/JEDECcompatible flash chips

       <*> Support for Intel/Sharp flash chips

       <*> Support for AMD/Fujitsu flash chips

       <*> Support for ROM chips in bus mapping

   NAND Flash Device Drivers >

       <*> NAND Device Support

<*> NAND Flash support for S3C2410/S3C2440 SoC

Character devices >

       [*] Nonstandard serial port support

       [*] S3C2410 RTC Driver

File systems >

   <> Second extended fs support #去除对ext2的支持

   Pseudo filesystems >

       [*] /proc file system support

       [*] Virtual memory file system support (former shm fs)

       [*] /dev file system support (OBSOLETE)

       [*] Automatically mount at boot (NEW)

#这里会看到我们前先修改fs/Kconfig的成果,devfs已经被支持上了

   Miscellaneous filesystems >

       <*> Compressed ROM file system support (cramfs)                

       <*> YAFFS2 file system support                  #支持yaffs2

       [*] Lets Yaffs do its own ECC

   Network File Systems >

       <*> NFS file system support

--以下最好选上,因为在挂载NFS时可能出现protocol不支持的情况--
                             [*]Provide NFSv3 client support
                             [*]Provide client support for the NFSv3 ACL protocol extension
                             [*]   Provide NFSv4 client support (EXPERIMENTAL)
                             [*]   Allow direct I/O on NFS files
------------------------------------------------------------------------- 

 

 

 [ ] NFS server support 

 

                             [*] Root file system on NFS 

 

 

           Ethernet (10 or 100Mbit)  --->
               “N”掉< > DM9000 support和< >   Generic Media Independent Interface device support
-------以下一定要选上,是AX88796的驱动------
               [*] Other ISA cards      
               <*> NE2000/NE1000 support
 
     保存退出,产生.config文件。
八、编译内核

1) 内核的编译操作

#make menuconfig       配置编译选项

#make dep              提供变量依赖关系信息

#make clean            删除生成的模块和目标文件

#make zImage           编译内核生成压缩的映像

#make modules          编译模块

#make modules_install  安装编译完成的模块

2) 生成压缩的内核映像

#make dep

#make zImage

至此,内核的编译工作完成,在arch/arm/boot目录下生成了zImage文件,即为压缩的内核映像。

最后,将内核镜像烧写到博创arm2410s开发板上,启动正常,网卡也正常

 

 

本文一大部分内容是借鉴移植Linux2.6.22.2到博创2410-S

http://blog.chinaunix.net/u1/34474/showart_369449.html

 

 

 

你可能感兴趣的:(c,linux,struct,Flash,makefile,linux内核)