目录
一、环境变量
- 环境变量的作用
可以不需要修改源码,修改运行时需要的一些数据和特性 - 环境变量优先级
uboot和环境变量中各有一个值,如果环境变量为空则适用代码的值,否则则使用环境变量的值
1.1、环境变量的工作方式
- 刚烧录的系统中环境变量分区是空白的,uboot第一次运行时加载的是uboot代码中自带的一份环境变量,叫默认环境变量
- saveenv时DDR中的环境变量会被更新到SD卡的环境变量中,下次开机就会在SD卡中加载环境变量到DDR中
1.2、默认环境变量
- 位置u-boot-2022.01/include/env_default.h
default_environment
是一个字符数组,大小为ENV_SIZE,内容就是很多个环境变量连续分布组成,每个环境变量最末端以'\0'结束const char default_environment[] = { #endif #ifndef CONFIG_USE_DEFAULT_ENV_FILE #ifdef CONFIG_ENV_CALLBACK_LIST_DEFAULT ENV_CALLBACK_VAR "=" CONFIG_ENV_CALLBACK_LIST_DEFAULT "\0" #endif #ifdef CONFIG_ENV_FLAGS_LIST_DEFAULT ENV_FLAGS_VAR "=" CONFIG_ENV_FLAGS_LIST_DEFAULT "\0" #endif #ifdef CONFIG_USE_BOOTARGS "bootargs=" CONFIG_BOOTARGS "\0" #endif #ifdef CONFIG_BOOTCOMMAND "bootcmd=" CONFIG_BOOTCOMMAND "\0" #endif #ifdef CONFIG_RAMBOOTCOMMAND "ramboot=" CONFIG_RAMBOOTCOMMAND "\0" #endif #ifdef CONFIG_NFSBOOTCOMMAND "nfsboot=" CONFIG_NFSBOOTCOMMAND "\0" #endif #if defined(CONFIG_BOOTDELAY) "bootdelay=" __stringify(CONFIG_BOOTDELAY) "\0" #endif #if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0) "baudrate=" __stringify(CONFIG_BAUDRATE) "\0" #endif #ifdef CONFIG_LOADS_ECHO "loads_echo=" __stringify(CONFIG_LOADS_ECHO) "\0" #endif #ifdef CONFIG_ETHPRIME "ethprime=" CONFIG_ETHPRIME "\0" #endif #ifdef CONFIG_IPADDR "ipaddr=" __stringify(CONFIG_IPADDR) "\0" #endif #ifdef CONFIG_SERVERIP "serverip=" __stringify(CONFIG_SERVERIP) "\0" #endif #ifdef CONFIG_SYS_AUTOLOAD "autoload=" CONFIG_SYS_AUTOLOAD "\0" #endif #ifdef CONFIG_PREBOOT "preboot=" CONFIG_PREBOOT "\0" #endif #ifdef CONFIG_ROOTPATH "rootpath=" CONFIG_ROOTPATH "\0" #endif #ifdef CONFIG_GATEWAYIP "gatewayip=" __stringify(CONFIG_GATEWAYIP) "\0" #endif #ifdef CONFIG_NETMASK "netmask=" __stringify(CONFIG_NETMASK) "\0" #endif #ifdef CONFIG_HOSTNAME "hostname=" CONFIG_HOSTNAME "\0" #endif #ifdef CONFIG_BOOTFILE "bootfile=" CONFIG_BOOTFILE "\0" #endif #ifdef CONFIG_SYS_LOAD_ADDR "loadaddr=" __stringify(CONFIG_SYS_LOAD_ADDR)"\0" #endif #if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0) "pcidelay=" __stringify(CONFIG_PCI_BOOTDELAY)"\0" #endif #ifdef CONFIG_ENV_VARS_UBOOT_CONFIG "arch=" CONFIG_SYS_ARCH "\0" #ifdef CONFIG_SYS_CPU "cpu=" CONFIG_SYS_CPU "\0" #endif #ifdef CONFIG_SYS_BOARD "board=" CONFIG_SYS_BOARD "\0" "board_name=" CONFIG_SYS_BOARD "\0" #endif #ifdef CONFIG_SYS_VENDOR "vendor=" CONFIG_SYS_VENDOR "\0" #endif #ifdef CONFIG_SYS_SOC "soc=" CONFIG_SYS_SOC "\0" #endif #ifdef CONFIG_ENV_IMPORT_FDT "env_fdt_path=" CONFIG_ENV_FDT_PATH "\0" #endif #endif #if defined(CONFIG_BOOTCOUNT_BOOTLIMIT) && (CONFIG_BOOTCOUNT_BOOTLIMIT > 0) "bootlimit=" __stringify(CONFIG_BOOTCOUNT_BOOTLIMIT)"\0" #endif #ifdef CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_SETTINGS #endif "\0" #else /* CONFIG_USE_DEFAULT_ENV_FILE */ #include "generated/defaultenv_autogenerated.h" #endif #ifdef DEFAULT_ENV_INSTANCE_EMBEDDED } #endif }; #if !defined(USE_HOSTCC) && !defined(DEFAULT_ENV_INSTANCE_EMBEDDED) #include <env_internal.h> static_assert(sizeof(default_environment) <= ENV_SIZE, "Default environment is too large"); #endif
- ENV_SIZE环境变量最大内存,10k
二、printenv命令
位置:u-boot-2022.01\cmd\nvedit.c
- 可以看出printenv命令对应的函数是do_env_print
- 首先判断输入命令是否是加了-a的,如果没有加,就argc=1进入env_print函数循环打印所有的环境变量出来
U_BOOT_CMD_COMPLETE(
printenv, CONFIG_SYS_MAXARGS, 1, do_env_print,
"print environment variables",
"[-a]\n - print [all] values of all environment variables\n"
#if defined(CONFIG_CMD_NVEDIT_EFI)
"printenv -e [-guid guid][-n] [name ...]\n"
" - print UEFI variable 'name' or all the variables\n"
" \"-guid\": GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n"
" \"-n\": suppress dumping variable's value\n"
#endif
"printenv name ...\n"
" - print value of environment variable 'name'",
var_complete
);
static int do_env_print(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
int i;
int rcode = 0;
int env_flag = H_HIDE_DOT;
#if defined(CONFIG_CMD_NVEDIT_EFI)
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e')
return do_env_print_efi(cmdtp, flag, --argc, ++argv);
#endif
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'a') {
argc--; // 2-- , 1
argv++; // printenv , -a
env_flag &= ~H_HIDE_DOT; // env_flag = flag & ~H; 1000 &0111 0000
}
if (argc == 1) {
/* print all env vars */
rcode = env_print(NULL, env_flag);
if (!rcode)
return 1;
printf("\nEnvironment size: %d/%ld bytes\n",
rcode, (ulong)ENV_SIZE);
return 0;
}
/* print selected env vars */
env_flag &= ~H_HIDE_DOT;
for (i = 1; i < argc; ++i) {
int rc = env_print(argv[i], env_flag);
if (!rc) {
printf("## Error: \"%s\" not defined\n", argv[i]);
++rcode;
}
}
return rcode;
}
三、驱动认识
- 裸机程序中是直接操控硬件的,操作系统中必须通过驱动来操控硬件。这两个的本质区别就是分层
- linux驱动本身做了模块化设计,linux驱动本身和linux内核不是强耦合的
- 驱动的设计中有一个关键数据结构(结构体),结构体中包含一些变量和一些函数指针
变量用来记录驱动相关的一些属性,函数指针用来记录驱动相关的操作方法
这些变量和函数指针加起来就构成了驱动。驱动就被抽象为这个结构体 - 一个驱动工作时主要就分几部分:驱动构建(构建一个struct mmc然后填充它)
驱动运行时(调用这些函数指针指针的函数和变量) - 分离思想
分离思想就是说在驱动中将操作方法和数据分开
操作方法就是函数,数据就是变量
在不同的地方来存储和管理驱动的操作方法和变量,这样的优势就是驱动便于移植。 - 分层思想
分层思想是指一个整个的驱动分为好多个层次
简单理解就是驱动分为很多个源文件,放在很多个文件夹中