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中尋找差異,果然定義了上述宏。於是改變,編譯調試,成功。

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