u-boot 2014.01移植手册
移植环境:
JZ2440 v2
arm-linux-gcc 4.3.2
u-boot-2014.01
参考资料:
韦东山linux开发视频
本uboot工程的补丁下载:
http://download.csdn.net/detail/callmefriend/7089867
原文地址:
http://blog.csdn.net/callmefriend/article/details/21954279
1、增加对2440的支持。
a、修改boards.cfg,仿照2410,增加2440.
b、在board/samsung/目录下执行:cp smdk2410/ smdk2440 -rf。将原来S3C2410单板下的所有文件拷贝到2440下。
c、在include/configs下执行:cp smdk2410.h smdk2440.h。拷贝原来2410的配置文件。
d、发现顶层makefiel的一个小bug:make distclean的时候,不删除ln -s生成的符号链接文件;这个不影响编译,但是显得不协调。改进办法:
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk\
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp\
$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep\
$(obj)include/spl-autoconf.mk \
$(obj)include/tpl-autoconf.mk \
$(obj)arch/${ARCH}/include/asm/arch \
$(obj)arch/${ARCH}/include/asm/proc
2、修改时钟
在start.S中增加对时钟的初始化,并在board\samsung\smdk2440\smdk2410.c的intboard_early_init_f(void)里取消对时钟初始化的代码。
start.S:
ldr r0, =0x4c000014
// mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8
str r1, [r0]
/* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */
orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode”*/
mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */
#define S3C2440_MPLL_400MHZ((0x5c<<12)|(0x01<<4)|(0x01))
/* MPLLCON = S3C2440_MPLL_200MHZ */
ldr r0, =0x4c000004
ldr r1, =S3C2440_MPLL_400MHZ
str r1, [r0]
smdk2410.c:
// writel(0xFFFFFF,&clk_power->locktime);
/* configure MPLL */
// writel((M_MDIV <<12) + (M_PDIV << 4) + M_SDIV,
// &clk_power->mpllcon);
3、初始化内存
在lowlevel_init.S里修改SMRDATA:对应的数值:
SMRDATA:
.long 0x22011110 //BWSCON
.long 0x00000700 //BANKCON0
.long 0x00000700 //BANKCON1
.long 0x00000700 //BANKCON2
.long 0x00000700 //BANKCON3
.long 0x00000740 //BANKCON4
.long 0x00000700 //BANKCON5
.long 0x00018005 //BANKCON6
.long 0x00018005 //BANKCON7
.long 0x008C04F4 // REFRESH
.long 0x000000B1 //BANKSIZE
.long 0x00000030 //MRSRB6
.long 0x00000030 //MRSRB7
4、修改链接选项
在arch/arm/config.mk里,取消-pie选项
在arch/arm/cpu/u-boot.lds下增加如下两行:
board/samsung/smdk2440/built-in.o(.text*)
arch/arm/cpu/built-in.o (.text*)
修改smdk2440.h里的CONFIG_SYS_TEXT_BASE的值为:
#define CONFIG_SYS_TEXT_BASE 0x33f00000
至此,uboot应该能初始化时钟和内存。
5、修改重定位代码
a、在addr的最后位置,去掉
// addr -= gd->mon_len;
// addr &= ~(4096- 1);
addr = CONFIG_SYS_TEXT_BASE;
b、在start.S里bl cpu_init_crit后增加nand初始化和copy代码,并清BSS,同时在增加copynand文件的源文件init.c:
/* NAND FLASH控制器 */
#define NFCONF(*((volatile unsigned long *)0x4E000000))
#define NFCONT(*((volatile unsigned long *)0x4E000004))
#define NFCMMD(*((volatile unsigned char *)0x4E000008))
#define NFADDR(*((volatile unsigned char *)0x4E00000C))
#define NFDATA(*((volatile unsigned char *)0x4E000010))
#define NFSTAT(*((volatile unsigned char *)0x4E000020))
/* GPIO */
#define GPHCON (*(volatile unsigned long*)0x56000070)
#define GPHUP (*(volatile unsigned long*)0x56000078)
/* UART registers*/
#define ULCON0 (*(volatile unsigned long*)0x50000000)
#define UCON0 (*(volatile unsigned long*)0x50000004)
#define UFCON0 (*(volatile unsigned long*)0x50000008)
#define UMCON0 (*(volatile unsigned long*)0x5000000c)
#define UTRSTAT0 (*(volatile unsigned long*)0x50000010)
#define UTXH0 (*(volatile unsigned char*)0x50000020)
#define URXH0 (*(volatile unsigned char*)0x50000024)
#define UBRDIV0 (*(volatile unsigned long *)0x50000028)
#defineTXD0READY (1<<2)
voidnand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);
static intisBootFromNorFlash(void)
{
volatile int *p = (volatile int *)0;
int val;
val = *p;
*p = 0x12345678;
if (*p == 0x12345678)
{
/* 写成功,是nand启动 */
*p = val;
return 0;
}
else
{
/* NOR不能像内存一样写 */
return 1;
}
}
/*
*src=0; dest=0x33f80000;len=0x73250
**/
voidcopy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
int i = 0;
/* 如果是NOR启动 */
if (isBootFromNorFlash())
{
while (i < len)
{
dest[i] = src[i];
i++;
}
}
else
{
//nand_init();
nand_read_ll((unsignedint)src, dest, len);
}
}
void clear_bss(void)
{
extern int __bss_start, __bss_end;
int *p = &__bss_start;
for (; p < &__bss_end; p++)
*p = 0;
}
voidnand_init_ll(void)
{
#define TACLS 0
#define TWRPH0 1
#define TWRPH1 0
/* 设置时序 */
NFCONF =(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
/* 使能NAND Flash控制器,初始化ECC,禁止片选 */
NFCONT =(1<<4)|(1<<1)|(1<<0);
}
static voidnand_select(void)
{
NFCONT &= ~(1<<1);
}
static voidnand_deselect_ll(void)
{
NFCONT |= (1<<1);
}
static voidnand_cmd(unsigned char cmd)
{
volatile int i;
NFCMMD = cmd;
for (i = 0; i < 10; i++);
}
static voidnand_addr(unsigned int addr)
{
unsigned int col = addr % 2048;
unsigned int page = addr / 2048;
volatile int i;
NFADDR = col & 0xff;
for (i = 0; i < 10; i++);
NFADDR = (col >> 8) & 0xff;
for (i = 0; i < 10; i++);
NFADDR = page & 0xff;
for (i = 0; i < 10; i++);
NFADDR = (page >> 8) & 0xff;
for (i = 0; i < 10; i++);
NFADDR = (page >> 16) & 0xff;
for (i = 0; i < 10; i++);
}
static voidnand_wait_ready_ll(void)
{
while (!(NFSTAT & 1));
}
static unsigned charnand_data(void)
{
return NFDATA;
}
/*
*src=0; dest=0x33f80000;len=0x73250
*/
voidnand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)
{
int col = addr % 2048;
int i = 0;
/* 1. 选中 */
nand_select();
while (i < len)
{
/* 2. 发出读命令00h */
nand_cmd(0x00);
/* 3. 发出地址(分5步发出) */
nand_addr(addr);
/* 4. 发出读命令30h */
nand_cmd(0x30);
/* 5. 判断状态 */
nand_wait_ready_ll();
/* 6. 读数据 */
for (; (col < 2048)&& (i < len); col++)
{
buf[i] =nand_data();
i++;
addr++;
}
col = 0;
}
/* 7. 取消选中 */
nand_deselect_ll();
}
c、在crt0.S里删除如下红色代码:
adr lr, here
ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off*/
add lr, lr, r0
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr*/
b relocate_code
here:
/* Set up final (full)environment */
bl c_runtime_cpu_setup /* we still call old routinehere */
ldr r0, =__bss_start /* this is auto-relocated!*/
ldr r1, =__bss_end /* this is auto-relocated! */
mov r2, #0x00000000 /* prepare zero to clear BSS*/
clbss_l:
cmp r0, r1 /* whilenot at end of BSS */
strlo r2, [r0] /* clear 32-bit BSS word */
addlo r0, r0, #4 /* move to next */
blo clbss_l
/* call board_init_r(gd_t *id, ulong dest_addr)*/
mov r0, r9 /* gd_t */
ldr r1, =CONFIG_SYS_TEXT_BASE /* dest_addr */
/* call board_init_r */
ldr pc, =board_init_r/* this is auto-relocated! */
6、修改串口
在include/configs/smdk2440.h里取消CONFIG_S3C2410
CONFIG_YAFFS2
CONFIG_CMD_NAND宏定义,并增加如下宏:
#define CONFIG_S3C2440
7、测试输出
目前为止:修改了时钟、内存、串口、-pie选项、lds文件。得到的输出为:
8、支持nand 读写。
8.1 在smdk2440.h中定义:#defineCONFIG_CMD_NAND
8.2 在driver/mtd/nand/下的makefile中增加:obj-$(CONFIG_NAND_S3C2440) +=s3c2440_nand.o
并将s3c2410_nand.c拷贝为s3c2440_nand.c。
8.3 将s3c2440_nand.c里面的2410全部替换为2440。
添加函数3c2440_nand_select();并在board_nand_init()里修改nand的初始化参数,添加writel((1<<4)|(1<<1)|(1<<0), &nand_reg->nfcont);
nand->select_chip = s3c2440_nand_select;。
修改s3c2440_hwcontrol():
static void s3c2440_hwcontrol(structmtd_info *mtd, int dat, unsigned int ctrl)
{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
if (ctrl & NAND_CLE)
{
/* 发命令 */
writeb(dat, &nand->nfcmd);
}
else if(ctrl & NAND_ALE)
{
/* 发地址 */
writeb(dat, &nand->nfaddr);
}
}
8.4 在smdk2440.h里添加:
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET0x40000
#define CONFIG_ENV_SIZE0x20000
9、修改网卡
9.1 修改配置支持DM9000
smdk2440.h:
增加以下定义:
#define CONFIG_DRIVER_DM9000/* we have a DM9000 on-board */
#define CONFIG_DM9000_BASE0x20000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA(CONFIG_DM9000_BASE + 4)
#define CONFIG_DM9000_NO_SROM
取消关于CS8900的定义。
#define CONFIG_CS8900/* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE0x19000300
#define CONFIG_CS8900_BUS16/* the Linux driver does accesses as shorts */
9.2 修改初始化文件smdk2410.c
在board_eth_init()中增加:
#ifdef CONFIG_DRIVER_DM9000
rc = dm9000_initialize(bis);
#endif
目前为止,网卡和nand读写均可以进行。
10、设置环境变量
10.1 在smdk2440.h中添加:
#define CONFIG_BOOTARGS"console=ttySAC0 root=/dev/mtdblock3"
#define CONFIG_BOOTCOMMAND"nand read 30000000 60000 200000;bootm 30000000"
10.2 在smdk2440.h修改参数区配置:
#if 0
#define CONFIG_ENV_ADDR(CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE0x10000
/* allow to overwriteserial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#endif
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET0x40000
#define CONFIG_ENV_SIZE0x20000
#define CONFIG_ENV_RANGECONFIG_ENV_SIZE
10.3 设置mtd parts参数
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define MTDIDS_DEFAULT"nand0=jz2440 V2-0"
#define MTDPARTS_DEFAULT\
"mtdparts=jz2440 V2-0:512k(bootloader),"\
"128k(params)\"
"2m(kernel)," \
"-(rootfs)"
10.4在smdk2410.c的board_init()中,修改bi_arch_number为MACH_TYPE_S3C2440。
11、测试烧写jffs2文件系统
fs_mini.jffs2:
set bootargs console=ttySAC0root=/dev/mtdblock3 rootfstype=jffs2
tftp 30000000 fs_mini.jffs2
nand erase 260000 $size
nand write.jffs2 30000000260000 $size
启动OK。
12、支持yaffs2文件系统烧写
改进措施:
if (!need_skip && !(flags &WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB))
ops.mode = MTD_OOB_RAW;
再次编译烧写,成功启动内核和fs。
13、支持NOR Flash
在drivers\mtd\jedec_flash.c文件中jedec_table[]数组中增加:
{
.mfr_id = (u16)MX_MANUFACT, /* 厂家ID */
.dev_id = 0X2249, /* 设备ID */
.name = "MXIC MT29LV160DB",
.uaddr = { /* NORflash看到解锁地址 */
[1] =MTD_UADDR_0x0555_0x02AA /* x16 */
},
.DevSize = SIZE_2MiB, /* 总大小 */
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 4,
.regions = {
ERASEINFO(16*1024,1),
ERASEINFO(8*1024,2),
ERASEINFO(32*1024,1),
ERASEINFO(64*1024, 31),
}
},
编译,烧进Nor Flash:
至此,uboot已经全部一致完毕。