移植u-boot2012.04.01

/***************************************************

*u-boot版本:u-boot2012.04.01

*gcc版本:arm-linux-gcc-4.3.2

*服务器:ubuntu12.04

***************************************************/

版权说明:根据韦东山先生讲解。

 

 

 

一、移植准备

  下载:ftp://ftp.denx.de/pub/u-boot/

解压:#tar xjf u-boot-2012.04.01.tar.bz2

配置:#cd u-boot-2012.04.01/

      #make smdk2410_config

  编译:#make

  结果:NG

  原因:gcc版本低

  解决:

    #cd /work/tools/

    #mkdir tmp

    #tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C tmp/

    #cd tmp/

    #cd usr/local/arm/4.3.2/

   查看环境变量:

    #echo $PATH

  显示为:

     /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/other_board/gcc-3.4.5-glibc-2.3.6/bin

  修改:

    #export PATH=/usr/local/arm/4.3.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

  以上只对本次有效;

  现在设置环境变量:

    #sudo vi /etc/environment

    PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/tools/usr/local/arm/4.3.2/bin"

  重新编译:

    #make distclean

    #make smdk2410_config

    #make

    编译ok

烧写结果:串口无任何输出。

 

 

 

二、建立Source insight工程

  a、打开SI

  b、添加文件到SI工程

     1、点击"Add All",选中“Include top level sub-directories”和“Recursively add lower sub-directories”点击“OK”

     2、选中“Board”目录,点击“Remove Tree”,去掉总个目录

     进入“Board\Samsung\Smdk2410\”,点击"Add All"

     3、选中“Arch”目录,点击“Remove Tree”,去掉总个目录

     进入“Arch\Arm\Cpu\Arm920t\”,双击选中“Cpu.c”“Interrupts.c”“start.S”。
    进入“Arch\Arm\Cpu\Arm920t\S3c24x0\”,点击"Add All"
    进入“Arch\Arm\”,选中"Dts"目录,点击"Add Tree"
    进入“Arch\Arm\Include\Asm\Arch_s3c24x0”,点击"Add All"
    进入“Arch\Arm\Include\Asm\”,点击"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加顶层目        录的文件
    进入“Arch\Arm\Include\Asm\”,单击选中"Proc-armv",点击"Add Tree"
    进入“Arch\Arm\Lib\”,点击"Add All"

    4、选中“Include”目录,点击“Remove Tree”,去掉总个目录

      进入“Include\”,点击"Add All",去掉“Include top level sub-directories”和“Recursively add lower sub-directories”前面的勾,表示只加顶层目录的文件
   进入“Include\”,单击选中"Andestech",点击"Add Tree"
   进入“Include\”,单击选中"Asm-generic",点击"Add Tree"
   进入“Include\”,同上选中除"Configs"目录外的所有目录,点击"Add Tree"。"Configs"目录先不加,下面再议
   进入“Include\Configs\”,双击选中“Smdk2410.h”

    5、同步文件,完成

 

 

 

三、通过链接命令分析组成文件、阅读代码分析启动过程

  重新编译,只关心最后一条链接命令:里面有这句arm-linux-ld -pie -T u-boot.lds -Bstatic -Ttext 0x0 $UNDEF_SYM arch/arm/cpu/arm920t/start.o

  #vi u-boot.lds 
其中:
SECTIONS
{
. = 0x00000000; //看出来链接地址是0,进一步说明支持nor启动
. = ALIGN(4);
.text :
{
__image_copy_start = .; //执行第一个文件是start.S
arch/arm/cpu/arm920t/start.o (.text)
*(.text)
} 

  通过链接脚本知道: . = 0x00000000;同时-Ttext 0x0,由此我们知道是从NOR flash开始运行,通过链接脚本还知道第一个运行的是arch/arm/cpu/arm920t/start.s

  

bootload的基本思路:
  a. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
  b. 如果bootloader比较大,要把它重定位到SDRAM
  c. 把内核从NAND FLASH读到SDRAM
  d. 设置"要传给内核的参数"
  e. 跳转执行内核

 

 

反汇编:arm-linux-objdump -D u-boot > u-boot.dis

#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
而在编译的时候回出现:arm-linux-gcc -g -Os -fno-common -ffixed-r8 //表示r8不变,保留

链接的时候加了一个选项 -pie
#arm-linux-ld --help | grep pie
   -pie, --pic-executable Create a position independent executable

 


u-boot大小是多大呢?
addr -= gd->mon_len;
addr &= ~(4096 - 1);
gd->mon_len = _bss_end_ofs; //gd->mon_len=000ae4e0 约700k,特别大
反汇编里面:
00000048 <_bss_end_ofs>:
48: 000ae4e0 .word 0x000ae4e0

/*******************************************************************
c语言调用过程中:

relocate_code(addr_sp, id, addr);

分析“重定位之修改代码到新地址”:
relocate_code:
mov r4, r0 /* save addr_sp */ r4=r0 ,堆栈
mov r5, r1 /* save addr of gd */ id指向gd
mov r6, r2 /* save addr of destination */ r2指向目标地址

/* Set up the stack */
stack_setup:
mov sp, r4 //重新设置栈,一开始的栈地址是ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) //sp=0x30000f80 从反汇编看出来

adr r0, _start //比较当前地址和目的地址
cmp r0, r6
beq clear_bss /* skip relocation */如果相等就不需要重定位
mov r1, r6 /* r1 <- scratch for copy_loop */
ldr r3, _bss_start_ofs /*r3就是拷贝的长度*/
add r2, r0, r3 /* r2 <- source end address */

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

#ifndef CONFIG_SPL_BUILD
/*
* fix .rel.dyn relocations
*/
ldr r0, _TEXT_BASE /* r0 <- Text base */
//r0=0,代码基地址

sub r9, r6, r0 /* r9 <- relocation offset */
//r9= r6 - r0 = 0x33f41000-0 = 0x33f41000,重定位偏移地址

ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
// r10 = 00073608

add r10, r10, r0 /* r10 <- sym table in FLASH */
// r10 = r10 + r0 =r10=00073608

ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
//r2 = _rel_dyn_start_ofs = 0006b568

add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
//r2 = r2 + r0 = 0006b568

ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
// r3 = _rel_dyn_end_ofs = 00073608

add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
//r3 = r3 + r0 = 00073608

fixloop: //修改循环
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
1.r0 = [0006b568] = 00000020

add r0, r0, r9 /* r0 <- location to fix up in RAM */
//1. r0 = r0 + r9 =00000020 + 0x33f41000 = 0x33f41020

ldr r1, [r2, #4]
// 1. r1 = [0006b568 + 4] = [0006b56c] = 00000017

and r7, r1, #0xff
// 1. r7 = r1 & 0xff = 00000017

cmp r7, #23 /* relative fixup? */相对地址修正
//比较 r7 ? 23 (0x17)

beq fixrel //相等,就跳转到fixrel
cmp r7, #2 /* absolute fixup? */绝对地址修正
beq fixabs
/* ignore unknown type of fixup */
b fixnext
fixabs:
/* absolute fix: set location to (offset) symbol value */
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
add r1, r10, r1 /* r1 <- address of symbol in table */
ldr r1, [r1, #4] /* r1 <- symbol value */
add r1, r1, r9 /* r1 <- relocated sym addr */
b fixnext
fixrel:
/* relative fix: increase location by offset */
ldr r1, [r0]
// 1. r1 = [00000020] = 000001e0

add r1, r1, r9
// 1. r1 = r1 + r9 = 000001e0 + 0x33f41000 = 0x33f411e0
fixnext:
str r1, [r0]
// [r0]==[0x33f41020](新地址) = 0x33f411e0

add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
//r2 = r2 + 8 = 0006b568 + 8 = 0006b570

cmp r2, r3
//比较 0006b570 == 00073608
//000001a4 <_rel_dyn_end_ofs>: 结束地址
// 1a4: 00073608 .word 0x00073608
blo fixloop
#endif

*******************************************************************/

 

 

 

现在新uboot执行过程:

  1.1 set the cpu to SVC32 mode
  1.2 turn off the watchdog
  1.3 mask all IRQs by setting all bits in the INTMR
  1.4 设置时钟比例
  1.5 设置内存控制器
  1.6 设置栈,调用C函数board_init_f
  1.7 调用函数数组init_sequence里的各个函数
  1.7.1 board_early_init_f : 设置系统时钟、设置GPIO
  ......
  1.8 重定位代码:
  1.8.1 从NOR FLASH把代码复制到SDRAM
  1.8.2 程序的链接地址是0,访问全局变量、静态变量、调用函数时是使"基于0地址编译得到的地址"
   现在把程序复制到了SDRAM
  需要修改代码,把"基于0地址编译得到的地址"改为新地址
  1.8.3 程序里有些地址在链接时不能确定,要到运行前才能确定:fixabs
  1.9 clear_bss
  1.10 调用C函数board_init_r:第2阶段的代码

第二阶段框架:
board_init_r
  board_init();
    gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
  puts("Flash: ");
  env_relocate(); // 初始化环境变量
  for (;;) {
    main_loop();

      s = getenv ("bootdelay");
      s = getenv ("bootcmd");
      run_command(s, 0);
    }


可以修改配置定义CONFIG_S3C2440

 

 


3. 修改U-BOOT代码
3.1 建一个单板(修改3个文件)

$ make distclean
$ cd board/samsung/
$ cp smdk2410 smdk2440 -rf
$ cd ../..
$ cd include/configs/
$ cp smdk2410.h smdk2440.h
看看是否能编译通过:
$ cd ../..
$ make smdk2440_config
make: *** No rule to make target `smdk2440_config'. Stop.
make: *** [smdk2440_config] Error 1
编译通不过.怀疑是makefile的问题,搜索一下:
$ grep "smdk2410" * -nR
arch/arm/include/asm/mach-types.h:1644:# define machine_is_smdk2410() (machine_arch_type == MACH_TYPE_SMDK2410)
arch/arm/include/asm/mach-types.h:1646:# define machine_is_smdk2410() (0)
board/samsung/smdk2410/Makefile:28:COBJS := smdk2410.o
board/samsung/smdk2440/Makefile:28:COBJS := smdk2410.o
boards.cfg:65:smdk2410 arm arm920t - samsung s3c24x0
MAINTAINERS:750: smdk2410 ARM920T

$ vi boards.cfg
在boards.cfg文件下复制65行,修改boards.cfg:
仿照
smdk2410 arm arm920t - samsung s3c24x0
添加:
smdk2440 arm arm920t - samsung s3c24x0
然后重新配置一下
$ make smdk2440_config
然后重新编译一下
1$ make

3.2 烧写看结果无法执行,下面按照第2节里面的分析启动过程

3.3 调试:
a. 阅读代码发现不足:UBOOT里先以60MHZ的时钟计算参数来设置内存控制器,但是MPLL还未设置
①处理措施: 把MPLL的设置放到start.S里,取消board_early_init_f里对MPLL的设置,如下面注释掉下面两行
//writel(0xFFFFFF, &clk_power->locktime);

/* configure MPLL */
//writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
// &clk_power->mpllcon);

编译出来的uboot非常大,可以先烧写主光盘里的u-boot.bin到nor,然后用这个uboot来烧写新的uboot
先查看一下是不是刚下的烧写结果是不是有问题
等待usb下载完: OpenJTAG> usb 1 30000000 //1表示一直等待
把flash的写保护去掉: OpenJTAG> protect off all //解除norflash写保护
把flash擦除:开始和结束地址 OpenJTAG> erase 0 7FFFF //擦除从0到0x7FFFF共0x80000个字节
下载进flash: OpenJTAG> cp.b 30000000 0 80000 //从内存0x30000000开始烧写程序到norflash的0地址去,烧写0X80000个字节
反汇编: $ arm-linux-objdump -D u-boot > u-boot.dis
上面反汇编的目的是:查看call_board_init_f所在的汇编地址,开始执行这个函数的时候,说明cpu_init_crit已经执行完了,SDRAM已经初始化完了,我们现在就是想验证一下SDRAM是否初始化成功

②修改start.S里的代码
# endif

 

/* 2. 设置时钟 */
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]

/* 启动ICACHE */
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #(1<<12)
mcr p15, 0, r0, c1, c0, 0 @ write it back

 

#endif /* CONFIG_S3C24X0 */

③把lowlevel_init.S里面的lowlevel_init函数里面
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30
替换为:
SMRDATA:
.long 0x22011110 //BWSCON
.long 0x00000700 //BANKCON0
.long 0x00000700 //BANKCON1
.long 0x00000700 //BANKCON2
.long 0x00000700 //BANKCON3
.long 0x00000700 //BANKCON4
.long 0x00000700 //BANKCON5
.long 0x00018005 //BANKCON6
.long 0x00018005 //BANKCON7
.long 0x008C04F4 // REFRESH
.long 0x000000B1 //BANKSIZE
.long 0x00000030 //MRSRB6
.long 0x00000030 //MRSRB7

完成上面3步之后,编译生成新的uboot.bin,我们先用openjtag烧写原来的uboot,然后通过原来的uboot来下载新生成的uboot.bin
等待usb下载完: OpenJTAG> usb 1 30000000 //1表示一直等待
把flash的写保护去掉: OpenJTAG> protect off all //解除norflash写保护
把flash擦除:开始和结束地址 OpenJTAG> erase 0 7FFFF //擦除从0到0x7FFFF共0x80000个字节
下载进flash: OpenJTAG> cp.b 30000000 0 80000 //从内存0x30000000开始烧写程序到norflash的0地址去,烧写0X80000个字节

到这里可以用openjtag去验证一下内存设置有没有成功

3.4 乱码,查看串口波特率的设置,发现在get_HCLK里没有定义CONFIG_S3C2440
①更改get_HCLK里没有定义CONFIG_S3C2440
board_init_f
init_sequence
serial_init
serial_init_dev
_serial_setbrg
get_PCLK
get_HCLK
处理措施:include/configs/smdk2440.h: 去掉CONFIG_S3C2410
#define CONFIG_S3C2440
②做完第一步后我们编译一下,发现错误,由于第一步的更改导致了第二步出现问题:
s3c2410_nand.c:72: error: dereferencing pointer to incomplete type
查看代码后解决:
$ vi drivers/mtd/nand/Makefile
那我们就去掉这个宏:在smdk2440.h
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
解决办法:暂时去掉如下行
//#define CONFIG_CMD_NAND
③验证:先烧写1.1.6的uboot,然后重启开发板,烧写开发板
等待usb下载完: OpenJTAG> usb 1 30000000 //1表示一直等待
把flash的写保护去掉: OpenJTAG> protect off all //解除norflash写保护
把flash擦除:开始和结束地址 OpenJTAG> erase 0 7FFFF //擦除从0到0x7FFFF共0x80000个字节
下载进flash: OpenJTAG> cp.b 30000000 0 80000 //从内存0x30000000开始烧写程序到norflash的0地址去,烧写0X80000个字节
下面是uboot输出:
U-Boot 2012.04.01 (Jul 29 2013 - 20:26:01)

CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###

3.5 修改UBOOT支持NAND启动
原来的代码在链接时加了"-pie"选项, 使得u-boot.bin里多了"*(.rel*)", "*(.dynsym)"
使得程序非常大,不利于从NAND启动(重定位之前的启动代码应该少于4K)
3.5.1 去掉 "-pie"选项
$ grep "\-pie" * -nR
arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉这行

3.5.2 参考"毕业班第1课"的start.S, init.c来修改代码
把init.c放入board/samsung/smdk2440目录,修改init.c文件主要是加上static , 修改Makefile
修改CONFIG_SYS_TEXT_BASE为0x33f80000
修改start.S
3.5.3 修改board_init_f, 把relocate_code去掉
3.5.4 修改链接脚本: 把start.S, init.c, lowlevel.S等文件放在最前面
$ find -name "u-boot.lds"
./arch/arm/cpu/u-boot.lds:

board/samsung/smdk2440/libsmdk2440.o
生成反汇编文件检查
$ arm-linux-objdump -D u-boot > u-boot.dis
烧写:
OpenJTAG> usb 1 30000000
OpenJTAG> nand erase 0 80000
OpenJTAG> nand write 30000000 0 80000
把开关拨到nand重启有输出,说明现在支持了nand启动:
U-Boot 2012.04.01 (Jul 29 2013 - 22:08:35)

CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###

在源码里面搜索“Flash:”,可以发现出现错误的原因,是由于board_init_r函数里面,
如果你的程序是从nand启动,那么会卡死,做如下修改:
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
} else {
puts("0 KB\n\r");
//puts(failed);
//hang();
}

3.6 修改UBOOT支持NOR FLASH
drivers\mtd\jedec_flash.c 加上新的型号
#define CONFIG_SYS_MAX_FLASH_SECT (128)

修复了重定时留下来的BUG:SP要重新设置

SMDK2410 # loady 32000000
SMDK2410 # protec off all
SMDK2410 # erase 0 7ffff
SMDK2410 # cp.b 32000000 0 80000


3.7 修改UBOOT支持NAND FLASH
修改:include/configs/smdk2440.h: #define CONFIG_CMD_NAND

把drivers\mtd\nand\s3c2410_nand.c复制为s3c2440_nand.c

分析过程:
nand_init
nand_init_chip
board_nand_init
设置nand_chip结构体, 提供底层的操作函数
nand_scan
nand_scan_ident
nand_set_defaults
chip->select_chip = nand_select_chip;
chip->cmdfunc = nand_command;
chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;

nand_get_flash_type
chip->select_chip
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
nand_command() // 即可以用来发命令,也可以用来发列地址(页内地址)、行地址(哪一页)
chip->cmd_ctrl
s3c2440_hwcontrol

chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
*maf_id = chip->read_byte(mtd);
*dev_id = chip->read_byte(mtd);

烧写实验:
①烧写到NOR Flash
SMDK2410 # loady 30000000
SMDK2410 # protect off all
SMDK2410 # erase 0 7ffff
SMDK2410 # cp.b 30000000 0 80000
②烧写到NAND Flash
SMDK2410 # nand erase 0 80000
SMDK2410 # nand write 0 0 80000 把norflash 0地址里面的程序烧写到nand flash 0地址里面去,烧写80000
比较
SMDK2410 # nand read 30000000 0 80000

NAND read: device 0 offset 0x0, size 0x80000
524288 bytes read: OK
SMDK2410 # cmp.b 0 30000000 80000
Total of 524288 bytes were the same


3.8 修改UBOOT支持DM9000网卡
①修改smdk2440.h使它支持网卡DM9000
#if 0
#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 */
#else
#define CONFIG_DRIVER_DM9000
#endif
然后编译出错:dm9000x.c:156: error: 'DM9000_DATA' undeclared (first use in this function)
查找原因:
$ grep "DM9000_DATA" * -nR
参考别人的代码:更改smdk2440.h和lowlevel_init.S里面的时序
还是有错误:看一下调用过程
eth_initialize
board_eth_init
cs8900_initialize

*** ERROR: `ethaddr' not set
现在可以用tftp下载代码了:
SMDK2410 # set ipaddr 192.168.1.17
SMDK2410 # set ethaddr 00:0c:29:4d:e4:f4
到这里先要在xp打开tptp服务器,服务器ip为192.168.1.50
SMDK2410 # set serverip 192.168.1.50
SMDK2410 # tftp 30000000 uImage
SMDK2410 # bootm 30000000
移植网卡搞定。

4. 易用性修裁剪及制作补丁

没有tftp时colin 下载uboot
SMDK2410 # loady 30000000
SMDK2410 # protect off all
SMDK2410 # erase 0 7ffff
SMDK2410 # cp.b 30000000 0 80000


tftp可ping通时colin 下载uboot:
SMDK2410 # tftp 30000000 u-boot_new.bin
SMDK2410 # protect off all
SMDK2410 # erase 0 3ffff
SMDK2410 # cp.b 30000000 0 40000
SMDK2410 # reset //重启

①环境变量的保存
重启uboot后,会打印:*** Warning - bad CRC, using default environment,这说明没有找到环境变量,需要使用默认的环境变量
在si中搜索,可以发现默认的参数修改
②裁剪

③以前在设置好了环境变量的时候一直不敢用save命令
内核打印出来的分区信息
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"
以前是这么烧写:
nand erase 60000 200000
nand write 30000000 60000 200000
现在可以用分区名字代替:
tftp 30000000 uImage
nand erase.part kernel
nand write 30000000 kernel

set bootcmd 'nand read 30000000 kernel;bootm 30000000'

 

最后看看能不能烧写文件系统:
一:
烧写JFFS2
tftp 30000000 fs_mini_mdev.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 0x00260000 5b89a8

set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2

二:
烧写YAFFS
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000 889bc0

更新UBOOT:
tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000

 

colin 查看数据:
SMDK2410 # nand dump 260000

制作补丁:
$ make distclean
$ rm u-boot.dis
$ cd ..
$ mv u-boot-2012.04.01 u-boot-2012.04.01_100ask
$ tar xjf u-boot-2012.04.01.tar.bz2
$ diff --help
$ diff -urN u-boot-2012.04.01 u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask_colin.patch
diff -urN u-boot-2012.04.01 u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask.patch

怎么用这个补丁:
$ cd u-boot-2012.04.01
$ patch -p1 < ../u-boot-2012.04.01_100ask_colin.patch
$ make smdk2440_config
$ make


最重要的一点:
修改NFS.C里面的#define NFS_TIMEOUT (10*2000UL)
这样可以解决
SMDK2410 # nfs 32000000 192.168.1.51:/work/nfs_root/uImage_new
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
could not establish link
Using dm9000 device
File transfer via NFS from server 192.168.1.51; our IP address is 192.168.1.17
Filename '/work/nfs_root/uImage_new'.
Load address: 0x32000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##############T T *** ERROR: Cannot umount

分析"重定位之修改代码为新地址":
#ifndef CONFIG_SPL_BUILD
/*
* fix .rel.dyn relocations
*/
ldr r0, _TEXT_BASE /* r0 <- Text base */
// r0=0, 代码基地址

sub r9, r6, r0 /* r9 <- relocation offset */
// r9 = r6-r0 = 0x33f41000 - 0 = 0x33f41000

ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
// r10 = 00073608

add r10, r10, r0 /* r10 <- sym table in FLASH */
// r10 = 00073608 + 0 = 00073608

ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
// r2=0006b568

add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
// r2=r2+r0=0006b568

ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
// r3=00073608

add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
// r3=r3+r0=00073608

fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
1. r0=[0006b568]=00000020

add r0, r0, r9 /* r0 <- location to fix up in RAM */
1. r0=r0+r9=00000020 + 0x33f41000 = 0x33f41020

ldr r1, [r2, #4]
1. r1=[0006b568+4]=00000017

and r7, r1, #0xff
1. r7=r1&0xff=00000017

cmp r7, #23 /* relative fixup? */
1. r7 == 23(0x17)

beq fixrel
cmp r7, #2 /* absolute fixup? */

beq fixabs
/* ignore unknown type of fixup */
b fixnext
fixabs:
/* absolute fix: set location to (offset) symbol value */
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */

add r1, r10, r1 /* r1 <- address of symbol in table */

ldr r1, [r1, #4] /* r1 <- symbol value */

add r1, r1, r9 /* r1 <- relocated sym addr */

b fixnext
fixrel:
/* relative fix: increase location by offset */
ldr r1, [r0]
1. r1=[00000020]=000001e0

add r1, r1, r9
1. r1=r1+r9=000001e0 + 0x33f41000 = 33F411E0

fixnext:
str r1, [r0]
1. [0x33f41020] = 33F411E0

add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
1. r2=r2+8=0006b568+8=6B570

cmp r2, r3
1.

blo fixloop
#endif

 

你可能感兴趣的:(2012)