您的位置:首页 > 运维架构 > Linux

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

2010-02-24 09:24 411 查看
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的定义体找不到。屏蔽之。
    编译通过,烧之,正常启动成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: