[ARM-LINUX]移植2.6.31.12内核到立宇泰ARMSYS2440开发板

来源:互联网 发布:asp.net 2.0高级编程 编辑:程序博客网 时间:2024/04/30 23:54

ARMSYS2440开发板原来的内核版本为linux2.6.12,这次要求移植高版本内核,并打上rt补丁,使之变成实时内核。

 

移植步骤主要参考 http://blog.csdn.net/yang_dk/archive/2008/04/17/2300712.aspx

 

移植环境:

   主机:ubuntu 9.04

  交叉编译器:arm-linux-gcc-3.4.1

  开发板平台:S3C2440(ARMSYS2440开发板)

 

准备工作:

  1. 下载源码:http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.31.12.tar.bz2

  2. 安装交叉编译工具:自带的工具包,工具安装在/usr/local/arm/3.4.1/中。

  3. 解压源码:tar jxvf linux-2.6.31.12.tar.bz2

 

开始移植:

 

1. 修改配置文件

  1). 修改内核根目录下Makefile,设定ARM的编译环境.

    在193行找到ARCH

    修改为

      ARCH = arm

      CROSS_COMPILE = /usr/local/arm/3.4.1/bin/arm-linux-

    CORSS_COMPILE视自己的环境定

  2). 添加devfs支持

    为了内核支持devfs 以及在启动时并在/sbin/init 运行之前能自动挂载/dev为devfs 文件系统。编辑fs/Kconfig:

    在906 行menu "Pseudo filesystems"下面添加如下代码:

      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

 

2. 修改源代码

  1). 修改对nand的分区信息,与bootloader一致,可以从以前板子上内核源码的arch/arm/mach-s3c2410/devs.c中找到。

    在arch/arm/plat-s3c24xx/common-smdk.c中修改smdk_default_nand_part[],注意这个一定要跟bootloader的一致。修改如下:

    static struct mtd_partition smdk_default_nand_part[] = {
      [0] = {
         .name = "Boot",
         .size = 0x00030000,
         .offset = 0
      },
      [1] = {
         .name = "Kernel",
         .size = 0x001d0000,
         .offset = 0x00030000,
      },
      [2] = {
         .name = "RootFileSystem",
         /*.size = 0x01e00000,    //30M*/
         .size = 0x03300000,
         .offset = 0x00200000,
      },
      [3] = {
         .name = "ExtendFileSystem",
         .size = 0x00b00000,
         .offset = 0x03500000,
      }
    };

 

    另外此文件还要修改smdk_nand_info如下:

      static struct s3c2410_platform_nand smdk_nand_info = {
        .tacls  = 0, // 20
        .twrph0  = 30,// 60
        .twrph1  = 0, // 20
        .nr_sets = ARRAY_SIZE(smdk_nand_sets),
        .sets  = smdk_nand_sets,
      };

 

  2). 修改时钟

        在arch/arm/mach-s3c2440/mach-smdk2440.c中修改smdk2440_map_io如下

            static void __init smdk2440_map_io(void)

            {

                s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));

                s3c24xx_init_clocks(12000000);      //default is 16934400

                s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));

            }

    另,我们板子上的uboot没有2440的MACH_TYPE匹配号,因此它用的还是2410的mach号,内核源码中2410的时钟启动为s3c24xx_init_clocks(0);默认启动(arch/arm/mach-s3c2410/mach-smdk2410.c)。故修改arch/arm/mach-s3c2410/mach-smdk2410.c中的0为16934400:

      static void __init smdk2410_map_io(void)
      {
       s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
       s3c24xx_init_clocks(16934400); // 0
       s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
      }

 

  3). 修改nand Flash的校验方式,去掉ECC校验。

       在drivers/mtd/nand/s3c2410.c 第841行

       将chip->ecc.mode = NAND_ECC_SOFT;

       改为 chip->ecc.mode = NAND_ECC_NONE;

 

3. 配置编译内核

  可以将开发板内核源码中原来的.config文件拷过来直接使用。

  若要自行配置,可把把默认配置文件拷贝过来

    cp arch/arm/configs/s3c2410_defconfig .config

  配置:make menuconfig

  确认以下选项都有:

 

  [*] Enable loadable module support --->

         [*]   Module unloading

 

  System Type ---->

         [*] S3C2410 DMA support

         S3C2410 Machines --->

                [*] SMDK2410/A9M2410

         S3C2440 Machines --->

                [*] SMDK2440

                [*] SMDK2440 with S3C2440 CPU module

 

  Boot option ----->

         修改启动参数为:

  root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200 display=L35T32 rootfstype=cramfs devfs=mount

 

  Device Drivers --->

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

                [*]   MTD partitioning support

                <*> NAND Device Support --->

                        <*>   NAND Flash support for S3C2410/S3C2440 SoC

                        [ ]    S3C2410 NAND Hardware ECC     //这个要去掉

         [*] Network device support --->

                 [*]   Ethernet (10 or 100Mbit) --->

                     <*>   CS89x0 support

         < > Real Time Clock --->   //这个去掉

 

  File systems --->

         <*> ROM file system support

         因为我的文件系统用cramfs,选择这个,其他用默认。

 

4. 编译内核

  make zImage

  编译成功,烧写到板子上。

  启动后,网卡驱动有误,因此需修改CS89x0驱动代码。

5. 移植CS89X0网卡驱动

  1). 修改arch/arm/plat-s3c24xx/include/plat/common-smdk.h,添加宏定义:

     #define __IRQT_FALEDGE IRQ_TYPE_EDGE_FALLING
     #define __IRQT_RISEDGE IRQ_TYPE_EDGE_RISING
     #define __IRQT_LOWLVL IRQ_TYPE_LEVEL_LOW
     #define __IRQT_HIGHLVL IRQ_TYPE_LEVEL_HIGH
     #define IRQT_NOEDGE (0)
     #define IRQT_RISING (__IRQT_RISEDGE)
     #define IRQT_FALLING (__IRQT_FALEDGE)
     #define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
     #define IRQT_LOW (__IRQT_LOWLVL)
     #define IRQT_HIGH (__IRQT_HIGHLVL)
     #define IRQT_PROBE IRQ_TYPE_PROBE


     #define pSMDK2410_ETH_IO __phys_to_pfn(0x19000000)
     #define vSMDK2410_ETH_IO 0xE0000000
     #define SMDK2410_ETH_IRQ IRQ_EINT9

  2). 修改arch/arm/mach-s3c2410/mach-smdk2410.c,添加网卡物理映射:

     static struct map_desc smdk2410_iodesc[] __initdata = {
       /* nothing here yet */
       {vSMDK2410_ETH_IO,pSMDK2410_ETH_IO,SZ_1M,MT_DEVICE} // 8900
     };

  3). 修改cs89x0.c,以下是diff文件,diff -ruN file1 file2:

 

@@ -174,6 +174,27 @@
 static unsigned int netcard_portlist[] __used __initdata =
    { 0x0300, 0};
 static unsigned int cs8900_irq_map[] = {1,0,0,0};
+
+#elif defined(CONFIG_ARCH_S3C2410) //Added zhangw
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-gpio.h>
+#include <plat/common-smdk.h>
+static unsigned int netcard_portlist[] __initdata = { vSMDK2410_ETH_IO +
+DEFAULTIOBASE, 0};
+static unsigned int cs8900_irq_map[] = {SMDK2410_ETH_IRQ , 0, 0, 0};
+
+#ifdef request_region
+#undef request_region
+#endif
+#ifdef release_region
+#undef release_region
+#endif
+#define request_region(a,s,n) request_mem_region(a,s,n)
+#define release_region(a,s) release_mem_region(a,s)
+
 #elif defined(CONFIG_MACH_IXDP2351)
 static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
@@ -324,6 +345,13 @@
        netdev_boot_setup_check(dev);
        io = dev->base_addr;
        irq = dev->irq;
+
+#ifdef CONFIG_ARCH_S3C2410 // add by zhangw
+ __raw_writel((__raw_readl(S3C2410_GPGCON)&~(0x3<<2))|(0x2<<2),S3C2410_GPGCON);
+ __raw_writel((__raw_readl(S3C2410_EXTINT1)&~(0x7<<4))|(0x4<<4),S3C2410_EXTINT1);
+ __raw_writel(0x2211d110,S3C2410_BWSCON);
+ __raw_writel(0x1f7c,S3C2410_BANKCON3);
+#endif

        if (net_debug)
                printk("cs89x0:cs89x0_probe(0x%x)/n", io);
@@ -387,6 +415,19 @@
 {
        outw(value, base_addr + (portno << 1));
 }
+#elif defined(CONFIG_ARCH_S3C2410)  // add by zhangw
+static u16
+readword(unsigned long base_addr, int portno)
+{
+ return __raw_readw(base_addr+portno);
+}
+
+static void
+writeword(unsigned long base_addr, int portno,u16 value)
+{
+ __raw_writew(value,base_addr+portno);
+}
+
 #else
 static u16
 readword(unsigned long base_addr, int portno)
@@ -653,7 +694,20 @@
           the driver will always do *something* instead of complain that
           adapter_cnf is 0. */

-#ifdef CONFIG_SH_HICOSH4
+#if defined CONFIG_ARCH_S3C2410 // add by zhangw
+ lp->force=FORCE_RJ45;
+ lp->auto_neg_cnf=IMM_BIT;
+
+ dev->dev_addr[0]=0x00; /*setMACaddress*/
+ dev->dev_addr[1]=0x00;
+ dev->dev_addr[2]=0x02;
+ dev->dev_addr[3]=0x50;
+ dev->dev_addr[4]=0x10;
+ dev->dev_addr[5]=0x08;
+
+#elif defined CONFIG_SH_HICOSH4
+
+//#ifdef CONFIG_SH_HICOSH4
        if (1) {
                /* For the HiCO.SH4 board, things are different: we don't
                   have EEPROM, but there is some data in flash, so we go
@@ -1280,7 +1334,7 @@
        int i;
        int ret;

-#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
+#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X)&& !defined(CONFIG_ARCH_S3C2410) /* uses irq#1, so this won't work */ // add by zhangw
        if (dev->irq < 2) {
                /* Allow interrupts to be generated by the chip */
 /* Cirrus' release had this: */
@@ -1311,7 +1365,7 @@
        else
 #endif
        {
-#ifndef CONFIG_CS89x0_NONISA_IRQ
+#if !defined(CONFIG_CS89x0_NONISA_IRQ)&& !defined(CONFIG_ARCH_S3C2410)// add by zhangw
                if (((1 << dev->irq) & lp->irq_map) == 0) {
                        printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x/n",
                                dev->name, dev->irq, lp->irq_map);
@@ -1326,6 +1380,10 @@
                writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
 #endif
                write_irq(dev, lp->chip_type, dev->irq);
+#if defined(CONFIG_ARCH_S3C2410) // add by zhangw
+ set_irq_type(dev->irq, IRQT_RISING);
+
+#endif
                ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
                if (ret) {
                        if (net_debug)
@@ -1396,7 +1454,7 @@
        case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
         default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
         }
-#ifdef CONFIG_ARCH_PNX010X
+#if defined(CONFIG_ARCH_PNX010X)  || defined(CONFIG_ARCH_S3C2410) // add by zhangw
        result = A_CNF_10B_T;
 #endif
         if (!result) {

 

  4). make menuconfig进入内核配置,在网络驱动中将 CS89x0 support 选中。

     重新编译内核并烧写,启动成功。

 

6. 打rt补丁

  1). 下载rt补丁:

  2). patch补丁:

    bzip2 -dc patch-2.6.31.12-rt21.bz2 | patch -p1

  3). 检查内核配置,主要参考 http://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO

  4). 增加rtc设备,修改arch/arm/mach-s3c2410/mach-smdk2410.c:

    static struct platform_device *smdk2410_devices[] __initdata =

    { 

     &s3c_device_usb, 

     &s3c_device_lcd, 

     &s3c_device_wdt, 

     &s3c_device_i2c0, 

     &s3c_device_iis, 

     &s3c_device_rtc,

    };

  5). 编译内核,出现编译错误:

    include/asm-generic/cmpxchg-local.h中的wrong_size_cmpxchg的定义体找不到。屏蔽之。

    编译通过,烧之,正常启动成功。

 

 

原创粉丝点击