一、环境变量
环境变量的作用
可以不需要修改源码,修改运行时需要的一些数据和特性
环境变量优先级
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然后填充它)
驱动运行时(调用这些函数指针指针的函数和变量)
分离思想
分离思想就是说在驱动中将操作方法和数据分开
操作方法就是函数,数据就是变量
在不同的地方来存储和管理驱动的操作方法和变量,这样的优势就是驱动便于移植。
分层思想
分层思想是指一个整个的驱动分为好多个层次
简单理解就是驱动分为很多个源文件,放在很多个文件夹中