|
U-boot_
Lalahu chenxinli008@163.com
我买的天嵌的板子,厂商只给了u-boot的bin文件,没有给出移植的过程,自己间间断断摸索了大半年,终于有了一小步了,现在uboot从norflash启动后,打印一串数据。自己写出来整理一下。(前提是linux已安装arm-linux-gcc)
参考资料:嵌入式Linux应用开发完全手册 韦东山
https://bbs.eeworld.com.cn/thread-80832-6-1.html 顶嵌嵌入式培训的资料
1. board目录下smdk2410复制为tq2440
cp -r smdk2410 tq2440
2. include/configs目录下建立配置文件tq2440.h。可将include/configs/smdk2410.h复制为
tq2440.h
3. 顶层Makefile在以下位置增加下列两行
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s
tq2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t tq2440 NULL s
4、在board/tq2440 Makefile增加如下修改(检查自己的flash型号是否支持CFI)
COBJS := tq2440.o
SOBJS := lowlevel_init.o
删除了flash.o
board/tq2440/flash.c .函数支持AM29LV400和AM29LV800。对于其他型号,例如我的flash是AM(EN)29LV160AB支持CFI接口标准,所以使用drivers/cfi_flash.c中的接口函数;否则自己编写。虽然我们的flash为
(等熟悉uboot了再修改,防止不必要的错误)
5、 修改SDRAM的配置()
u-boot-
define B1_BWSCON (DW32) 修改为 #define B1_BWSCON (DW16)
#define B5_BWSCON (DW16) 修改为 #define B5_BWSCON (DW8)
#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
修改为
#define REFCNT 0x
6、 修改board/tq2440/tq2440.c中的board_init函数
/* S
*m = M(the value for divider M)+8, p=P(the value for divider P)+2*/
#define S
#define S
#define S
int board_init (void)
{
S
S
clk_power->CLKDIVN = S
/* change to asynchronous bus mod */
__asm__( "mrc p15, 0, r1, c1, c0, 0\n" /* read ctrl register */
"orr r1, r1, #0xc0000000\n" /* Asynchronous */
"mcr p15, 0, r1, c1, c0, 0\n" /* write ctrl register */
:::"r1"
);
/* to reduce PLL lock time, adjust the LOCKTIME register */
clk_power->LOCKTIME = 0xFFFFFF;
/* configure MPLL */
clk_power->MPLLCON = S
/* some delay between MPLL and UPLL */
delay (4000);
/* configure UPLL */
clk_power->UPLLCON = S
/* some delay between MPLL and UPLL */
delay (8000);
/* 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;
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_S
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
return 0;
}
7、 头文件修改 include/configs添加tq2440.h
cp include/configs/smdk2410.h include/configs/tq2440.h
#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#if 0
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
#endif
修改为:
#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 */
添加以下宏定义
#define CFG_FLASH_CFI 1
#define CFG_FLASH_CFI_DRIVER 1
#define CFG_MONITOR_BASE 0x00000000
修改以下语句(刚开始输出flash 0k,修改以下即可)
#define PHYS_FLASH_SIZE 0x00200000 /* 2MB */
#define CFG_MAX_FLASH_SECT (35) /* max number of sectors on one chip
#define CFG_PROMPT "TQ2440 # " /* Monitor Command Prompt */
注意,我在工程中查找PHYS_FLASH_SIZE除了以上一句外,没有别的引用它。没有什么用处,我自认为。因为CFG_MAX_FLASH_SECT修改为35时,不管PHYS_FLASH_SIZE为何值时,打印出FLASH
8、 include/s
在下面结构体中添加
typedef struct {
S
S
S
S
S
S
S
}
添加NAND寄存器结构体
/* NAND FLASH (see S
typedef struct {
S
S
S
S
S
S
S
S
S
S
S
S
S
S
S
S
} /*__attribute__((__packed__))*/ S
9、修改cpu/arm920t/s
在#define MPLL 0
#define UPLL 1上面增加DECLARE_GLOBAL_DATA_PTR;
增加宏定义
/* for s
#define S
#define S
#define S
#define S
#define S
#define S
#define S
#define S
#define S
#define S
#define S
#define S
static ulong get_PLLCLK(int pllreg)
{
S
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 & 0x
s = r & 0x3;
/* support both of S
/*return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));*/
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 << s)); /* S
}
/* return FCLK frequency */
/* return HCLK frequency */
ulong get_HCLK(void)
{
S
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
/* support both of S
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;
/* work out clock scalings */
switch (clkdiv & S
case S
hdiv = 1;
break;
case S
hdiv = 2;
break;
case S
hdiv = (camdiv & S
break;
case S
hdiv = (camdiv & S
break;
}
return get_FCLK() / hdiv;
}
/*return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());*/
}
/* return PCLK frequency */
ulong get_PCLK(void)
{
S
/*return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());*/
unsigned long clkdiv;
unsigned long camdiv;
int hdiv = 1;
/* support both of S
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;
/* work out clock scalings */
switch (clkdiv & S
case S
hdiv = 1;
break;
case S
hdiv = 2;
break;
case S
hdiv = (camdiv & S
break;
case S
hdiv = (camdiv & S
break;
}
return get_FCLK() / hdiv / ((clkdiv & S
}
}
Make clean
Make tq2440_config
Make all
随后,Jtag下载到开发板,这个教程上有,打开电源选择norflash启动,串口打印出:
SMDK2410 # fl
U-Boot
DRAM: 64 MB
Flash: 2 MB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
TQ2440 # fl
Bank # 1: CFI conformant FLASH (16 x 16) Size: 2 MB in 35 Sectors
Erase timeout 16384 ms, write timeout 1 ms, buffer write timeout 1 ms, buffer size 1
Sector Start Addresses:
00000000 (RO) 00004000 (RO) 00006000 (RO) 00008000 (RO) 00010000 (RO)
00020000 00030000 00040000 00050000 00060000
00070000 00080000 00090000
00110000 00120000 00130000 00140000 00150000
00160000 00170000 00180000 00190000
001B0000
SMDK2410 # md 0
00000000: 00000000 00000000 00000000 00000000 ................
00000010: 00000000 00000000 00000000 00000000 ................
00000020: 00520051 00020059 00400000 00000000 Q.R.Y.....@.....
00000030: 00000000 00270000 00000036 00040000 ......'.6.......
00000040:
00000050: 00000002 00000000 00000004 00400000 ..............@.
00000060: 00010000 00200000 00000000 00800000 ...... .........
00000070: 001e0000 00000000 00000001 00000000 ................
00000080: 00520050 00310049 00000030 00010002 P.R.I.1.0.......
00000090: 00040001 00000000 00000000 00000000 ................
000000b0: 00000000 00000000 00000000 00000000 ................
000000d0: 00000000 00000000 00000000 00000000 ................
000000e0: 00000000 00000000 00000000 00000000 ................
SMDK2410 # <INTERRUPT>
遇到问题:
/opt/EmbedSky/
(.text+0x8): undefined reference to `raise'
产生了这样的一个错误。解决方法javascript:;
这就要求USE_PRIVATE_LIBGCC在此之前就有定义,于是在顶层目录的config.mk中的用到export 的地方添加.
#########################################################################
export HOSTCC HOSTCFLAGS CROSS_COMPILE \
AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE
export TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
export USE_PRIVATE_LIBGCC =yes
#########################################################################
以上问题没有解决,参考以下方案,得到方案
用比较旧的arm-linux-gcc编译即可。
arm-linux-gcc-
以下是支持Nand Flash的修改,再加上以上的先前不加的部分。
可参考javascript:;
javascript:;完整的uboot移植,加了DM9000
javascript:;完整的uboot移植
10、include/configs/tq24x0.h在最后#endif /* __CONFIG_H */前增加NAND相关宏定义:
#define CFG_NAND_BASE 0
#define CFG_MAX_NAND_DEVICE 1
#define NAND_MAX_CHIPS 1
11、include/s
添加:
/* for s
static inline S
{
return (S
}
12、添加cpu/arm920t/s
/*
* Nand flash interface of s
* Changed from drivers/mtd/nand/s
*/
#include <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include <s
#include <nand.h>
DECLARE_GLOBAL_DATA_PTR;
#define S
#define S
#define S
#define S
/* select chip, for s
static void s
{
S
if (chip == -1) {
s
} else {
s
}
}
/* command and control s, for s
*
* Note, these all use tglx's method of changing the IO_ADDR_W field
* to make the code simpler, and use the nand layer's code to issue the
* command and address sequences via the proper IO ports.
*
*/
static void s
{
S
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 *)&s
break;
case NAND_CTL_SETALE:
chip->IO_ADDR_W = (void *)&s
break;
/* NAND_CTL_CLRCLE: */
/* NAND_CTL_CLRALE: */
default:
chip->IO_ADDR_W = (void *)&s
break;
}
}
/* s
*
* returns 0 if the nand is busy, 1 if it is ready
*/
static int s
{
S
return (s
}
/* select chip, for s
static void s
{
S
if (chip == -1) {
s
} else {
s
}
}
/* command and control s */
static void s
{
S
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 *)&s
break;
case NAND_CTL_SETALE:
chip->IO_ADDR_W = (void *)&s
break;
/* NAND_CTL_CLRCLE: */
/* NAND_CTL_CLRALE: */
default:
chip->IO_ADDR_W = (void *)&s
break;
}
}
/* s
*
* returns 0 if the nand is busy, 1 if it is ready
*/
static int s
{
S
return (s
}
/*
* Nand flash hardware initialization:
* Set the timing, enable NAND flash controller
*/
static void s
{
S
S
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
{
/* Enable NAND flash controller, Initialize ECC, enable chip select, Set flash memory timing */
s
}
else
{
/* Set flash memory timing */
s
/* Initialize ECC, enable chip select, NAND flash controller enable */
s
}
}
/*
* Called by drivers/nand/nand.c, initialize the interface of nand flash
*/
void board_nand_init(struct nand_chip *chip)
{
S
S
s
if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410) {
chip->IO_ADDR_R = (void *)&s
chip->IO_ADDR_W = (void *)&s
chip->hwcontrol = s
chip->dev_ready = s
chip->select_chip = s
chip->options = 0;
} else {
chip->IO_ADDR_R = (void *)&s
chip->IO_ADDR_W = (void *)&s
chip->hwcontrol = s
chip->dev_ready = s
chip->select_chip = s
chip->options = 0;
}
chip->eccmode = NAND_ECC_SOFT;
}
#endif
13、Makefile (u-boot-
COBJS = i
usb_ohci.o nand_flash.o
make all时,遇到问题,Uboot用的是软浮点,编译器用的是硬浮点
换成arm-linux-gcc-
arm-linux-gcc-
arm-linux-ld: ERROR: /usr/local/arm/
File in wrong format: failed to merge target specific data of file /usr/local/arm/
make: *** [u-boot] Error 1
换成arm-linux-cross-2.95.3报以下错误,不知怎么办才好。
cmd_bootm.c:469: undefined or invalid # directive
cmd_bootm.c:475: undefined or invalid # directive
make[1]: *** [cmd_bootm.o] Error 1
make[1]: Leaving directory `/root/Desktop/bootloader/u-boot-
make: *** [common/libcommon.a] Error 2
javascript:;这里遇到的问题和我的一样。
javascript:;试试这个网站的解决方法
14、根据以上所述,所以修改Config.mk (u-boot-
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
# -msoft-float
PLATFORM_CPPFLAGS += -march=armv4
# ============================================================
#
# Supply options according to compiler version
#
# #============================================================
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32)#,-mabi=apcs-gnu)
PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
重新配置,make
烧到Nor Flash里,运行:
U-Boot
DRAM: 64 MB
Flash: 2 MB
NAND: 256 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
TQ2440 @ nand info
Device 0: NAND 256MiB 3,3V 8-bit, sector size 128 KiB
TQ2440 @
但是光标没有了。这是一个问题。这是串口监控软件的问题,可以自己配置。
我用的是SecureCRT。
有两个网址下载交叉编译器比较好
1、javascript:; 可以下载2.95.3、
2、http://www.codesourcery.com/gnu_ ... tion?@template=lite 这个可以下载比较新版本的交叉编译工具,如gcc4.1以上,可以支持EABI。我下载最新的Sourcery G++ Lite 2008q1-126 for ARM EABI,可以编译u-boot1.1.6和2.6.24内核均没问题。
=================================================================
我没有配置
Board.c (u-boot-
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
Nand.c (u-boot-
static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
ulong base_addr)
{
mtd->priv = nand;
nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;
board_nand_init(nand);//这一句非常重要,自己写的内容都在这里。
if (nand_scan(mtd, 1) == 0) {
if (!mtd->name)
mtd->name = (char *)default_nand_name;
} else
mtd->name = NULL;
}
void nand_init(void)
{
int i;
unsigned int size = 0;
for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
size += nand_info[i].size;
if (nand_curr_device == -1)
nand_curr_device = i;
}
printf("%lu MiB\n", size / (1024 * 1024));
#ifdef CFG_NAND_SELECT_DEVICE
/*
* Select the chip in the board/cpu specific driver
*/
board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
#endif
}
=================================================================