u-boot-1.3.4移植问题点(一)

u-boot-1.3.4移植问题点分析

硬件平台:Arm920Tv4 S3c2410 开发板:优龙fs2410 NORFlash:SST39VF1601(2MB)

1. u-boot 环境变量偏移地址及大小设置不合理,导致内核无法启动
现象:   当我设置setenv bootcmd nand read 30800000 40000 200000 /;bootm 30800000 之后,上电复位移动时无法启动,经查,nandflash 40000-240000 全部被清零,我知道nand flash 被擦除后应为1,为什么会被清零?
问题解决:2009年11月22日
#define CFG_ENV_OFFSET          0x38000
#define CFG_ENV_SIZE        0x10000    /* Total Size of Environment Sector */
原因分析:问题在于我的环境变量保存后会覆盖内核开始的部分空间, 0-40000 为bootloader,按照我的设置0-38000 为bootloader,38000-3ffff为环境变量存储区,但是在fs2410.h中我的环境变量大小设置为10000(64K),然而运行saveenv 后,会重写38000-48000的空间,所以之前kernel从40000开始的32k已被重写,自然会出现错误;
解决办法:
(1)一般情况u-boot均小于192k,所以可以将CFG_ENV_OFFSET 设置为30000,CFG_ENV_SIZE 设置为10000;
(2)将CFG_ENV_OFFSET 设置为38000,CFG_ENV_SIZE设置为8000即可。

2. u-boot向内核传递参数
   我们都知道u-boot向内核传递参数的方式是:u-boot先将要传递给内核的参数以固定的数据结构存放在内存中的某一固定位置,fs2410默认是30000100,然后内核启动后会从这一内存区域读取相关的参数;
那么现在的问题是我们如何在u-boot启动时查看我们究竟传递了那些参数给内核?呵呵,麻烦的是,u-boot 将参数存放在30000100位置的这一过程,是由bootm命令来之行的,也就是说是在bootm命令执行之后才将参数存放在30000100位置的,所以我们想要在u-boot命令行通过md 30000100打印内存是看不到真正的传递参数的内容的,这里有一个办法,在u-boot引导内核命令执行过程中打印相关参数,而且这些内容是由u-boot打印的,不是内核。
    之前认为u-boot在向内核传递参数时,是将要传递的参数存放在内存中指定的位置,arm一般是30000100,但是今天打印内存30000100 段内存,什么也没有?哦,我想起来了,进入命令行时,还未执行到向内核传递参数那一段,我们其实应该在thekernel()调用内核之前打印所传递的参数.经确认,的确是在bootm.c或者1.3.4之前版本的armlinux.c之中的do_bootm_linux()函数中调用一堆的内核参数设置函数,最后调用thekernel()跳转到内核入口点执行。-------Good!
    就目前来讲u-boot向内核传递参数只有两项,即CONFIG_SETUP_MEMORY_TAGS和CONFIG_CMDLINE_TAG,经在u-boot/lib_arm/bootm.c的do_bootm_linux()函数跳转到内核入口点之前打印参数存储位置30000100处的内存信息显示了cmdline内容,即就是bootargs的内容,但是识别CONFIG_SETUP_MEMORY_TAGS设置的信息顺序好像反了。
打印向内核参数传递信息如下
30000100: 00000005 54410001 00000000 00000000    ......AT........
30000110: 00000000 00000004 54410002 04000000    ..........AT.... //04000000=64MB
30000120: 30000000 0000002f 54410009 746f6f72    ...0/.....ATroot //30000000即为内存起始地址
30000130: 65642f3d 666e2f76 77722073 73666e20    =/dev/nfs rw nfs
30000140: 746f6f72 3239313d 3836312e 312e312e    root=192.168.1.1
30000150: 2f3a3230 656d6f68 7261662f 68676973    02:/home/farsigh
30000160: 65522f74 72756f73 2f736563 725f796d    t/Resources/my_r
30000170: 66746f6f 70692073 3239313d 3836312e    ootfs ip=192.168
30000180: 312e312e 313a3231 312e3239 312e3836    .1.112:192.168.1
30000190: 3230312e 3239313a 3836312e 312e312e    .102:192.168.1.1
300001a0: 3535323a 3535322e 3535322e 4a3a302e    :255.255.255.0:J
300001b0: 69747375 73665f6e 30313432 6874653a    ustin_fs2410:eth
300001c0: 666f3a30 6f632066 6c6f736e 74743d65    0:off console=tt
300001d0: 43415379 31312c30 30303235 00000000    ySAC0,115200....
300001e0: 00000000 00000000 00000000 00000000    ................
300001f0: 00000000 00000000 00000000 00000000    ................
解释如下:
from u-boot/include/asm-arm/setup.h
struct tag_mem32 {
    u32    size;
    u32    start;    /* physical start address */
};从这个顺序来看是没有问题的,size 在先,然后是内存起始地址--ok! 问题解决。
方法如下:
实现上述打印内存的详细过程 :
在/lib_arm/bootm.c(u-boot-1.3.4)或者/lib_arm/armlinux.c(u-boot-1.3.1)文件中的
    printf(" Starting kernel....");之后
    cleanup_before_linux();之前添件如下代码
(1)定义命令指针数组
#ifdef CONFIG_JUSTIN_DEBUG
    char *j_argv[3];   //定义命令指针数组
    printf("I'm in lib_arm/bootm.c do_bootm_linux() called by cmd_bootm.c do_bootm()/n");
#endif
(2)给命令指针数组赋值,即设置要执行的命令及参数
#ifdef CONFIG_JUSTIN_DEBUG
    j_argv[0]="md";
    j_argv[1]="30000100";
    j_argv[2]="200";
    printf(" It's going to the linux kernel !/n");
    printf(" Congratulate you !.........../n");
(3)调用md命令关联之函数common/cmd_mem.c中的do_mem_md()如下:
    do_mem_md(NULL,0,3,j_argv);
#endif 
(4)在lib_arm/bootm.c最上面添加如下包含文件语句
#include"../common/cmd_mem.c"
以上
3. u-boot移植过程中发现bootfile变量可以被写入nand flash ,但当我运行nfsboot时,无法动态引用之前设置的变量bootfile,而是引用默认的变量,不知是为什么?
问题解决:
迷失在main_loop之中,一直以为运行命令会调用run_command();原来完全不是这样,应在include/configs/fs2410.h中添加:
#define CFG_HUSH_PARSER
#define CFG_PROMPT_HUSH_PS2  "> "
就会在main_loop中调用parse_file_outer();而不是run_command()不能读取变量的问题解决;
寻找原因方法:在run_command中打印调试信息,但是在farsight已移植好的u-boot-1.3.1中,无论如何也不会打印我设定的信息,于是怀疑根本没有进入该函数,于是在fs2410.h中寻找差异,果然定义了上述宏。于是改变,编译调试,成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章