*** Warning – bad CRC or NAND, using default environment

來源:互聯網
上載者:User

when uboot start,dispaly following info:

U-Boot 1.1.6 (Mar 19 2008 - 14:02:12)

so google and find ,the

means nothing wrong ,but need some environment variables for uboot when booting.

,and "The message will go away as soon as you save the envrionment variables using the command"

digest from :

http://www.denx.de/wiki/DULG/WarningBadCRCUsingDefaultEnvironment

http://www.koansoftware.com/it/art.php?art=80

【後記】

具體解釋一下*** Warning - bad CRC or NAND, using default environment的原因和解決辦法:

【原因】

Uboot中的邏輯是,彙編執行完之後,掉轉到C代碼入口處,(此處是arm平台),此處是lib_arm\board.c中的start_armboot,其在一系列的初始化後,會去調用

/* initialize environment */
env_relocate ();

去載入環境變數,在common\env_common.c中的env_relocate():

if (gd->env_valid == 0) {
#if defined(CONFIG_GTH) || defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */
   puts ("Using default environment\n\n");
#else
   puts ("*** Warning - bad CRC, using default environment\n\n");
   show_boot_progress (-60);
#endif
   set_default_env();
}
else {
   env_relocate_spec ();
}

會去根據gd->env_valid 前面有沒有被初始化,是否為1,而決定,

是直接調用預設環境變數,(我此處的uboot中定義的是#define CONFIG_ENV_IS_IN_NAND
,其在env_nand.c中的env_init()中已經初始化了 gd->env_valid = 1;)

還是去調用env_relocate_spec ()去重新(從你指定的裝置,我這裡的是之前指定的nand)裝載你之前預存環境變數。

而我這裡,按照上面說明,就是去執行env_relocate_spec (),

在common\env_nand.c中

void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
int ret;

ret = readenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr);
if (ret)
   return use_default();

if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
   return use_default();
#endif /* ! ENV_IS_EMBEDDED */
}

static void use_default()
{
puts ("*** Warning - bad CRC or NAND, using default environment\n\n");
set_default_env();
}

可以很清楚的看到,如果是readenv讀取環境變數失敗,那麼就調用use_default,使用預設環境變數。

如果即使資料讀的對了,但是crc32校正失敗,那麼也是去調用use_default,使用預設環境變數。

而這兩種情況下,調用use_default,就會列印*** Warning - bad CRC or NAND, using default environment,然後使用你原先在編譯Uboot的時候,在自己的標頭檔裡面定義那些預設的值,比如對於常用到的啟動參數和啟動命令來說,我代碼裡面的是:

/* read kernel from mtdblock2 no matter for 24/4K pagesize nand */
#define CONFIG_BOOTCOMMAND "nand read 0x40007FC0 0x100000 0x200000;bootm 0x40007FC0"
/* mmcblk0p2 -> rootfs Partition */
#define CONFIG_BOOTARGS "root=/dev/mtdblock2 rw init=/linuxrc console=ttyAMA1,115200 mem=64M rootfstype=yaffs2"
,反之,如果你上面從你指定的nand裝置裡面讀取的環境變數是正常的話,那麼就會用那些值,而不是你代碼裡面寫的值。

【解決辦法】

知道了具體原因,解決起來就好辦了:

1.正常的辦法是,如果你確定你已經實現了saveenv,即,

已經在標頭檔中,定義了對應的值:

以我的此處的用nand儲存env舉例來說就是類似於這樣的:

/* use nand to store env */
#define CONFIG_ENV_IS_IN_NAND
/*
current layout:
0-0x100000, uboot;
0x100000 - 0x800000, kernel;
0x800000 - 0x900000, env;
0x900000 - ~ , rootfs;
*/
#define CONFIG_ENV_OFFSET    0x800000
#define CONFIG_ENV_ADDR    CONFIG_ENV_OFFSET /* duplicate define */
#define CONFIG_ENV_SIZE    0x4000 /* 16KB is large enough */
/* set the block size to the max one: 128KB of 2K, 512KB of 4k pagesze nand */
#define CONFIG_ENV_SECT_SIZE   0x80000
#define CONFIG_SYS_ENV_OVERWRITE 1
#define CONFIG_CMD_SAVEENV             1

並且保證你的讀取資料的代碼是OK的:

即保證你的nand驅動相關操作函數等功能已經實現了,可以正常讀取/寫入資料,擦除塊了。

那麼,saveenv就應該可以正常工作了。

此時,你就可以在第一次啟動後(第一次會有此警告),進入uboot(一般是按s鍵,前提是你代碼裡面設定了uboot等待一定的時間,運行你進入uboot)後,執行saveenv,就可以把第一次,從代碼裡面擷取的預設的那些env的值,儲存到nand裡面了。此後,就不會出現這樣的提示了,因為可以正常從指定的nand裝置中讀取和寫入對應的env了。

2.如果你想特殊點,不想讓別人改你的啟動參數等env值,那麼你可以去在標頭檔中,不要定義CONFIG_SYS_ENV_OVERWRITE,然後也不要定義類似於這樣的CONFIG_ENV_IS_IN_NAND定義。

然後別人無法修改這些環境變數,同時,也會每次都提示你

*** Warning - bad CRC or NAND, using default environment,此時,你就再直接把那行列印注釋掉,就可以了。。。,雖然做法不雅,但是還是可以實現目的的。。。

【總結】

一句話,只要有源碼,就沒有解決不了的問題。一切問題,參考源碼,都能找到根本原因。

此處對於arm+nand來說,具體涉及的檔案和函數,總結如下:

1. lib_arm\board.c

void start_armboot (void)
{

。。。

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
   if ((*init_fnc_ptr)() != 0) { //此處會去調用env_init()
    hang ();
   }
}

。。。

/* initialize environment */
env_relocate ();

。。。

}

2.對於env_init(),此處因為指定的是CONFIG_ENV_IS_IN_NAND,所以對應著:

common\env_nand.c:

int env_init(void)
{

。。。

gd->env_valid = 1;

。。。

}

3.common\env_common.c:

void env_relocate (void)
{

。。。

if (gd->env_valid == 0) {
#if defined(CONFIG_GTH) || defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */
   puts ("Using default environment\n\n");
#else
   puts ("*** Warning - bad CRC, using default environment\n\n");
   show_boot_progress (-60);
#endif
   set_default_env();
}
else {
   env_relocate_spec ();
}
。。。

}

4.此處的env_relocate_spec,這裡對應的是common\env_nand.c:

void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
int ret;

ret = readenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr);
if (ret)
   return use_default();

if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
   return use_default();
#endif /* ! ENV_IS_EMBEDDED */
}

5.對於資料讀取有誤或者讀出來的資料crc32有誤的話,都會調用common\env_nand.c:

static void use_default()
{
puts ("*** Warning - bad CRC or NAND, using default environment\n\n");
set_default_env();
}

因此才會提示有誤。OK,總結完畢。有問題,最好自己跟蹤代碼,最後都是可以搞定的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.