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

Linux-world-2012-January->16(mini2440 uboot201103 系统移植)->1

2012-01-20 17:40 417 查看
移植过程主要是根据网上一名为csuwzc的高手提供的方法进行的,他不仅提供了方法,还把移植好的u-boot 2011.03放在网上供人下载,真是要感谢他了。移植过程基本顺利。不过还是有一些问题,我将这此记录下来,以供参考。

准备:

说是容易,做起来却挺难。因为编译u-boot要在linux环境下,而不能在我们平时所熟悉的ads下那么直观。首先要建立好交叉编译环境,这个交叉编译环境可以自己来做,不过完全没必要,而且难度也挺大,一般是下载人家编译好的工具。我刚开始在这里就郁闷了很久,现在会了以后觉得原来就是这么简单,在些我把方法说清楚,希望不会再有人为这个问题郁闷了:

1、u-boot-2011.03在mini2440/micro2440上的移植(一)——准备工作

1.1 移植环境

u-boot版本:u-boot-2011-03

Linux平台:Fedora 14

交叉编译工具:arm-linux-gcc-4.3.2

arm开发板:micro2440

CPU:S3C2440

SDRAM:64M

Nor Flash:2M

Nand Flash:256M

网卡:DM9000EP

1.2 移植目标

支持Nand启动

支持Nand读写

支持yaffs写入

支持tftp下载

1.3 删减u-boot文件(可不做)

(1)删除arch目录下除arm目录以外的所有目录

(2)删除arm/cpu目录下除arm920tmulu以外的所有目录

(3)删除arch/arm/cpu/arm920t目录下除s3c24x0目录以外的所有目录(文件不要删)

(4)删除arch/arm/include/asm目录下除arch‐s3c24x0外的所有arch‐xxxx目录(文件不要删)

(5)删除board目录下除samsung目录以外的所有目录

(6)删除board/samsung目录下除smdk2410目录以外的所有目录

(7)删除include/configs目录下除smdk2410.h文件以外的所有头文件。

1.4 建立Micro2440配置

(1)[408@WZC u-boot-2011.03]$ vim boards.cfg

添加一行

micro2440 arm arm920t - samsung s3c24x0

【说明】
我们是基于smdk2410开发板移植,我们仍然将开发板文件建立在board/samsung下

(2)创建板级支持文件

[408@WZC u-boot-2011.06]$ cp -r board/samsung/smdk2410 board/samsung/micro2440

[408@WZC u-boot-2011.06]$ cd board/samsung/micro2440/

[408@WZC micro2440]$ mv smdk2410.c micro2440.c

[408@WZC micro2440]$ vim Makefile

COBJS := smdk2410.o flash.o改为COBJS := micro2440.oflash.o

[408@WZC u-boot-2011.06]$ cd ../../..

[408@WZC u-boot-2011.06]$ cp include/configs/smdk2410.h include/configs/micro2440.h

[408@WZC u-boot-2011.03]$ vim include/configs/micro2440.h

修改一:

#define CONFIG_SYS_PROMPT "[Micro2440]# "
/* Monitor Command Prompt */

修改二:

#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1

#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)

【说明】
如果不定义修改二的内容,编译时就会出错,这是新版本的一个bug。

这里需要注意,直接复制内容到micro2440.h可能导致make通不过,提示有garbage,我想可能是因为windows和Linux回车编码不同造成的。

(3)测试编译环境

[408@WZC u-boot-2011.06]$ make micro2440_config

Configuring for micro2440 board...

[408@WZC u-boot-2011.06]$ make

Generating include/autoconf.mk

Generating include/autoconf.mk.dep

......

......

arm-linux-objcopy -O srec u-boot u-boot.srec

arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin

2、u-boot-2011.03在mini2440/micro2440上的移植(二)——在RAM中运行

2.1 include/configs/micro2440.h

删除

#define CONFIG_S3C2410 1 /* specifically a SAMSUNG S3C2410 SoC */

#define CONFIG_SMDK2410 1 /* on a SAMSUNG SMDK2410 Board */

添加

#define CONFIG_S3C2440 1 /* specifically a SAMSUNG S3C2440 SoC */

#define CONFIG_MICRO2440

#define CONFIG_SKIP_LOWLEVEL_INIT

【说明】
定义CONFIG_SKIP_LOWLEVEL_INIT是因为我们要在RAM中运行,所以要跳过底层的一些初始化代码

2.2 arch/arm/cpu/arm920t/start.S

# if defined(CONFIG_S3C2410)

ldr r1, =0x3ff

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

# if defined(CONFIG_S3C2440)

# define LOCKTIME 0x4C000000

# define MPLLCON 0x4C000004

# define UPLLCON 0x4C000008

# define CLKDIV_VAL 5

# define M_MDIV 0x7f /* XTal=12.0MHz MPLL=405MHz */

# define M_PDIV 2

# define M_SDIV 1

# define U_MDIV 0x38 /* XTal=12.0MHz UPLL=48MHz */

# define U_PDIV 2

# define U_SDIV 2

ldr r1, =0x7fff

ldr r0, =INTSUBMSK

str r1, [r0]

ldr r0,=LOCKTIME /* 设置U_LTIME和M_LTIME */

ldr r1,=0x0fff0fff

str r1,[r0]

ldr r0, =CLKDIVN /* Fclk:Hclk:Pclk = 1:4:8 */

ldr r1, =CLKDIV_VAL

str r1, [r0]

mrc p15, 0, r0, c1, c0, 0 /* 总线模式设为异步模式 */

orr r0, r0, #0xc0000000

mcr p15, 0, r0, c1, c0, 0

ldr r0,=UPLLCON /* 配置UPLL */

ldr r1,=((U_MDIV<<12) + (U_PDIV<<4) + U_SDIV)

str r1,[r0]

nop /* 为确保硬件完成操作,至少需7个时钟周期 */

nop

nop

nop

nop

nop

nop

ldr r0,=MPLLCON /* 配置MPLL */

ldr r1,=((M_MDIV<<12) + (M_PDIV<<4) + M_SDIV)

str r1,[r0]

#else

/* FCLK:HCLK:PCLK = 1:2:4 */

/* default FCLK is 120 MHz ! */

ldr r0, =CLKDIVN

mov r1, #3

str r1, [r0]

#endif /* CONFIG_S3C2440 */

#endif /* CONFIG_S3C24X0 */

2.3 board/samsung/micro2440/micro2440.c

#define FCLK_SPEED 2

#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */

#define M_MDIV 0xC3

#define M_PDIV 0x4

#define M_SDIV 0x1

#elif FCLK_SPEED==1 /* Fout = 202.8MHz */

#define M_MDIV 0xA1

#define M_PDIV 0x3

#define M_SDIV 0x1

#elif FCLK_SPEED==2 /* Fout = 405MHz */

#define M_MDIV 0x7F

#define M_PDIV 0x2

#define M_SDIV 0x1

#endif

#define USB_CLOCK 2

#if USB_CLOCK==0

#define U_M_MDIV 0xA1

#define U_M_PDIV 0x3

#define U_M_SDIV 0x1

#elif USB_CLOCK==1

#define U_M_MDIV 0x48

#define U_M_PDIV 0x3

#define U_M_SDIV 0x2

#elif USB_CLOCK==2 /* Fout = 48MHz */

#define U_M_MDIV 0x38

#define U_M_PDIV 0x2

#define U_M_SDIV 0x2

#endif

int board_init (void)

{

......

gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

......

}

int dram_init (void)

{

......

gd->ram_size = PHYS_SDRAM_1_SIZE;

return 0;

}

【说明】
我在发布资源时用的是MACH_TYPE_MICRO2440,之前的Linux内核中有MICRO2440的机器码,值为2680,但是最近的内核,比如Linux-2.6.39中并没有这个值,虽然我自己是在Micro2440开发板上移植,但机器码还是使用MACH_TYPE_MINI2440,其值为1999。所以下载了资源的网友一定要注意gd->bd->bi_arch_number 的值。

2.4 测试

[408@WZC u-boot-2011.06]$ make

编译完成后将u-boot.bin下载到SDRAM的0x33f80000地址处,u-boot已经能在RAM中运行。

3、u-boot-2011.03在mini2440/micro2440上的移植(三)——支持DM9000

3.1 include/configs/micro2440.h

删除
#define CONFIG_CS8900 /* we have a CS8900 on-board */

#define CONFIG_CS8900_BASE 0x19000300

#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */

#define CONFIG_NETMASK 255.255.255.0

#define CONFIG_IPADDR 10.0.0.110

#define CONFIG_SERVERIP 10.0.0.1
添加
#define CONFIG_CMD_NET

#define CONFIG_DRIVER_DM9000 1

#define CONFIG_DM9000_NO_SROM 1

#define CONFIG_DM9000_BASE 0x20000300

#define DM9000_IO CONFIG_DM9000_BASE

#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
#define CONFIG_CMD_PING

#define CONFIG_ETHADDR 08:00:3e:26:0a:5b //开发板MAC地址

#define CONFIG_NETMASK 255.255.255.0

#define CONFIG_IPADDR 192.168.10.126 //开发板IP地址

#define CONFIG_SERVERIP 192.168.10.124 //主机IP地址

【说明】IP地址要根据实际情况自己设置, CONFIG_SERVERIP用于制定tftp等下载时的主机IP

3.2 board/samsung/micro2440/micro2440.c

int board_eth_init(bd_t *bis)

{

int rc = 0;

#ifdef CONFIG_CS8900

rc = cs8900_initialize(0, CONFIG_CS8900_BASE);

#endif

#ifdef CONFIG_DRIVER_DM9000

rc = dm9000_initialize(bis);

#endif
return rc;

}

#endif

【说明】到此,DM9000已经能初始化了,但是使用ping命令时,串口一直打印 "raise: Signal # 8 caught",下一步直接将该打印语句注释掉,经测试没有影响。

3.3 arch/arm/lib/eabi_compat.c

int raise (int signum)

{

#ifndef CONFIG_MICRO2440

printf("raise: Signal # %d caught/n", signum);

#endif

return 0;

}

【说明】到这一步后可以ping通,但是总是出现了一个"could not establish link"的提示。按照下一步修改,这样修改的结果是第一次不能ping通,需使用Ctrl+C结束,以后即可ping通并使用tftp下载。

3.4 drivers/net/dm9000x.c

static int dm9000_init(struct eth_device *dev, bd_t *bd)

{

……

#ifndef CONFIG_MICRO2440

i = 0;

while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */

udelay(1000);

i++;

if (i == 10000) {

printf("could not establish link/n");

return 0;

}

}

#endif

……

}

static void dm9000_halt(struct eth_device *netdev)

{

DM9000_DBG("%s/n", __func__);

#ifndef CONFIG_MICRO2440

/* RESET devie */

phy_write(0, 0x8000); /* PHY RESET */

DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */

DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */

DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */

#endif

}

4、u-boot-2011.03在mini2440/micro2440上的移植(四)——支持内核启动

分类: Bootloader移植2011-05-30 10:14
287人阅读评论(0)
收藏举报

4.1 include/conskfigs/micro2440.h

添加
#define CONFIG_SETUP_MEMORY_TAGS 1 //如果没有定义这个参数,则uboot参数必须加入men=内存大小

#define CONFIG_INITRD_TAG 1

#define CONFIG_CMDLINE_TAG 1 //设置bootargs出入内核必须

#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"

【说明】到此步后,使用bootm后在"Starting kernel ..."地方死机。按照下一步修改,具体原因尚不理解,需要在以后阅读uboot的源代码。

4.2 arch/arm/lib/bootm.c

static void announce_and_cleanup(void)

{

printf("/nStarting kernel .../n/n");
#ifdef CONFIG_USB_DEVICE

{

extern void udc_disconnect(void);

udc_disconnect();

}

#endif

#ifndef CONFIG_MICRO2440

cleanup_before_linux();

#endif

}

4.3 自动启动内核

如果要自动启动内核,需要在include/conskfigs/micro2440.h定义CONFIG_BOOTCOMMAND,类似如下内容:
#define CONFIG_BOOTCOMMAND "nand read 0x30008000 0x60000 0x300000;bootm 0x30008000"

5、u-boot-2011.03在mini2440/micro2440上的移植(五)——支持Nand Flash

5.1 添加s3c2440_nand.c

[408@WZC u-boot-2011.03]$ touch drivers/mtd/nand/s3c2440_nand.c

[408@WZC u-boot-2011.03]$ cat> drivers/mtd/nand/s3c2440_nand.c

#include <common.h>

#if 0

#define DEBUGN printf

#else

#define DEBUGN(x, args ...) {}

#endif

#include <nand.h>

#include <asm/arch/s3c24x0_cpu.h>

#include <asm/io.h>

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

#define NF_BASE 0x4e000000 //Nand配置寄存器基地址

#define NFCONF __REGi(NF_BASE + 0x0) //偏移后还是得到配置寄存器基地址

#define NFCONT __REGi(NF_BASE + 0x4) //偏移后得到Nand控制寄存器基地址

#define NFCMD __REGb(NF_BASE + 0x8) //偏移后得到Nand指令寄存器基地址

#define NFADDR __REGb(NF_BASE + 0xc) //偏移后得到Nand地址寄存器基地址

#define NFDATA __REGb(NF_BASE + 0x10) //偏移后得到Nand数据寄存器基地址

#define NFMECCD0 __REGi(NF_BASE + 0x14) //偏移后得到Nand主数据区域ECC0寄存器基地址

#define NFMECCD1 __REGi(NF_BASE + 0x18) //偏移后得到Nand主数据区域ECC1寄存器基地址

#define NFSECCD __REGi(NF_BASE + 0x1C) //偏移后得到Nand空闲区域ECC寄存器基地址

#define NFSTAT __REGb(NF_BASE + 0x20) //偏移后得到Nand状态寄存器基地址

#define NFSTAT0 __REGi(NF_BASE + 0x24) //偏移后得到Nand ECC0状态寄存器基地址

#define NFSTAT1 __REGi(NF_BASE + 0x28) //偏移后得到Nand ECC1状态寄存器基地址

#define NFMECC0 __REGi(NF_BASE + 0x2C) //偏移后得到Nand主数据区域ECC0状态寄存器基地址

#define NFMECC1 __REGi(NF_BASE + 0x30) //偏移后得到Nand主数据区域ECC1状态寄存器基地址

#define NFSECC __REGi(NF_BASE + 0x34) //偏移后得到Nand空闲区域ECC状态寄存器基地址

#define NFSBLK __REGi(NF_BASE + 0x38) //偏移后得到Nand块开始地址

#define NFEBLK __REGi(NF_BASE + 0x3c) //偏移后得到Nand块结束地址

#define S3C2440_NFCONT_nCE (1<<1)

#define S3C2440_ADDR_NALE 0x0c

#define S3C2440_ADDR_NCLE 0x08

ulong IO_ADDR_W = NF_BASE;

static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)

{

struct nand_chip *chip = mtd->priv;

DEBUGN("hwcontrol(): 0x%02x 0x%02x/n", cmd, ctrl);

if (ctrl & NAND_CTRL_CHANGE)

{

IO_ADDR_W = NF_BASE;

if (!(ctrl & NAND_CLE)) //要写的是地址

IO_ADDR_W |= S3C2440_ADDR_NALE;

if (!(ctrl & NAND_ALE)) //要写的是命令

IO_ADDR_W |= S3C2440_ADDR_NCLE;

if (ctrl & NAND_NCE)

NFCONT &= ~S3C2440_NFCONT_nCE; //使能nand flash

else

NFCONT |= S3C2440_NFCONT_nCE; //禁止nand flash

}

if (cmd != NAND_CMD_NONE)

writeb(cmd,(void *)IO_ADDR_W);

}

static int s3c2440_dev_ready(struct mtd_info *mtd)

{

DEBUGN("dev_ready/n");

return (NFSTAT & 0x01);

}

int board_nand_init(struct nand_chip *nand)

{

u_int32_t cfg;

u_int8_t tacls, twrph0, twrph1;

struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power();

DEBUGN("board_nand_init()/n");

tacls = 1;

twrph0 = 2;

twrph1 = 1;

cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);

NFCONF = cfg;

cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);

NFCONT = cfg;

/* initialize nand_chip data structure */

nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;

/* read_buf and write_buf are default */

/* read_byte and write_byte are default */

/* hwcontrol always must be implemented */

nand->cmd_ctrl = s3c2440_hwcontrol;

nand->dev_ready = s3c2440_dev_ready;

return 0;

}

【说明】
经过几次测试,yaffs2写入不太稳定,修改上面红色部分后,yaffs2写入正常。

5.2 drivers/mtd/nand/Makefile

COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

5.3 include/conskfigs/micro2440.h

添加

#define CONFIG_MTD_DEVICE

#define CONFIG_NAND_S3C2440

#define CONFIG_CMD_NAND

#if defined(CONFIG_CMD_NAND)

#define CONFIG_SYS_NAND_BASE 0x4E000000 //Nand配置寄存器基地址

#define CONFIG_SYS_MAX_NAND_DEVICE 1

#define CONFIG_MTD_NAND_VERIFY_WRITE 1

#endif

#define CONFIG_ENV_IS_IN_NAND 1

#define CONFIG_ENV_OFFSET 0x40000 //将环境变量保存到nand中的0x40000位置

#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */

6、u-boot-2011.03在mini2440/micro2440上的移植(六)——支持yaffs下载

6.1 include/conskfigs/micro2440.h

添加

#define CONFIG_CMD_NAND_YAFFS

【说明】
本人在阅读cmd_nand.c时发现u-boot-2011.03已经支持yaffs写入,只需添加如上定义即可,但实际写入错误,再阅读源代码,发现只要按下一步修改即可,虽然这是最简单的方法,但似乎并不是最优的方法。

6.2 drivers/mtd/nand/nand_util.c

int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,

u_char *buffer, int withoob)

{

……

if (need_skip < 0) {

printf ("Attempt to write outside the flash area/n");

*length = 0;

return -EINVAL;

}

if (!need_skip && !withoob) {

……

}

while (left_to_write > 0) {

……

#ifdef CONFIG_CMD_NAND_YAFFS

if (withoob) {

……

ops.len = pagesize;

ops.ooblen = nand->oobsize;

ops.mode = MTD_OOB_RAW;

ops.ooboffs = 0;

pages = write_size / pagesize_oob;

for (page = 0; page < pages; page++) {

ops.datbuf = p_buffer;

ops.oobbuf = ops.datbuf + pagesize;

rval = nand->write_oob(nand, offset, &ops);

if (rval)

break;

offset += pagesize;

p_buffer += pagesize_oob;

}

}

……

}

6.3 下载yaffs镜像

下载yaffs镜像的时候要注意分区的第一块不能写,比如友善之臂的默认分区如下:

Number of partitions: 4

name : offset size flag

------------------------------------------------------------

vivi : 0x00000000 0x00040000 0

param : 0x00040000 0x00020000 0

kernel : 0x00060000 0x00500000 0

root : 0x00560000 0x3fa80000 0

也就是说yaffs镜像所在分区的起始地址在0x560000,因此使用nand write.yaffs命令下载yaffs时要写的地址为0x560000 + 0x20000 (Nand Flash每块的大小)= 0x580000,即下载命令类似如下

tftp 0x30008000 uImage

nand write.yaffs 0x30008000 0x580000
0x300000

7、u-boot-2011.03在mini2440/micro2440上的移植(七)——支持Nand Flash启动

7.1 创建nand_read.c

【注意】

本程序只能用于读取2K/页的Nand。本人的Micro2440上的Nand Flash为256M,型号为K9F2G08

[408@WZC u-boot-2011.06]$ touch board/samsung/micro2440/nand_read.c

[408@WZC u-boot-2011.06]$ cat> board/samsung/micro2440/nand_read.c

#define rNFCONF (*(volatile unsigned *)0x4E000000)

#define rNFCONT (*(volatile unsigned *)0x4E000004)

#define rNFCMD (*(volatile unsigned *)0x4E000008)

#define rNFADDR (*(volatile unsigned *)0x4E00000C)

#define rNFDATA8 (*(volatile unsigned char*)0x4E000010)

#define rNFSTAT (*(volatile unsigned *)0x4E000020)

#define CMD_READ1 0x00 /* 页读命令周期1 */

#define CMD_READ2 0x30 /* 页读命令周期2 */

#define CMD_RESET 0xFF /* 复位 */

#define NF_CMD(cmd) {rNFCMD=(cmd);} /* 写命令 */

#define NF_ADDR(addr) {rNFADDR=(addr);} /* 写地址 */

#define NF_RDDATA8() (rNFDATA8) /* 读8位数据 */

#define NF_nFCE_L() {rNFCONT&=~(1<<1);} /* 片选使能 */

#define NF_nFCE_H() {rNFCONT|=(1<<1);} /* 片选禁用 */

#define NF_WAITRB() {while(!(rNFSTAT&(1<<1)));} /* 等待就绪 */

#define NF_CLEAR_RB() {rNFSTAT |= (1<<2);} /* 清除就绪/忙位 */

#define NF_DETECT_RB() {while(!(rNFSTAT&(1<<2)));} /* 等待就绪 */

#define TACLS 1

#define TWRPH0 2

#define TWRPH1 1

void delay(int i)

{

while(i-->0);

}

void Nand_Init(void)

{

rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);

rNFCONT = (1<<4)|(1<<1)|(1<<0);

}

static void Nand_Reset(void)

{

NF_nFCE_L(); /* 片选使能 */

NF_CLEAR_RB(); /* 清除就绪/忙位 */

NF_CMD(CMD_RESET); /* 写复位命令 */

NF_DETECT_RB(); /* 等待就绪 */

NF_nFCE_H(); /* 片选禁用 */

}

unsigned char Nand_ReadPage(const int page, unsigned char * const buffer)

{

int i;

Nand_Reset();

NF_nFCE_L();

NF_CLEAR_RB();

NF_CMD(CMD_READ1);

NF_ADDR(0x0);

NF_ADDR(0x0);

NF_ADDR(page&0xff);

NF_ADDR((page>>8)&0xff);

NF_ADDR((page>>16)&0xff);

NF_CMD(CMD_READ2);

NF_DETECT_RB();

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

{

buffer[i] = NF_RDDATA8();

}

NF_nFCE_H();

}

int nand_read(int start_page, int read_pages, unsigned char *buffer)

{

int i;

Nand_Init();

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

{

Nand_ReadPage(start_page, buffer + 2048*i);

start_page++;

}

return 0;

}

7.2 board/samsung/micro2440/Makefile

COBJS := micro2440.o flash.o nand_read.o

7.3 arch/arm/cpu/arm920t/u-boot.lds

.text :

{

arch/arm/cpu/arm920t/start.o (.text)

board/samsung/micro2440/libmicro2440.o (.text)

*(.text)

}

【说明】
如果是在RAM中运行,一定要删去board/samsung/micro2440/libmicro2440.o (.text),否则在RAM中也不能运行。原因尚不理解,需要阅读代码。

7.4 arch/arm/cpu/arm920t/start.S

下面红色部分是添加的部分,黑色的代码用于定位。

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

bl cpu_init_crit

#endif

#ifdef CONFIG_S3C2440_NAND_BOOT

ldr sp, =0x30008000

ldr r0, =0x0;

ldr r1, _end_ofs

mov r1, r1, LSR #11

add r1, r1, #1

ldr r2, =(CONFIG_SYS_TEXT_BASE)

bl nand_read

ldr pc, =relocations

#endif

......

......

copy_loop:

ldmia r0!, {r9-r10} /* copy from source address [r0] */

stmia r1!, {r9-r10} /* copy to target address [r1] */

cmp r0, r2 /* until source end address [r2] */

blo copy_loop

#ifdef CONFIG_S3C2440_NAND_BOOT

relocations:

ldr r6, =CONFIG_SYS_TEXT_BASE

#endif

#ifndef CONFIG_PRELOADER

/*

* fix .rel.dyn relocations

*/

......

......

clbss_l:str r2, [r0] /* clear loop... */

add r0, r0, #4

cmp r0, r1

bne clbss_l

bl coloured_LED_init

bl red_LED_on

#endif

#ifdef CONFIG_S3C2440_NAND_BOOT

ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)

bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

ldr r0,=0x00000000

ldr pc, =board_init_f

#endif

/*

* We are done. Do not return, instead branch to second part of board

* initialization, now running from RAM.

*/

#ifdef CONFIG_NAND_SPL

7.5 include/configs/micro2440.h

#define CONFIG_S3C2440_NAND_BOOT
/* #define CONFIG_SKIP_LOWLEVEL_INIT */

【说明】
由于要在Nand Flash中运行,所以需要注释掉#define CONFIG_SKIP_LOWLEVEL_INIT

7.6 arch/arm/lib/board.c

void board_init_f (ulong bootflag)

{

......

gd->mon_len = _bss_end_ofs + 0x100000; /* why */

......

/* relocate_code (addr_sp, id, addr); */
#ifdef CONFIG_S3C2440_NAND_BOOT /*add by wzc*/
__asm__ __volatile__("mov sp,%0"::"r"(addr_sp):"sp");/*add by wzc*/
board_init_r(id, addr);
#else
relocate_code (addr_sp, id, addr);
/* NOTREACHED - relocate_code() does not return */
#endif
}

【说明】

至于gd->mon_len = _bss_end_ofs + 0x100000;我也不理解,需要阅读源代码才能解释。

7.7 下载到Nand Flash

到这里应该就可以从Nand Flash启动了。


8、u-boot-2011.03在mini2440/micro2440上的移植(八)——结束语及资源下载

8.1 其他

(1)支持使用向上的箭头显示上一条命令

include/configs/micro2440.h

#define CONFIG_CMDLINE_EDITING

#ifdef CONFIG_CMDLINE_EDITING

#undef CONFIG_AUTO_COMPLETE

#else

#define CONFIG_AUTO_COMPLETE

#endif

(2)使用自己的环境变量

common/env_common.c文件中的default_environment[]数组,格式如:

"b=" "nand read 0x30008000 0x60000 0x300000;bootm 0x30008000" "/0"

8.2 下载

(1)按照本文移植后的uboot已经上传,地址为http://download.csdn.net/detail/doublewei1/4029659 或者
http://download.csdn.net/source/3325396

(2)再次提醒:我在发布资源时用的是MACH_TYPE_MICRO2440,之前的Linux内核中有MICRO2440的机器码,值为2680,但是最近的内核,比如Linux-2.6.39中并没有这个值,虽然我自己是在Micro2440开发板上移植,但机器码还是使用MACH_TYPE_MINI2440,其值为1999。所以下载了资源的网友一定要注意gd->bd->bi_arch_number 的值。该值定义在board/samsung/micro2440/micro2440.c中的int
board_init (void)函数中使用。具体内容在本博客第二篇。

(3)经过几次测试,yaffs2写入不太稳定,修改适当的时序后,yaffs2写入正常。具体参见本博客的第五篇。

(4)本文可能有遗漏的地方,但本资源可以编译

make micro2440_config

make CROSS_COMPILE=arm-linux-

现在系统就已经移植完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: