U-Boot移植
U-Boot移植过程记录
一些提示:
1.交叉编译环境要事先搭建好
2.解释一下一段代码
smdk2400_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2400 NULL s3c24x0
arm,就表示现在用的是 CPU 的架构是 arm 体系结构。
arm920t,指明这是 cpu 的内核类型,它对应于 cpu/arm920t 目录。
Smdk2410,这是开发板的型号,它的目录在 board/smdk2410 目录下。
NULL,表示开发者或者经销商是谁(vender)
S3c24x0,表示开发板上的 cpu 是啥。
正文:
1.删除用不到的目录
根目录下的lib_文件夹,保留lib_arm ,lib_generic即可
cpu/目录下的文件夹,保留你要移植的目标平台即可(我这里是arm920t)
board/目录下的文件夹,保留一个相似的板作模板(我这里是smdk2410)
2.修改最顶级的Makefile,添加自己的板子支持
a.按照2410的格式,自己新建一个:(这里命名为myboard,记住第二行之前一定是tab)
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
myboard_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t myboard NULL s3c24x0
b.创建自己的开发板主目录
1.进入board目录,用smdk2410做模板,复制一份命名为myboard
cd board
cp -fr smdk2410 myboard
2.更改Makefile文件
大约在28行
COBJS := smdk2410.o flash.o 更改为COBJS := myboard.o flash.o
[否则make的时候会出现.depend找不到libmyboard.a的错误]
3.更改文件名
mv board/myboard/smdk2410.c board/myboard/myboard.c
mv include/configs/smdk2410.h include/configs/myboard.h
3.编译测试
1.make myboard_config
2.make
经过这两步,正常的话会在根目录下生成u-boot.bin文件,证明基础过程完成!
4.修改配置文件,使其符合自己的开发板。
一.U-BOOT板本为U-BOOT-1.1.6
二.新建开发板的目录
1.在board目录下将smdk2410复制为myboard目录
2.将board/myboard/smdk2410.c改名为myboard.c
3.将include/configs/smdk2410.h复制为myboard.h
4.修改顶层Makefile,添加:
myboard_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t myboard NULL s3c24x0
5.修改board/myboard/Makefile:
COBJS := smdk2410.o flash.o
改为:
COBJS := myboard.o flash.o
二.修改SDRAM的配置
1.根据HCLK设置SDRAM的刷新参数,主要是REFCNT寄存器,修改board/myboard/lowlevel_init.S
#define REFCNT 1113
改为
#define REFCNT 0x4f4 /*period=7.8125us , HCLK=100MHZ, (2048+1-7.8125*100)*/
三.修改board_init函数
1.修改board/myboard/myboard.c中的board_init函数,修改为:
#define S3C2440_MPLL_400MHZ ((0x5c<<12) | (0x01<<4) | (0x01))
#define S3C2440_UPLL_48MHZ ((0x38<<12) | (0x02<<4) | (0x02))
#define S3C2440_CLKDIV 0x05
#define S3C2410_MPLL_220MHZ ((0x5c<<12) | (0x04<<4) | (0x00))
#define S3C2410_UPLL_48MHZ ((0x28<<12) | (0x01<<4) | (0x02))
#define S3C2410_CLKDIV 0x03
int board_init (void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
/* set up the I/O ports */
gpio->GPACON = 0x007FFFFF;
gpio->GPBCON = 0x00044555;
gpio->GPBUP = 0x000007FF;
gpio->GPCCON = 0xAAAAAAAA;
gpio->GPCUP = 0x0000FFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0x0000FFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF95FFBA;
gpio->GPGUP = 0x0000FFFF;
gpio->GPHCON = 0x002AFAAA;
gpio->GPHUP = 0x000007FF;
if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002) ) {
} else {
/* FCLK:HCLK:PCLK = 1:4:8 */
clk_power->CLKDIVN = S3C2440_CLKDIV;
__asm__( "mrc p15,0,r1,c1,c0,0\n"
"orr r1,r1,#0xc0000000\n"
"mcr p15,0,r1,c1,c0,0\n"
:::"r1"
);
/* to reduce PLL lock time, adjust the LOCKTIME register */
clk_power->LOCKTIME = 0xFFFFFF;
/* configure MPLL */
clk_power->MPLLCON = S3C2440_MPLL_400MHZ;
/* some delay between MPLL and UPLL */
delay (4000);
/* configure UPLL */
clk_power->UPLLCON = S3C2440_UPLL_48MHZ;
/* some delay between MPLL and UPLL */
delay (8000);
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;
}
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
return 0;
}
四.在/include/s3c24x0.h中加入2440 的CAMDIVN定义:
typedef struct {
S3C24X0_REG32 LOCKTIME;
S3C24X0_REG32 MPLLCON;
S3C24X0_REG32 UPLLCON;
S3C24X0_REG32 CLKCON;
S3C24X0_REG32 CLKSLOW;
S3C24X0_REG32 CLKDIVN;
S3C24X0_REG32 CAMDIVN;
} S3C24X0_CLOCK_POWER;
五.修改cpu/arm920t/s3c24x0/speed.c,首先要在程序的开头增加如下一行,才可以使用gd变量:
DECLARE_GLOBAL_DATA_PTR;
#define S3C2440_CLKDIVN_PDIVN (1<<0)
#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1)
#define S3C2440_CLKDIVN_HDIVN_1 (0<<1)
#define S3C2440_CLKDIVN_HDIVN_2 (1<<1)
#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1)
#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1)
#define S3C2440_CLKDIVN_UCLK (1<<3)
#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)
#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4)
#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8)
#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
#define S3C2440_CAMDIVN_DVSEN (1<<12)
1. 修改get_PLLCLK()
DECLARE_GLOBAL_DATA_PTR;
static ulong get_PLLCLK(int pllreg)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
ulong r, m, p, s;
if (pllreg == MPLL)
r = clk_power->MPLLCON;
else if (pllreg == UPLL)
r = clk_power->UPLLCON;
else
hang();
m = ((r & 0xFF000) >> 12) + 8;
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;
if(gd->bd->bi_arch_number == MACH_TYPE_SMDK2410) {
return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
} else {
return ((CONFIG_SYS_CLK_FREQ*m*2) / (p<
}
}
2. 修改get_HCLK()
/* return HCLK frequency */
ulong get_HCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
else {
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
return get_FCLK() / hdiv;
}
}
3. 修改get_PCLK()
/* return PCLK frequency */
ulong get_PCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
else {
clkdiv = clk_power->CLKDIVN;
camdiv = clk_power->CAMDIVN;
switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
case S3C2440_CLKDIVN_HDIVN_1:
hdiv = 1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv = 2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
break;
}
return get_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
}
}
六.选择 NOR FLASH 型号
1.修改include/configs/myboard.h 把型号改成开发板中的NOR flash型号 AM29LV800
#if 0
#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#endif
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
重新编译
七.配置include/configs/myboard.h中定义CS8900的各个默认地址,如IP,MAC等
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.8
#define CONFIG_SERVERIP 192.168.1.15
八.添加include/configs/myboard.h
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_CMD_LINE_TAG 1
#define CONFIG_BOOTDELAY 3
#define CONFIG_BOOTARGS "noinitrd console=ttSAC0 root=/dev/mtdblock1 rootfstype=jffs2"
#define CONFIG_BOOTCOMMAND "nboot 0x32000000 0 0; bootm 0x32000000"
九.添加PING命令
修改include/configs/myboard.h:
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_PING | \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
十.修改提示符
修改include/configs/myboard.h:
#define CFG_PROMPT "myboard> " /* Monitor Command Prompt */
十一.支持NAND FLASH
1. 修改配置文件include/configs/myboard.h的宏定义
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_PING | \
CFG_CMD_NAND | \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C |*/ \
/*CFG_CMD_USB |*/ \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
2. 在include/configs/myboard.h中添加三个跟NAND 有关的宏定义
#define CFG_NAND_BASE 0
#define CFG_MAX_NAND_DEVICE 1
#define NAND_MAX_CHIPS 1
3. 在include/s3c24x0.h中添加S3C2440_NAND数据结构
/* 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 NFMECCD0;
S3C24X0_REG32 NFMECCD1;
S3C24X0_REG32 NFSECCD;
S3C24X0_REG32 NFSTAT;
S3C24X0_REG32 NFESTAT0;
S3C24X0_REG32 NFESTAT1;
S3C24X0_REG32 NFMECC0;
S3C24X0_REG32 NFMECC1;
S3C24X0_REG32 NFSECC;
S3C24X0_REG32 NFSBLK;
S3C24X0_REG32 NFEBLK;
} /*__attribute__((__packed__))*/ S3C2440_NAND;
4. 在include/s3c2410.h文件中仿照S3C2410_GetBase_NAND函数定义S3C2440_GetBase_NAND函数
static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)
{
return (S3C2440_NAND * const)S3C2410_NAND_BASE;
}
5.新建cpu/arm920t/s3c24x0/nand_flash.c
#include
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include
#include
DECLARE_GLOBAL_DATA_PTR;
#define S3C2440_NFSTAT_READY (1<<0)
#define S3C2440_NFCONT_nFCE (1<<1)
static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chip)
{
S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
if(chip == -1) {
s3c2440nand->NFCONT |= S3C2440_NFCONT_nFCE;
} else {
s3c2440nand->NFCONT &= ~S3C2440_NFCONT_nFCE;
}
}
static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
struct nand_chip *chip = mtd->priv;
switch (cmd) {
case NAND_CTL_SETNCE:
case NAND_CTL_CLRNCE:
printf("%s: called for NCE\n", __FUNCTION__);
break;
case NAND_CTL_SETCLE:
chip->IO_ADDR_W = (void *) &s3c2440nand->NFCMD;
break;
case NAND_CTL_SETALE:
chip->IO_ADDR_W = (void *) &s3c2440nand->NFADDR;
break;
default:
chip->IO_ADDR_W = (void *) &s3c2440nand->NFDATA;
break;
}
}
static int s3c2440_nand_devready(struct mtd_info *mtd)
{
S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);
}
static void s3c24x0_nand_inithw(void)
{
S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
s3c2440nand->NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
s3c2440nand->NFCONT = (1<<4) | (0<<1) | (1<<0);
}
void board_nand_init(struct nand_chip *chip)
{
S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();
s3c24x0_nand_inithw();
chip->IO_ADDR_R = (void *)&s3c2440nand->NFDATA;
chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
chip->hwcontrol = s3c2440_nand_hwcontrol;
chip->dev_ready = s3c2440_nand_devready;
chip->select_chip = s3c2440_nand_select_chip;
chip->options = 0;
chip->eccmode = NAND_ECC_SOFT;
}
#endif
6.修改cpu/arm920t/s3c24x0/Makefile:
COBJS = i2c.o interrupts.o serial.o speed.o \
usb_ohci.o nand_flash.o
十二.修改完,已经可以编译U-BOOT
Make myboard_config
Make all
生成u-boot.bin,用HJTAG下载到板上运行
八.测试网络
1.把开发板连上网络
2.配置开发板的IP地址:
SMDK2410 # setenv ipaddr 192.168.6.239
SMDK2410 # setenv ethaddr 08:00:3e:26:0a:5b
SMDK2410 # setenv serverip 192.168.6.15
SMDK2410 # saveenv
3.打开电脑的tftp-server
tftp 0x30000000 u-boot.bin
4. 烧写U-BOOT
SMDK2410 # protect off all
SMDK2410 # erase all
SMDK2410 # tftp 0x30000000 u-boot.bin
SMDK2410 # cp.b 0x30000000 0x0 0x1ffff
SMDK2410 # protect on all
阅读(2172) | 评论(0) | 转发(1) |