Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4250570
  • 博文数量: 241
  • 博客积分: 15936
  • 博客等级: 上将
  • 技术积分: 25293
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 11:22
个人简介

Fedora-ARM

文章分类
文章存档

2016年(3)

2014年(1)

2013年(3)

2012年(50)

2011年(61)

2010年(26)

2009年(27)

2008年(21)

2007年(49)

分类: LINUX

2007-10-13 23:51:11

移植UBoot.1.2.0到友善之臂SBC2440V4S3C2440AL)(2)


接上篇:【置顶】移植U-Boot.1.2.0到友善之臂SBC2440V4(S3C2440AL)(1)

 

8、在个文件中添加“CONFIG_S3C2440”,使得原来s3c2410的代码可以编译进来。

1/include/common.h文件的第454行:

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X) || defined(CONFIG_S3C2440)

2/include/s3c24x0.h文件的第859599110148404行:

#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

3/cpu/arm920t/s3c24x0/interrupts.c文件的第33行:

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

38行:#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

4/cpu/arm920t/s3c24x0/serial.c文件的第22行:

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

26行:#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

void serial_setbrg (void)

{

         S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);

         int i;

         unsigned int reg = 0;

 

         /* value is calculated so : (int)(PCLK/16./baudrate) -1 */

         reg = get_PCLK() / (16 * gd->baudrate) - 1;

         /* FIFO enable, Tx/Rx FIFO clear */

         uart->UFCON = 0x00;

         uart->UMCON = 0x0;

         /* Normal,No parity,1 stop,8 bit */

         uart->ULCON = 0x3;

......

}

5/cpu/arm920t/s3c24x0/speed.c文件的第33行:

#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)

37:#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

顺便修改源代码,以匹配s3c2440

static ulong get_PLLCLK(int pllreg)
{
   ......

    m = ((r & 0xFF000) >> 12) + 8;
    p = ((r & 0x003F0) >> 4) + 2;
    s = r & 0x3;
//tekkaman
#if defined(CONFIG_S3C2440)
   if (pllreg == MPLL)
    return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
    else if (pllreg == UPLL)
#endif
//tekkaman

   
return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
}

......

/* return FCLK frequency */

ulong get_FCLK(void)

{

    return(get_PLLCLK(MPLL));

}

 

/* return HCLK frequency */

ulong get_HCLK(void)

{

    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

 

      

              if (clk_power->CLKDIVN & 0x6)   

                            {

                            if ((clk_power->CLKDIVN & 0x6)==2)        return(get_FCLK()/2);

                            if ((clk_power->CLKDIVN & 0x6)==6)        return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);        

                            if ((clk_power->CLKDIVN & 0x6)==4)        return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);        

                            return(get_FCLK());

                            }

 

              else       {

                            return(get_FCLK());

                            }

}

......

6/cpu/arm920t/s3c24x0/usb_ohci.c文件的第45行:

#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

(i2c的文件还没修改,因为没用到)

7/rtc/s3c24x0_rtc.c文件的第35行:

#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

 

在个文件中添加“defined(CONFIG_tekkaman2440)”,使得原来SBC2410X的代码可以编译进来。

1/cpu/arm920t/s3c24x0/interrupts.c文件的第181行: 

    defined(CONFIG_VCMA9) || defined(CONFIG_tekkaman2440)

 

9、 include/linux/mtd/nand_ids.h的结构体nand_flash_ids加入

static struct nand_flash_dev nand_flash_ids[] = {

......
    {"Samsung KM29N16000",NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000, 0},
   
{"Samsung K9F1208U0B",  NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
    {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0},
......

};

 

 

10、修改/lib_arm中的board.c。

......

#include
#include
#include
#include
#include
#include
#include

 

......

 

static int display_banner (void)
{      

         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

         gpio->GPBDAT = 0x100;  //tekkamanninja

//在串口初始化和console初始化完成,串口输出信息之前,LED1LED2LED3会亮起!

    printf ("\n\n%s\n\n", version_string);
    debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
           _armboot_start, _bss_start, _bss_end);
   
printf ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",    //tekkaman
        _armboot_start, _bss_start, _bss_end);      //tekkaman
#ifdef CONFIG_MODEM_SUPPORT
    debug ("Modem Support enabled\n");
#endif
#ifdef CONFIG_USE_IRQ
    debug ("IRQ Stack: %08lx\n", IRQ_STACK_START);
    debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif

    return (0);
}

 

......

void start_armboot (void)

{

         init_fnc_t **init_fnc_ptr;

         char *s;

#ifndef CFG_NO_FLASH

         ulong size;

#endif

#if defined(CONFIG_VFD) || defined(CONFIG_LCD)

         unsigned long addr;

#endif

         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

......

         gpio->GPBDAT = 0x0;  //tekkamanninja

//在进入命令提示符之前,四个LED会同时亮起!

         /* main_loop() can return to retry autoboot, if so just run it again. */

         for (;;) {

                   main_loop ();

         }

 

         /* NOTREACHED - no way out of command loop except booting */

}


11、 修改common/env_nand.c

......
#ifdef CONFIG_INFERNO
#error CONFIG_INFERNO not supported yet
#endif

int nand_legacy_rw (struct nand_chip* nand, int cmd,
        size_t start, size_t len,
        size_t * retlen, u_char * buf);
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, size_t len, int clean);

/* info for NAND chips, defined in drivers/nand/nand.c */
extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE];

......

#else /* ! CFG_ENV_OFFSET_REDUND */
int saveenv(void)
{
    ulong total;
    int ret = 0;

    puts ("Erasing Nand...");
    //if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))

if (nand_legacy_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))
        return 1;


    puts ("Writing to Nand... ");
    total = CFG_ENV_SIZE;
    //ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

ret = nand_legacy_rw(nand_dev_desc + 0,

0x00 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE,

&total, (u_char*)env_ptr);


    if (ret || total != CFG_ENV_SIZE)
        return 1;

    puts ("done\n");
    return ret;
......
#else /* ! CFG_ENV_OFFSET_REDUND */
/*
 * The legacy NAND code saved the environment in the first NAND device i.e.,
 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
 */
void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
    ulong total;
    int ret;

    total = CFG_ENV_SIZE;
    //ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
    ret = nand_legacy_rw(nand_dev_desc + 0, 0x01 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr);

......



12、 在/board/tekkaman/tekkaman2440/tekkaman2440.c文件的末尾添加对Nand Flash 的初始化函数(在后面Nand Flash的操作都要用到)

u-boot运行至第二阶段进入start_armboot()函数。其中nand_init()函数是对nand flash的最初初始化函数。Nand_init()函数在两个文件中实现。其调用与CFG_NAND_LEGACY宏有关,如果没有定义这个宏,系统调用 drivers/nand/nand.c中的nand_init();否则调用自己在board/tekkaman/tekkaman2440/tekkaman2440.c中的nand_init()函数。这里我选择第二种方式。

 

#if (CONFIG_COMMANDS & CFG_CMD_NAND)
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;

static inline void NF_Conf(u16 conf)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCONF = conf;
}

static inline void NF_Cont(u16 cont)

{

S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCONT = cont;

}

static inline void NF_Cmd(u8 cmd)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCMD = cmd;
}

static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}

static inline void NF_Addr(u8 addr)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFADDR = addr;
}

static inline void NF_SetCE(NFCE_STATE s)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

switch (s) {
case NFCE_LOW:
nand->NFCONT &= ~(1<<1);
break;

case NFCE_HIGH:
nand->NFCONT |= (1<<1);
break;
}
}

static inline void NF_WaitRB(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

while (!(nand->NFSTAT & (1<<0)));
}

static inline void NF_Write(u8 data)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFDATA = data;
}

static inline u8 NF_Read(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

return(nand->NFDATA);
}

static inline void NF_Init_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

nand->NFCONT |= (1<<4);
}

static inline u32 NF_Read_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

return(nand->NFECC);
}

#endif


#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern ulong nand_probe(ulong physadr);


static inline void NF_Reset(void)
{
int i;

NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}


static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif

       NF_Conf((TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4));

       NF_Cont((1<<6)|(1<<4)|(1<<1)|(1<<0));
/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */

NF_Reset();
}

void
nand_init(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

NF_Init();
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif

 

 

12 在/include/s3c24x0.h中加入2440 的NAND FLASH 寄存器定义和CAMDIVN定义:

......

typedef struct {

         S3C24X0_REG32   LOCKTIME;

         S3C24X0_REG32   MPLLCON;

         S3C24X0_REG32   UPLLCON;

         S3C24X0_REG32   CLKCON;

         S3C24X0_REG32   CLKSLOW;

         S3C24X0_REG32   CLKDIVN;

         S3C24X0_REG32   CAMDIVN;

} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;

......

#if defined(CONFIG_S3C2410)

/* NAND FLASH (see S3C2410 manual chapter 6) */

typedef struct {

         S3C24X0_REG32   NFCONF;

         S3C24X0_REG32   NFCMD;

         S3C24X0_REG32   NFADDR;

         S3C24X0_REG32   NFDATA;

         S3C24X0_REG32   NFSTAT;

         S3C24X0_REG32   NFECC;

} /*__attribute__((__packed__))*/ S3C2410_NAND;

#endif

#if defined (CONFIG_S3C2440)

/* NAND FLASH (see S3C2440 manual chapter 6) */

typedef struct {

         S3C24X0_REG32   NFCONF;

         S3C24X0_REG32   NFCONT;

         S3C24X0_REG32   NFCMD;

         S3C24X0_REG32   NFADDR;

         S3C24X0_REG32   NFDATA;

         S3C24X0_REG32   NFMECC0;

         S3C24X0_REG32   NFMECC1;

         S3C24X0_REG32   NFSECC;

         S3C24X0_REG32   NFSTAT;

         S3C24X0_REG32   NFESTAT0;

         S3C24X0_REG32   NFESTAT1;

         S3C24X0_REG32   NFECC;

} /*__attribute__((__packed__))*/ S3C2410_NAND;

#endif

 

 

三、交叉编译UBoot
UBoot的根目录下
$make
一阵English飘过~~~~~~~~~~~~~~~~~~~~~~~

 

SBC2440V4是双网卡设计,DM9000网卡移植请看: 【置顶】移植U-Boot.1.2.0到友善之臂SBC2440V4(补:DM9000网卡移植),这篇文章的移植使用CS8900网卡。tftp功能是可用的,我测试过!
由于时间关系,我没有复查,可能有遗漏。如果按上面的修改,出现了错误,请及时联系我,我会及时更正!
阅读(13324) | 评论(1) | 转发(9) |
给主人留下些什么吧!~~