Embeded linux之Uboot参数与内核

一、uboot存储方式:

  

  uboot源码:二进制的uboot程序

  0xffffffff:uboot分区没有用的空闲空间

  uboot环境变量:bootdelay、bootcmd、bootargs等参数,键与值用0x3d,即“=”隔开,两参数之间用0x00,即隔开

  0x00000000:uboot参数分区没有用的空闲空间

二、uboot参数操作:

  2.1 参数:

    include/configs/xxx.h  //xxx为芯片名称

    中定义了一些环境变量默认值的宏定义

    common/env_embedded.c

    中定义了环境变量键值对字符串结构体

   2.2 功能函数:

  common/env_common.c

  

  初始化如下结构:

  #ifdef CONFIG_ENV_IS_IN_NAND

    extern int nand_env_init(void);
    extern unsigned char nand_env_get_char_spec(int);
    extern int nand_saveenv(void);
    extern void nand_env_relocate_spec(void);

    static struct env_common_func_t nand_env_cmn_func = {
      .env_init = nand_env_init,
      .env_get_char_spec = nand_env_get_char_spec,
      .saveenv = nand_saveenv,
      .env_relocate_spec = nand_env_relocate_spec,
      .env_name_spec = "NAND",
    };

  #else

    static struct env_common_func_t nand_env_cmn_func = {0};

  #endif

  #ifdef CONFIG_ENV_IS_IN_SPI_FLASH

    extern int sf_env_init(void);
    extern unsigned char sf_env_get_char_spec(int);
    extern int sf_saveenv(void);
    extern void sf_env_relocate_spec(void);

    static struct env_common_func_t nand_env_cmn_func = {
      .env_init = sf_env_init,
      .env_get_char_spec = sf_env_get_char_spec,
      .saveenv = sf_saveenv,
      .env_relocate_spec = sf_env_relocate_spec,
      .env_name_spec = "SPI FLASH",
    };

  #else

    static struct env_common_func_t sf_env_cmn_func = {0};

  #endif

  #ifdef CONFIG_ENV_IS_IN_EMMC

    extern int emmc_env_init(void);
    extern unsigned char emmc_env_get_char_spec(int);
    extern int emmc_saveenv(void);
    extern void emmc_env_relocate_spec(void);

    static struct env_common_func_t emmc_env_cmn_func = {
      .env_init = emmc_env_init,
      .env_get_char_spec = emmc_env_get_char_spec,
      .saveenv = emmc_saveenv,
      .env_relocate_spec = emmc_env_relocate_spec,
      .env_name_spec = "NAND",
    };

  #else

    static struct env_common_func_t emmc_env_cmn_func = {0};

  #endif

  int env_init(void)
  {
    switch (get_boot_media())

    {
      default:
        env_cmn_func = NULL;
        break;
      case BOOT_MEDIA_NAND:
        env_cmn_func = &nand_env_cmn_func;
        break;
      case BOOT_MEDIA_SPIFLASH:
        env_cmn_func = &sf_env_cmn_func;
        break;
      case BOOT_MEDIA_EMMC:
        env_cmn_func = &emmc_env_cmn_func;
        break;
      case BOOT_MEDIA_DDR:
        env_cmn_func = &sf_env_cmn_func;
        break;
    }

    if (env_cmn_func && !env_cmn_func->env_name_spec)

      env_cmn_func = NULL;

    if (!env_cmn_func)
      return -1;

    env_cmn_func->env_init();
    env_name_spec = env_cmn_func->env_name_spec;

    return 0;
  }

  2.3 功能函数调用

  common/cmd_nvedit.c

  U_BOOT_CMD(
    saveenv, 1, 0, do_saveenv,
    "save environment variables to persistent storage",
    ""
  );

  int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  {
    extern char * env_name_spec;

    env_crc_update ();

    return (saveenv() ? 1 : 0);
  }

三、内核查参方式:

  3.1 mtd方式

    文件形式,待补

  3.2 ioremap

    驱动+应用,待补

  3.3 mtd_debug

    软件移植,待补

  3.4 fw_printenv

    3.4.1 工具生成方法:

      uboot_source_tree # make ARCH=arm CROSS_COMPILE=arm-linux-gcc env

      uboot_source_tree/tools/env下得到fw_printenv与fw_env.config

    3.4.2 将工具与配置文件放到板子文件系统上

    3.4.3 修改fw_env.config

        Device offset    对应于uboot源码目录中include/configs/board_name.h的CONFIG_ENV_OFFSET

        Env size     对应于uboot源码目录中include/configs/board_name.h的CONFIG_ENV_SIZE

        Flash sector size  对应于uboot源码目录中include/configs/board_name.h的CONFIG_ENV_SECT_SIZE

        Number of sectors对应于多少块 这里用的是nand flash,如果用nor就不用写这个了

    3.4.4 使用方法:

        ln -s fw_printenv fw_setenv

        读:

          fw_printenv 读全参

          fw_printenv -n param_name 读指定参

        写:

          fw_setenv param_name param_value 写指定参

    3.4.5 错误解决办法:

      错误A:/include/linux/types.h:154:36: error: conflicting types for ‘uintmax_t’ typedef u_int32_t uintmax_t;

         arm-linux/target/usr/include/stdint.h:140:32: note: previous declaration of ‘uintmax_t’ was here

typedef unsigned long long int uintmax_t;

      解决A:两个文件的uintmax_t类型冲突了,将uboot中的类型按照编译器文件中的类型改过来

      错误B:include/linux/types.h:155:36: error: conflicting types for ‘intmax_t’ typedef int32_t intmax_t;

          arm-linux/target/usr/include/stdint.h:138:24: note: previous declaration of ‘intmax_t’ was here

typedef long long int intmax_t;

      解决B:方法同上

      错误C:Warning: Bad CRC, using default environment

      解决C:方案一、环境变量没save,uboot的环境变量分散于代码中,只有save才会存储与env地址中,如果不存到env地址中,fw_printenv是找不到的

         方案二、fw_env.config没设置参数,参数设置方法见3.4.3

四、uboot增加环境变量

  4.1 方法一、uboot命令行手动set param_name param_value

  4.2 方法二、uboot代码中添加:

    1)uboot源码目录中include/configs/board_name.h添加变量宏定义

    2)uboot源码目录中common/env_common.c添加

      

 

原文地址:https://www.cnblogs.com/pokerface/p/6857469.html