uboot.2015.07移植之从NAND Flash启动(5)

移植u-boot-2015.07之修改程序支持NAND Flash

1.为什么要支持NAND Flash启动

由于NAND Flash 的存储空间大并且价格便宜(相对于 NOR Flash 来说),所以程序的存储位置一般会放在 NAND FLash 里面,虽然 NAND Flash 也有缺点,那就是容易发生位反转,但是这并不妨碍 NAND Flash 的优势,所以从 NAND Flash 启动是非常有必要的。还有一个问题就是在 S3C2440 上电的时候,只会从 NAND Flash 的前面4K空间拷贝代码到内存空间里面,这就导致了一些比较大的bootloader不能够直接放入内存空间运行,而是由程序从 NAND Flash 里面拷贝到内存空间里面去运行

2.添加驱动函数

添加nand的读函数,添加bss段的清零函数到单板目录下面(建立init.c文件,并且添加到单板目录下的 makefile 文件中去)。这个代码需要自己去实现,这里不再赘述。

3.修改设置

  • 注释掉 arch/arm/config.mk 里面的82行 LDFLAGS_u-boot += -pie (我们使用自己的重定位函数,为了能够从 nand flash 启动)

  • 修改smdk2440.h里面的 CONFIG_SYS_TEXT_BASE 为 0x33f00000,这个就是代码的链接地址

  • 把最开始要执行的代码都放在bin文件的最前面,以防被编译器编译到4K空间之外,在 arch/arm/cpu/u-boot.lds 里面修改,包括
    arch/arm/lib/built-in.o board/samsung/smdk2440/built-in.o。本版本u-boot将一个文件夹下面的c文件都链接成一个.o文件,名字为built-in.o,所以我们直接写上built-in.o即可。要想将一个单独的文件放出来以供手动指定链接位置的话,把该文件所在目录下面的 Makefile 文件中该文件对应的obj-y选项改为 extra-y 即可,这样的话就可以在u-boot.lds里面单独指定一个c文件的位置,这点查看start.S文件所在文件夹下面的Makefile就可以知道。另外把开头的 #include <config.h> 给注释掉,不然当你使用双斜杠注释掉板级文件头文件中的一些宏定义的时候make会出现错误,主要就是根目录下的 u-boot.lds 文件头部会出现一大堆注释宏定义,当然,出现错误的时候直接在生成的 u-boot.lds 文件里面删除也是可以的,这里为了方便就把它给注释掉了

. = 0x00000000;

. = ALIGN(4);
.text :
{
        *(.__image_copy_start)
        *(.vectors)
        CPUDIR/start.o (.text*)
        arch/arm/lib/crt0.o (.text*)
        arch/arm/lib/vectors.o (.text*)
        board/samsung/smdk2440/built-in.o (.text*)
        *(.text*)
}

4.修改 board_init_f

注意:这里说的board_init_f指的是board.c里面的函数,而不是board_f.c里面的函数
- 在crt0.S里面进行代码的重定位,在board_init_f上面添加一个标识符,例如:

bym_board_init_f:
    bl  board_init_f
/* 然后在上面进行代码的重定位,修改后如下所示 */
ldr r0, =_start
mov r1, #0
ldr r2, =__bss_start
sub r2, r2, r0

bl bym_copy2sdram

bym_board_init_f:
    bl  board_init_f
  • 在board_init_f里面注释掉
addr -= gd->mon_len;
addr &= ~(4096 - 1);

改为

addr = (ulong)&_start;  /* 指向代码段的开始,人为指定 */

5.修改重定位代码

在Crt0.S里面注释掉所有与代码重定位和清除bss段有关的代码,用自己的代码替换之,替换后的代码如下:

    ldr r0, =__image_copy_start
    mov r1, #0

    /* 为避免 __image_copy_start 等值错误而加的 */
    ldr r2, =__rel_dyn_start    /* r2 <- SRC &__rel_dyn_start */
    ldr r3, =__rel_dyn_end  /* r3 <- SRC &__rel_dyn_end */
    /* 为避免 __image_copy_start 值错误而加的 */

    ldr r2, =__image_copy_end
    sub r2, r2, r0

    bl bym_cpoy2sdram

    bl clear_bss

    ldr pc, =bym_board_init_f

bym_board_init_f:
    /* mov r0, #0 not needed due to above code */
    ldr r0,=0x00000000
    bl  board_init_f

6.测试

  1. 拷贝并覆盖以上修改文件到虚拟机上面

  2. make smdk2440_defconfig

  3. make 这一步出现u-boot contains unexpected relocations.通过网上查找资料,发现是编译的时候有checkarmreloc选项,再次去arch/arm/config.mk里面修改,注释掉ALL-y += checkarmreloc,重新make。该行代码指的是检测重定位信息,我们把所有的重定位代码信息都给注释掉了(包括前面的编译选项),所以这里会出现错误。

悲剧

下载之后启动不成功,查看反汇编文件,发现__bss_start的值并不是我们期望的在0x33f00000之后的一个值,而是0,这点显然是不对的,而且在make的时候最后链接之后出现了奇怪的错误。这样想来这一版本的u-boot还不单单是通过修改 CONFIG_SYS_TEXT_BASE 就可以达到完全改变程序链接地址的目的,此项搁置暂时转为2012版本的移植,以后再来看这个版本的

转机

我又回来了,上面说到反汇编之后查看__bss_start的值不对,我百无聊赖之下把crt0.S里面的官方重定位代码又加上了,重新编译,__bss_start值变得正常了,下载到单板上面可以运行前面的串口初始化以及打印CPU信息那里。问题何在,我又一次去掉了系统原有重定位代码,再次编译,__bss_start值再次不正常,然后我怀疑是重定位里面代码有什么猫腻,然后一点一点去掉重定位函数里面的代码,我发现如果要是去掉了与u-boot.lds文件里面指定的__rel_dyn_start与__rel_dyn_end标号有关的代码__bss_start的值就会变得不正常。万般无奈之下只得把这两句代码搬移到crt0.S里面自己实现的重定位代码之前如上面的代码,不影响重定位代码的参数值,又使用了这两个标号,终于成功。然后我怀疑是编译器的优化作用或是别的什么地方有特殊的处理,总之非常奇怪,这点暂时搁置,现在已经实现了支持 nand flash 启动的代码了

7.从 board_f.c 里面启动

然后我想从board_f.c里面的board_init_f函数启动,没错我就是这么爱折腾。再次修改smdk2440.h里面,还原 #define CONFIG_SYS_GENERIC_BOARD。更改board_init_f(board_f.c里面的)函数里面调用函数组里面的reserve_uboot函数里面的gd->relocaddr赋值语句

//  gd->relocaddr -= gd->mon_len;
//  gd->relocaddr &= ~(4096 - 1);
#ifdef CONFIG_E500
    /* round down to next 64 kB limit so that IVPR stays aligned */
    gd->relocaddr &= ~(65536 - 1);
#endif

    gd->relocaddr = (ulong)&__image_copy_start;

保存覆盖文件到虚拟机,重新make并且下载。程序成功运行到等待用户输入命令界面。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值