1.安装交叉编译器
这里选择一个比较新的版本:ARM-Linux-gcc 4.5.1
在/usr/local目录下新建一个目录arm,把4.5.1版本拷贝到这里。
然后设置环境变量:在/root/.bashrc文件最后一行添加如下内容:
export PATH=$PATH:/usr/local/arm/4.5.1/bin
保存后注销系统,重新登录后可以用export命令查看是否生效:
root@ubuntu:/# export
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/4.5.1/bin"
可以看到设置有效,接下来可以试一下编译Uboot.
2.初试Uboot编译
先做个简单的编译试一下前面安装的交叉编译器是否能用。
2.1.把U-boot-2012.10版本解压到/Home/my/smdk6410目录下,
2.2.修改U-boot-2012.10目录下的Makefile文件
在CROSS_COMPILE ?=这里上面增加两行:
CROSS_COMPILE =/usr/local/arm/4.5.1/bin/arm-linux-
export CROSS_COMPILE
保存后编译:
root@ubuntu:/home/my/smdk6410/u-boot-2012.10# make clean
这时如果没有提示出错的话说明交叉编译器安装成功了,接下来:
root@ubuntu:/home/my/smdk6410/u-boot-2012.10# make smdk6400_config
root@ubuntu:/home/my/smdk6410/u-boot-2012.10# make
.
3.Uboot移植到smdk6410上
因为是板级移植,所以我们先复制一份SMDK6400改为smdk6410。
3.1.需要拷贝的文件&目录有:
3.1.1.拷贝board/samsung/smdk6400 到board/samsung/smdk6410
3.1.2.拷贝nand_spl/board/samsung/smdk6400 到 nand_spl/board/samsung/smdk6410
3.1.3.拷贝include/configs/smdk6400.h 到include/configs/smdk6410.h
3.1.4.拷贝include/asm/arch/s3c6400.h 为 include/asm/arch/s3c6410.h
3.2.需要更改名称的文件有:
3.2.1.更改board/samsung/smdk6410目录下smdk6400.c 为smdk6410.c ,
3.2.2.更改smdk6400_nand_spl.c为smdk6410_nand_spl.c
3.2.3.更改nand_spl/board/samsung/smdk6410目录下smdk6400_nand_spl.c为smdk6410_nand_spl.c
3.3.需要修改内容的文件有:
3.3.1. board/samsung/smdk6410/Makefile
把其中有SMDK6400的相关字符换成smdk6410
3.3.2. nand_spl/board/samsung/smdk6410/Makefile
把其中有SMDK6400的相关字符换成smdk6410
3.3.3. u-boot-2011.12目录下Makefile
找到ARM1176 Systems部分,把smdk6400都换成smdk6410
3.3.4. 把所有#include 都改为#include
3.3.5. arch/arm/cpu/arm1176/s3c64xx/Makefile
把COBJS-$(CONFIG_S3C6400)改为COBJS-$(CONFIG_S3C6410)
3.3.6. include/configs/smdk6410.h
把#define CONFIG_S3C6400 1 改为 #define CONFIG_S3C6410 1
把#define CONFIG_SMDK6400 1 改为 #define CONFIG_SMDK6410 1
好了,在u-boot-2011.12目录下
make smdk6410_config
make
编译通过,说明复制成功了,但这时的u-boot还是SMDK6400的,所以我们还要修改,才能在OK6410板上运行起来。
4.配置板上资源使uboot能够在板上运行。
这里说的运行指的是下载到SDRAM后能够跑起来。
4.1.修改/include/configs/smdk6410.h
4.1.1 #define CONFIG_S3C6410 1 /* in a SAMSUNG S3C6400 SoC */
4.1.2 #define CONFIG_SMDK6410 1 /* on a SAMSUNG SMDK6400 Board */
4.1.3 #define CONFIG_SYS_PROMPT "SMDK6410 # " /* Monitor Command Prompt */
4.1.4#define CONFIG_NR_DRAM_BANKS 2 //2个128M的chip
4.1.5#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE /* SDRAM Bank #1 */
4.1.6#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128 MB in Bank #1 */
//zxd-->
4.1.7#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE+PHYS_SDRAM_1_SIZE)/* SDRAM Bank #1 */
4.1.8#define PHYS_SDRAM_2_SIZE 0x08000000 /* 128 MB in Bank #1 */
//<--
这里4.1.4到4.1.8暂时不修改也可以,但运行后显示SDRAM 128M。或者把4.1.6中的0x08000000改为0x10000000再配合后面的修改也可以显示256M的SDRAM。
4.1.9#define CONFIG_IDENT_STRING " for SMDK6410"
4.1.10#define CONFIG_SYS_NAND_PAGE_SIZE 4096//2048
4.1.11#define CONFIG_SYS_NAND_BLOCK_SIZE (512 * 1024)//128
4.1.12#define CONFIG_SYS_NAND_PAGE_COUNT 128//64。
这里4.1.10到4.1.12暂时不修改也可以,改它是为了后面NAND驱动的都写都能正常
4.2.修改/board/samsung/smdk6410/lowlevel_init.S
4.2.1修改LED显示
/* LED on only #8 */
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x00111111
str r1, [r0, #GPMCON_OFFSET]
ldr r1, =0x00000555
str r1, [r0, #GPMPUD_OFFSET]
ldr r1, =0x0027
str r1, [r0, #GPMDAT_OFFSET]
4.2.2修改这段This was unconditional in original Samsung sources.......屏蔽掉宏定义
//#ifndef CONFIG_S3C6410
ldr r1, [r0, #OTHERS_OFFSET]
bic r1, r1, #0xC0
orr r1, r1, #0x40
str r1, [r0, #OTHERS_OFFSET]
wait_for_async:
ldr r1, [r0, #OTHERS_OFFSET]
and r1, r1, #0xf00
cmp r1, #0x0
bne wait_for_async
//#endif
4.2.3修改这句
#elif !defined(CONFIG_S3C6400)为
#elif !defined(CONFIG_S3C6410)
/* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
4.2.4要想正确显示SDRAM大小,除了上面4.1.6外还要在这里修改MMU关于内存这部分:
/* 128MB for SDRAM 0xC0000000 -> 0x50000000 */
.set __base, 0x500
.rept 0xD00 - 0xC00 //.rept 0xc80 - 0xC00
FL_SECTION_ENTRY __base, 3, 0, 1, 1
.set __base, __base + 1
.endr
/* access is not allowed. */
.rept 0x1000 - 0xD00 //.rept 0x1000 - 0xc80
.word 0x00000000
.endr
5.下载uboot到SDRAM中运行
5.1 先使用IROM_Fusing_Tool.exe把OK6410_SDboot.nb0烧录到SD卡中
5.2 设置开发板从SD卡启动。打开DNW,设置下载地址为0x57e00000,启动开发板后通过DNW把编译好的u-boot.bin下载到SDRAM中,下载后DNW窗口显示:
U-Boot 2012.10 (Nov 05 2012 - 17:29:28) for SMDK6410
CPU: S3C6410@533MHz
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6410
DRAM: 256 MiB
然后。。。。。。系统重启了:
6.调试
跟踪发现board.c(/arch/arm/lib)中有两个函数board_init_f和board_init_r。显示SDRAM: 256 MiB就是在board_init_f函数中实现,而board_init_r会接着初始化FLASH等,查看这个函数发现显示FLASH及NAND大小都是在这个函数中实现。但为什么会没有打印信息而是直接重启了呢?难道系统还没有走到这个board_init_r函数就发生了错误?为了验证这个猜想,在这个board_init_r函数开头弄串字符输出看看,把puts("I am here! ");这句话放在board_init_r函数的开头,重新编译出现:
U-Boot 2012.10 (Nov 05 2012 - 23:52:29) for SMDK6410
CPU: S3C6410@533MHz
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6410
DRAM: 256 MiB
I am here! WARNING: Caches not enabled
Flash: *** failed ***
### Error ### Please RESET the Board ###
这说明board_init_r这个函数还是有执行的。后面测试发现无论把puts("I am here! ");放在board_init_f或board_init_r中都可以输出
。。。。。。
WARNING: Caches not enabled
Flash: *** failed ***
### Error ### Please RESET the Board ###
程序到这里就停住了。
再看看board_init_r函数里到底有什么吧。
。。。。。。。
#if !defined(CONFIG_SYS_NO_FLASH)
puts("Flash: ");
flash_size = flash_init();
if (flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
char *s = getenv("flashchecksum");
print_size(flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
*
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
*/
if (s && (*s == 'y')) {
printf(" CRC: %08X", crc32(0,
(const unsigned char *) CONFIG_SYS_FLASH_BASE,
flash_size));
}
putc('\n');
# else /* !CONFIG_SYS_FLASH_CHECKSUM */
print_size(flash_size, "\n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
} else {
puts(failed);
hang();
}
#endif
#if defined(CONFIG_CMD_NAND)
puts("NAND: ");
nand_init(); /* go init the NAND */
#endif
。。。。。。
显然“*** failed ***”就是puts(failed)这个函数干的。而“### Error ### Please RESET the Board ###”又是谁出的主意呢?调查hang()发现:
void hang(void)
{
puts("### ERROR ### Please RESET the board ###\n");
for (;;);
}
元凶在此,OK6410开发板上并没有这个FLASH,所以先屏蔽掉hang()试试吧,也把测试的那句puts("I am here! ")去掉,下载后DNW显示如下:
U-Boot 2012.10 (Nov 05 2012 - 23:52:29) for SMDK6410
CPU: S3C6410@533MHz
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6410
DRAM: 256 MiB
WARNING: Caches not enabled
Flash: *** failed ***
NAND: raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
No oob scheme defined for oobsize 218
2048 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x60000, size 0x1c0000
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
。。。。。(后面是不停地打印raise: Signal # 8 caught)。
OK,关于“Signal # 8 caught”的问题后面再解决,但怎么也想不明白屏蔽hang()之前加上测试
puts("I am here! ")就可以让程序正常的运行呢?
元芳,你怎么看?