Mini2440之uboot移植之裁剪、分區與環境變量設置(五)


本節的代碼都是在Mini440之uboot移植之實踐NAND啟動(四) 代碼基礎上修改的。

一、修改默認環境變量

不知道你有沒有留意到,uboot在啟動時,串口輸出信息有下面一行:

U-Boot 2016.05 (Jan 14 2022 - 22:22:01 +0800)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   dm9000
### main_loop: bootcmd="<UNDEFINED>"
SMDK2440 #

可以看出,讀出的是壞的CRC,使用默認的環境變量,我們分析一下輸出這個的原因。

1.1 分析環境變量初始化

Mini440之uboot移植之源碼分析board_init_r(四)我們介紹到board_init_r()函數會進行環境變量的的初始化。

具體在initr_env()函數執行過程中,該函數位於common/board_r.c文件,去掉無用代碼如下:

static int initr_env(void)
{
    /* initialize environment */
    if (should_load_env())
        env_relocate();
    else
        set_default_env(NULL);

    /* Initialize from environment */
    load_addr = getenv_ulong("loadaddr", 16, load_addr);
    return 0;
}

其中should_load_env去除無用代碼,定義如下:

static int should_load_env(void)
{
    return 1;
}

然后執行env_relocate();

1.2 env_relocate

env_relocate函數定義在common/env_common.c文件,去除無用代碼:

void env_relocate(void)
{
    if (gd->env_valid == 0) {
        bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM);
        set_default_env("!bad CRC");
    } else {
        env_relocate_spec();
    }
}

會去根據gd->env_valid 前面有沒有被初始化,是否為1,而決定,是直接調用默認環境變量,還是去調用env_relocate_spec ()去重新裝載你之前存儲在外部介質(例如NAND、NOR FLASH)中的環境變量。這里由於我們並沒有將環境變量寫入外部存儲介質。

而我這里,按照上面說明,gd->env_valid=0,所以執行set_default_env("!bad CRC");

1.3 set_default_env

set_default_env函數定義在common/env_common.c文件:

void set_default_env(const char *s)
{
    int flags = 0;

    if (sizeof(default_environment) > ENV_SIZE) {
        puts("*** Error - default environment is too large\n\n");
        return;
    }

    if (s) {
        if (*s == '!') {
            printf("*** Warning - %s, "
                "using default environment\n\n",
                s + 1);
        } else {
            flags = H_INTERACTIVE;
            puts(s);
        }
    } else {
        puts("Using default environment\n\n");
    }

    if (himport_r(&env_htab, (char *)default_environment,
            sizeof(default_environment), '\0', flags, 0,
            0, NULL) == 0)
        error("Environment import failed: errno = %d\n", errno);

    gd->flags |= GD_FLG_ENV_READY;
}

因為s="!bad CRC",所以串口會輸出警告信息。

我們之前介紹過默認的環境變量都是保存在default_environment這個字符數組中的,環境變量之間使用\0分隔,其內容大致如下:

const uchar default_environment[] = {
    "bootdelay="    __stringify(CONFIG_BOOTDELAY)    "\0"
    "baudrate="    __stringify(CONFIG_BAUDRATE)    "\0"
    "ipaddr="    __stringify(CONFIG_IPADDR)    "\0"
    "serverip="    __stringify(CONFIG_SERVERIP)    "\0"
    "netmask="    __stringify(CONFIG_NETMASK)    "\0"
};

這里我們以其中的baudrate為例,CONFIG_BAUDRATE在smdk2440.h(include/configs/smdk2440.h)中定義:

#define CONFIG_BAUDRATE        115200

此外還有一個比較重要的宏配置,是用來啟動linux內核的,這里我們沒有配置,但是有必要介紹一下,CONFIG_BOOTARGS,搜索 bootargs 字樣,可以在其它單板中看到有類似這樣的定義:

#define CONFIG_BOOTARGS        "root=/dev/mtdblock3 console=ttySAC0,115200 init=/linuxrc"
  • root 指定文件系統位置,這里/dev/mtdblock3代表的是rootfs根文件系統所在的分區,並不是隨便指定的,是要根據實際塊設備驅動來指定;
  • init 指定內核啟動后執行的第一個應用程序;
  • console 指定使用哪個終端,這里ttySAC0代表的是UART0字符設備/dev/ttySAC0,頁是要根據實際UART驅動來指定;

其它宏也是這樣,比如我們熟悉的有:

  • CONFIG_BOOTCOMMAND,用來啟動內核的命令;
  • CONFIG_BOOTDELAY:uboot啟動倒計時,默認值為5s,只有設置了bootcmd,它才有用;
  • CONFIG_BAUDRATE:波特率,默認為115200;
  • CONFIG_IPADDR:IP 地址;
  • CONFIG_SERVERIP:服務器IP地址;
  • CONFIG_NETMASK:子網掩碼;
  • CONFIG_GATEWAYIP:網關;

仿照其它單板在include/configs/smdk2440.h中添加相應的宏來設置默認環境變量,代碼如下(紅色為添加代碼):

/* autoboot */
#define CONFIG_BOOTDELAY    5
#define CONFIG_BOOT_RETRY_TIME    -1
#define CONFIG_RESET_TO_RETRY
#define CONFIG_ZERO_BOOTDELAY_CHECK

#define CONFIG_NETMASK        255.255.255.0
#define CONFIG_IPADDR        192.168.0.188
#define CONFIG_SERVERIP        192.168.0.200
#define CONFIG_ETHADDR      08:00:3e:26:0a:5b

這個其實我們在u-boot支持DM9000網卡的時候已經介紹過了。 這樣當uboot啟動時就會默認使用上面的環境變量,不需要每次啟動都去修改變量了。

1.4 設置環境變量保存位置

在之前的打印信息中雖然會出現,"bad CRC,using default environment",后面我們通過手動設置環境變量:

set ethaddr 00:0c:29:d3:fe:1d

也是可以執行我們想要的操作,但是如果使用 save 命令將其保存到 flash 中,保存地址設置有誤的話,會保存失敗。並且有可能會破壞flash原有的內容,導致uboot啟動失敗。

所以,首先我們先找到 save 在代碼中的位置,在 u-boot 上,輸入 save -help 命令,打印如下:

saveenv - save environment variables to persistent storage

useage:
saveenv

在u-boot代碼搜索saveenv,

grep "saveenv" * -nR

發現很多文件中都有對 saveenv 函數的定義,由於我們只需要把環境變量保存到 FALSH中,所以只需要關注與 FLASH有關的文件,如上圖所示:

  • common/env_nand.c 文件:將環境變量保存到 NAND 中;
  • common/env_flash.c 文件:將環境變量保存到 NOR中;

打開 common 目錄下的 Makefile 文件,查看編譯這兩個文件所依賴的宏:

 

可以看出:

  • 編譯 env_flash.c 文件需要 CONFIG_ENV_IS_IN_FLASH 宏;
  • 編譯 env_nand.c 文件需要 CONFIG_ENV_IS_IN_NAND 宏;

在 smdk2440.h 文件中查找這兩個宏有無定義:

發現只有與NOR 相關宏的定義,沒有與 NAND 相關宏的定義。

1.4.1 NAND啟動

需要注意的是如果是NAND啟動,不支持 NOR FLASH操作,NAND啟動的話只能將環境變量保存在NAND FLASH中。

參照其它單板對NAND 宏的定義,修改include/configs/smdk2440.h:

/* 保存環境變量到NOR FLASH */
#if 0
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x080000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE            0x10000
#else
/* 保存環境變量到NAND FLASH */
#define CONFIG_ENV_IS_IN_NAND        /* U-Boot env in NAND Flash  */
#define CONFIG_ENV_SIZE            0x20000        //128kb
#define CONFIG_ENV_OFFSET          0x80000        //給uboot預留512kb
#endif

其中還有一個 CONFIG_ENV_RANGE 宏,這個宏可以不定義,如果不定義的話,在env_nand.c 中,會把它設置為 CONFIG_ENV_SIZE。

重新編譯,燒寫u-boot到NAND FLASH,就可以使用 save 命令保存環境變量了。

1.4.2 NOR啟動

如果是NOR啟動,修改CONFIG_ENV_ADDR:

/* 保存環境變量到NOR FLASH */
#if 1
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x080000)   //給uboot預留512kb
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE            0x10000
#else
/* 保存環境變量到NAND FLASH */
#define CONFIG_ENV_IS_IN_NAND        /* U-Boot env in NAND Flash  */
#define CONFIG_ENV_SIZE            0x20000        //128kb
#define CONFIG_ENV_OFFSET          0x80000        //給uboot預留512kb
#endif

重新編譯,燒寫u-boot到NOR FLASH,並設置開發板從NOR啟動,啟動后設置環境變量,並保存:

U-Boot 2016.05 (Jan 16 2022 - 13:53:11 +0800)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
SMDK2440 # set ethaddr 00:0c:29:d3:fe:1d
SMDK2440 # save
Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... 9....8....7....6....5....4....3....2....1....done
1.4.3 env_relocate_spec 

由於gd->env_valid = 1,下次在啟動就不會執行env_relocate,將會去執行env_relocate_spec (),函數定義在common/env_flash.c:

void env_relocate_spec(void)
{
    env_import((char *)flash_addr, 1);
}

env_import()在common/env_common.c中定義:

/*
 * Check if CRC is valid and (if yes) import the environment.
 * Note that "buf" may or may not be aligned.
 */
int env_import(const char *buf, int check)
{
    env_t *ep = (env_t *)buf;
    int ret;

    if (check) {
        uint32_t crc;

        memcpy(&crc, &ep->crc, sizeof(crc));

        if (crc32(0, ep->data, ENV_SIZE) != crc) {
            set_default_env("!bad CRC");
            return 0;
        }
    }

    /* Decrypt the env if desired. */
    ret = env_aes_cbc_crypt(ep, 0);
    if (ret) {
        error("Failed to decrypt env!\n");
        set_default_env("!import failed");
        return ret;
    }

    if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0,   // 正常會執行這里
            0, NULL)) {
        gd->flags |= GD_FLG_ENV_READY;
        return 1;
    }

    error("Cannot import environment: errno = %d\n", errno);

    set_default_env("!import failed");

    return 0;
}

這里就不深入介紹了,有興趣自行研究。

二、設置 mtdparts 分區

我們首先來介紹一下什么是分區,其實linux系統下的各個分區和windows系統下的各個盤類似, 比如我們有一個硬盤,在windows系統中,我們一般會把硬盤分為四個盤,C盤為系統盤,然后D、E、F盤用來放各種類型文件。

同理,我們可以對NAND FLASH進行分盤,比如划分一個盤用來放u-boot、再划分一個盤用來放linux內核,只不過在linux系統下,這個操作叫做叫分區。

如果想要查看 u-boot,kernel等的分區,在uboot中輸入mtdparts命令即可,該命令用來查看NAND FLASH分區情況。運行u-boot,輸入該命令:

SMDK2440 # mtdparts 
mtdids not defined, no default present

發現不支持該命令,修改代碼使u-boot支持mtdparts命令,命令相關的都在cmd目錄下定義。

打開cmd目錄下的 Makefile ,發現要想編譯mtdparts.c 文件,需定義CONFIG_CMD_MTDPARTS 宏,如下圖所示:

然后我們do_mtdparts函數:

static int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc,
               char * const argv[])
{
    if (argc == 2) {
        if (strcmp(argv[1], "default") == 0) {
            setenv("mtdids", (char *)mtdids_default);
            setenv("mtdparts", (char *)mtdparts_default);
            setenv("partition", NULL);

            mtdparts_init();
            return 0;
        } else if (strcmp(argv[1], "delall") == 0) {
            /* this may be the first run, initialize lists if needed */
            mtdparts_init();

            setenv("mtdparts", NULL);

            /* mtd_devices_init() calls current_save() */
            return mtd_devices_init();
        }
    }

    /* make sure we are in sync with env variables */
    if (mtdparts_init() != 0)
        return 1;

    if (argc == 1) {
        list_partitions();
        return 0;
    }
        ...
}

當執行mtdparts命令時,第一個參數為命令mtdparts命令對應的結構體,第二個參數為命令標志,第三個參數為命令參數個數,這里沒有傳入額外參數,長度也就是1,即命令本身。

該函數會調用mtdparts_init函數

2.1 mtdparts_init

mtdparts_init函數定義在cmd/mtdparts.c文件:

/**
 * Parse and initialize global mtdids mapping and create global
 * device/partition list.
 *
 * @return 0 on success, 1 otherwise
 */
int mtdparts_init(void)
{
       ...
    /* get variables */
    ids = getenv("mtdids");
    parts = getenv("mtdparts");
    current_partition = getenv("partition");

    /* if mtdids variable is empty try to use defaults */
    if (!ids) {
        if (mtdids_default) {
            debug("mtdids variable not defined, using default\n");
            ids = mtdids_default;
            setenv("mtdids", (char *)ids);
        } else {
            printf("mtdids not defined, no default present\n");
            return 1;
        }
    }
    ...
}

在默認環境變量中沒有定義mtdids環境變量,ids為0,執行if (mtdids_default)語句,在同文件有如下定義:

/* default values for mtdids and mtdparts variables */
#if defined(MTDIDS_DEFAULT)
static const char *const mtdids_default = MTDIDS_DEFAULT;
#else
static const char *const mtdids_default = NULL;
#endif

2.2 配置分區宏

我們的單板頭文件(include/configs/smdk2440.h)默認沒有定義MTDIDS_DEFAULT宏,所以執行mtdparts時輸出錯誤信息,查看其它單板頭文件是如何定義的,修改include/configs/smdk2440.h里宏的定義:

/*
 * File system
 */
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE

/* mtdparts command line support */
#define MTDIDS_DEFAULT        "nand0=Mini2440-0"
/* default mtd partition table */
#define MTDPARTS_DEFAULT    "mtdparts=Mini2440-0:512k(u-boot)," \
                            "128k(params)," \
                            "4m(kernel)," \
                            "-(rootfs);" 

這樣當在u-boot命令行執行“mtdparts default”命令時,do_mtdparts會根據上面的MTDPARTS_DEFAULT宏保存的mtd分區信息,來將NAND分區。

然后再次使用mtdparts查看分區信息,如下:

SMDK2440 # mtdparts default
SMDK2440 # mtdparts

device nand0 <Mini2440-0>, # parts = 4
 #: name        size        offset        mask_flags
 0: u-boot              0x00080000    0x00000000    0
 1: params              0x00020000    0x00080000    0
 2: kernel              0x00400000    0x000a0000    0
 3: rootfs              0x0fb60000    0x004a0000    0

active partition: nand0,0 - (u-boot) 0x00080000 @ 0x00000000

defaults:
mtdids  : nand0=Mini2440-0
mtdparts: mtdparts=Mini2440-0:512k(u-boot),128k(params),4m(kernel),-(rootfs);

256MB大小的NAND被分成四個分區:

  • 0x00000000~0x00080000:512kb存放u-boot;
  • 0x00080000~0x000A0000:128kb可以用來存放u-boot環境變量;
  • 0x000A0000~0x004A0000:4MB存放linux內核;
  • 0x004A0000~0x10000000:剩下空間存放根文件系統;

2.3 u-boot啟動自動分區

下面修改代碼,讓u-boot啟動時自動設置分區(執行“mtdparts default”命令),在u-boot進入main_loop()死循環之前添加執行命令代碼(run_command("mtdparts default", 0);),修改run_main_loop()函數如下(common/board_r.c文件中):

static int run_main_loop(void)
{
#ifdef CONFIG_SANDBOX
    sandbox_main_loop_init();
#endif
     run_command("mtdparts default", 0); 

    /* main_loop() can return to retry autoboot, if so just run it again */
    for (;;)
        main_loop();
    return 0;
}

這樣,u-boot每次啟動時都會執行一次mtdparts default 命令,使它根據默認參數來自動分區,這樣mtdparts就設置好了。

編譯,燒寫,在uboot中輸入mtdparts,打印如下:

SMDK2440 # mtdparts

device nand0 <Mini2440-0>, # parts = 4
 #: name        size        offset        mask_flags
 0: u-boot              0x00080000    0x00000000    0
 1: params              0x00020000    0x00080000    0
 2: kernel              0x00400000    0x000a0000    0
 3: rootfs              0x0fb60000    0x004a0000    0

active partition: nand0,0 - (u-boot) 0x00080000 @ 0x00000000

defaults:
mtdids  : nand0=Mini2440-0
mtdparts: mtdparts=Mini2440-0:512k(u-boot),128k(params),4m(kernel),-(rootfs);

三、裁切u-boot

到這一步,我們編譯的u-boot 大概有482kb,這其中有很多無用的代碼,所以接下來我們需要對 uboot 進行裁剪。

u-boot 很多文件都是基於Makefile里的宏來進行編譯的,而這些宏的定義基本上都在include/configs/smdk2440.h 中,所以我們需要修改smdk2440.h文件,去掉不需要的宏。

3.1 裁切USB

#if 0
#define CONFIG_USB_OHCI
#define CONFIG_USB_OHCI_S3C24XX
#define CONFIG_USB_KEYBOARD
#define CONFIG_USB_STORAGE
#define CONFIG_DOS_PARTITION
#endif

3.2 裁切RTC

/************************************************************
 * RTC
 ************************************************************/
#if 0
#define CONFIG_RTC_S3C24X0
#endif

3.3 裁切BOOTP選項

/*
 * BOOTP options
 */
#if 0
#define CONFIG_BOOTP_BOOTFILESIZE
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
#endif

3.4 裁切部分不需要的命令行

/*
 * Command line configuration.
 */
#if 0
#define CONFIG_CMD_BSP
#define CONFIG_CMD_DATE
#endif
#define CONFIG_CMD_NAND
#define CONFIG_CMD_REGINFO

3.5 裁切文件系統

/*
 * File system
 */
#if 0
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS

3.6 編譯

編譯,打印如下錯誤:

打開common目錄下的Makefile,定位到usb關鍵字,如下:

可以看出編譯 usb.c 需要宏 CONFIG_CMD_USB 的支持,在 configs/smdk2440_defconfig找到該宏,將其屏蔽,同時屏蔽文件系統相關的宏:

CONFIG_ARM=y
CONFIG_TARGET_SMDK2440=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="SMDK2440 # "
# CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
#CONFIG_CMD_EXT2=y
#CONFIG_CMD_FAT=y

再次編譯:

make clean
make distclean
make smdk2440_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux- V=1

此時編譯完成u-boot大概為246kb。

3.7 下載到NOR FLASH運行

下載到NOR FLAH運行,記得在編譯u-boot執行修改環境變量地址:

/* 保存環境變量到NOR FLASH */
#if 1
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x080000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE            0x10000
#else
/* 保存環境變量到NAND FLASH */
#define CONFIG_ENV_IS_IN_NAND        /* U-Boot env in NAND Flash  */
#define CONFIG_ENV_SIZE            0x20000        //128kb
#define CONFIG_ENV_OFFSET          0x80000        //給uboot預留512kb
#endif

我們將編譯后的u-boot下載到NOR FALSH中運行,以NOR方式啟動:

並在命令行輸入print,查看所有環境變量:

SMDK2440 # print
baudrate=115200
bootdelay=5
ethact=dm9000
ethaddr=00:0c:29:d3:fe:1d
ipaddr=192.168.0.188
mtddevname=u-boot
mtddevnum=0
mtdids=nand0=Mini2440-0
mtdparts=mtdparts=Mini2440-0:512k(u-boot),128k(params),4m(kernel),-(rootfs);
netmask=255.255.255.0
partition=nand0,0
serverip=192.168.0.200
stderr=serial
stdin=serial
stdout=serial

Environment size: 355/65532 bytes

如果我們去修改環境變量,保存到NOR FLASH是可以保存成功的,由於第一節已經演示了這種方式,這里就不再演示。

3.8 下載到NAND FLASH運行

下載到NOR FLAH運行,記得在編譯u-boot執行修改環境變量地址:

/* 保存環境變量到NOR FLASH */
#if 0
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x080000)  //給uboot預留512kb
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE            0x10000
#else
/* 保存環境變量到NAND FLASH */
#define CONFIG_ENV_IS_IN_NAND        /* U-Boot env in NAND Flash  */
#define CONFIG_ENV_SIZE            0x20000        //128kb
#define CONFIG_ENV_OFFSET          0x80000        //給uboot預留512kb
#endif

我們首先向NOR FALSH燒入Mini2440商家原有的Superboot2440.bin,然后設置從NOR啟動,我們搭配MiniTools將u-boot.bin代碼下載到NAND運行:

需要注意的是使用MiniTools下載程序,好像文件大於256kb,MiniTools就無法下載成功。但是這里我們的u-boot裁切到246kb。可以下載成功。

開發板以NAND方式啟動:

我們發現了一個奇怪的現象,同一個程序,NOR啟動和NAND啟動輸出信息不一樣。在NAND啟動方式中,輸出Flash: 0 Bytes。

這主要是因為NAND啟動時,片內SRAM被映射到nGCS0片選的空間,此時導致NOR FLASH失效,因此在flash_detect_legacy()讀取NOR FLASH信息時,讀取到的實際是片內SRAM內存的值。

在命令行輸入print,查看所有環境變量:

SMDK2440 # print
baudrate=115200
bootdelay=5
ethact=dm9000
ethaddr=08:00:3e:26:0a:5b
ipaddr=192.168.0.188
mtddevname=u-boot
mtddevnum=0
mtdids=nand0=Mini2440-0
mtdparts=mtdparts=Mini2440-0:512k(u-boot),128k(params),4m(kernel),-(rootfs);
netmask=255.255.255.0
partition=nand0,0
serverip=192.168.0.200
stderr=serial
stdin=serial
stdout=serial

Environment size: 355/65532 bytes

我們嘗試修改環境變量,並保存:

SMDK2440 # set ipaddr 192.168.1.1
SMDK2440 # save
Saving Environment to NAND...
Erasing NAND...

Erasing at 0x80000 -- 100% complete.
Writing to NAND... OK
SMDK2440 # 

四、代碼下載

Young / s3c2440_project[u-boot-2016.05-crop]

參考文章

[1]移植u-boot-2012.04.01到JZ2440(六: 修改源碼之裁剪uboot、設置分區與環境變量)

[2]六,移植uboot-設置默認環境變量,完善u-boot


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM