本文共 3814 字,大约阅读时间需要 12 分钟。
在 u-boot 中, env 有两套机制在 board_init_f 中有一套在 board_init_r 中有一套u-boot 进入 cmdline 或者 bootcmd 时 采用 board_init_r 的那一套
u-boot 运行过程中 board_init_f // board_init_f 之前就已经初始化好了 gd->env_buf // 初始化 gd 结构体变量 地址的时候 初始化的 gd->env_buf // 因为 gd_t 结构体 如此声明env_buf : char env_buf[32]; // gd->env_buf 用来装 env_get_ulong->env_get 时,获取的字符串 env_init env_driver_lookup env_get_location return env_locations[prio] ; // ENVL_MMC _env_driver_lookup n_ents = xxx in section .u_boot_list_2_env_driver ,根据 ENVL_MMC 找到对应的 驱动对应的结构体 struct env_driver drv->init // drv 为找到的结构体 struct env_driver _u_boot_list_2_env_driver_2_mmc 中没有 init 成员 env_set_inited(drv->location) gd->env_has_init |= (1UL << ENVL_MMC); // 环境变量的地址 gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = ENV_VALID; 消费者 init_baud_rate gd->baudrate = env_get_ulong("baudrate", 10, CONFIG_BAUDRATE); // 找到的是 include/env_default.h L23 中 const uchar default_environment[] 的 "baudrate=" __stringify(CONFIG_BAUDRATE) "\0" env_get env_get_f env_get_char env_get_char_spec *(uchar *)(gd->env_addr + index) board_init_r initr_env env_relocate(); env_load drv = env_driver_lookup(ENVOP_LOAD, prio)); printf("Loading Environment from %s... ", drv->name); drv->load();/env_mmc_load// 将 mmc 中的变量加载到内存中 // env_mmc_load 在 env/mmc.c // ENV_IS_IN_MMC 决定了 env/mmc.c 编入u-boot // ENV_IS_IN_MMC 依赖 MMC(mmc的驱动) struct mmc *mmc = find_mmc_device(dev); init_mmc_for_env(mmc); mmc_get_env_addr(mmc, 0, &offset) // offset的单位是字节 // 1. 设备树中分析dt_prop.partition,如果不行再分析下一个 // 2. 设备树中分析dt_prop.offset,如果不行再分析下一个 // 3. CONFIG_ENV_OFFSET // 该值应该是一个 u64,因为u32最多支持4G // 但是u-boot在这一个变量的定义处有bug(有的是s64,有的是s32) // 这个offset的值和u-boot移植人员相关,u-boot移植人员想让其指向什么位置就让其指向什么位置 // 但是要注意mmc的布局 // 我现在用的是一张32G的microsd卡,62410752个sector // 按照 之前ENV的布局,其实sector是 62409678, 起始字节是 62409678*512 = 0x770979c00 // 单位 : sector // | 32 | 16 | 1 |1025 | // |ENV | BL1|SIGN |RESERVED| read_env(mmc, CONFIG_ENV_SIZE, offset, buf) env_import(buf, 1, H_EXTERNAL) // 导入到 env_htab 中 // mmc 的env 地址处是空的 if (crc32(0, ep->data, ENV_SIZE) != crc) env_set_default("bad CRC", 0); printf("*** Warning - %s, " "using default environment\n\n", s); // 做一次转换 himport_r(&env_htab, (char *)default_environment, sizeof(default_environment), '\0', flags, 0, 0, NULL) return -ENOMSG; else if(不空且正常) // 做一次转换 himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', flags, 0, 0, NULL) else // 不空且不正常 env_set_default("import failed", 0); if(import没问题){ ep = (env_t *)buf; gd->env_addr = (ulong)&ep->data; }else // import 有问题 env_set_default(errmsg, 0); fini_mmc_for_env(mmc); printf("OK\n"); // 打印 为 Loading Environment from MMC... OK gd->env_load_prio = prio; env_set_hex("fdtcontroladdr",(unsigned long)map_to_sysmem(gd->fdt_blob)); 消费者 image_load_addr = env_get_ulong("loadaddr", 16, image_load_addr); env_get hsearch_r(e, ENV_FIND, &ep, &env_htab, 0); // 在内存中的数据结构 env_htab 中寻值
1. 初始化 A. env_init B. initr_env2. 初始化中环境变量地址的转移过程 A. default_environment(include/env_default.h L23) -> gd->env_addr B. mmc(env_mmc_load中的局部变量offset) -> buf(gd->env_addr) -> env_htab3. env_get_ulong 的路径 A. env_get->env_get_f->env_get_char->env_get_char_spec->*(uchar *)(gd->env_addr + index) B. env_get->hsearch_r4. env_get_ulong 中存储得来的字符串的位置 A. 全局变量 gd->env_buf B. 局部变量 struct env_entry *ep
bootargs=root=/dev/mmcblk0p2 rw rootfstype=ext3 init=/linuxrc console=ttySAC0,115200 rootwaitbootcmd=fatload mmc 0:1 0x50008000 uImage;bootm 0x50008000;
转载地址:http://obigi.baihongyu.com/