移植过程主要是根据网上一名为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﹕3c24x0外的所有arch﹛xxx目录(文件不要删)
(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.o?flash.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,=CLKDIVN /* Fclk:Hclk:Pclk = 1:4:8 */
????ldr r1,=CLKDIV_VAL
????str r1,[r0]
?
????mrc p15,r0,c1,c0,0 /* 总线模式设为异步模式 */
????orr r0,#0xc0000000
????mcr p15,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,#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,#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); #elserelocate_code (addr_sp,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/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-
现在系统就已经移植完成了。