当前位置: 首页 > article >正文

【UBOOT】【run_main_loop】uboot 启动 linux 内核

common/board_r.c文件 run_main_loop 函数

static int run_main_loop(void)
{
	/* main_loop() can return to retry autoboot, if so just run it again */
	for (;;)
		main_loop();
	return 0;
}
/*************************************分析*************************************

************************************系统调用***********************************

**************************************结束************************************/

common/main.c 文件 main_loop 函数

void main_loop(void)
{
	const char *s;

	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
	setenv("ver", version_string);  /* set version variable */
	cli_init();
	s = bootdelay_process();
	autoboot_command(s);
	cli_loop();
}
/*************************************分析*************************************
1、设置 main_loop 函数执行标志位
2、设置环境变量 version
3、设置全局变量 top_vars
4、获取 bootdelay 和 bootcmd 环境变量
5、如果没有按键直接启动 linux
6、如果有按键走 cli_loop 函数进入 uboot 命令行模式
************************************系统调用***********************************

**************************************结束************************************/

common/cli.c 文件 cli_init 函数

// common/cli.c
void cli_init(void)
{
	u_boot_hush_start();
}
// common/cli_hush.c
int u_boot_hush_start(void)
{
	if (top_vars == NULL) {
		top_vars = malloc(sizeof(struct variables));
		top_vars->name = "HUSH_VERSION";
		top_vars->value = "0.01";
		top_vars->next = NULL;
		top_vars->flg_export = 0;
		top_vars->flg_read_only = 1;
	}
	return 0;
}
/*************************************分析*************************************
struct variables {
	char *name;
	char *value;
	int flg_export;
	int flg_read_only;
	struct variables *next;
};
设置全局变量 top_vars
************************************系统调用***********************************

**************************************结束************************************/

common/autoboot.c 文件 bootdelay_process 函数

const char *bootdelay_process(void)
{
	char *s;
	int bootdelay;

	s = getenv("bootdelay");
	printf("%s:%d:s = %s\n", __func__, __LINE__, s);
	bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
	printf("Normal Boot\n");
	debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);
	bootretry_init_cmd_timeout();
	s = getenv("bootcmd");
	printf("%s:%d:s = %s\n", __func__, __LINE__, s);
	process_fdt_options(gd->fdt_blob);
	stored_bootdelay = bootdelay;

	return s;
}
/*************************************分析*************************************

************************************系统调用***********************************

**************************************结束************************************/

common/autoboot.c 文件 autoboot_command 函数

void autoboot_command(const char *s)
{
	if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) {
		printf("%s:%d:bootcmd= %s\n", __func__, __LINE__, s);
		run_command_list(s, -1, 0);
	}
}
/*************************************分析*************************************
stored_bootdelay 不会等于 -1,条件一直成立
s 是有值的,条件也一直成立
abortboot 函数如果按键返回 1,不走if分支
             如果没有按键返回 0,走if 分支,调用 run_command_list 函数
run_command_list 函数启动 linux 内核
************************************系统调用***********************************

**************************************结束************************************/

common/autoboot.c 文件 abortboot 函数

static int abortboot(int bootdelay)
{
	return abortboot_normal(bootdelay);
}

static int abortboot_normal(int bootdelay)
{
	int abort = 0;
	unsigned long ts;
	bootdelay = 10;
	while ((bootdelay > 0) && (!abort)) {
		printf("%s:%d:bootdelay = %d,Waiting to choose whether to enter uboot...\n", __func__, __LINE__, bootdelay);
		--bootdelay;
		/* delay 1000 ms */
		ts = get_timer(0);
		do {
			if (tstc()) {
				abort  = 1;
				bootdelay = 0;
				(void) getc();
				break;
			}
			udelay(10000);
		} while (!abort && get_timer(ts) < 1000);
	}
	return abort;
}
/*************************************分析*************************************
等待 10s, 如果有按键事件,返回 1,没有按键事件返回 0
************************************系统调用***********************************

**************************************结束************************************/

common/cli.c 文件 cli_loop 函数

void cli_loop(void)
{
	parse_file_outer();
	/* This point is never reached */
	for (;;);
}
/*************************************分析*************************************
parse_file_outer 函数是命令行处理函数
************************************系统调用***********************************

**************************************结束************************************/

http://www.kler.cn/a/430333.html

相关文章:

  • 【网络协议】开放式最短路径优先协议OSPF详解(四)
  • 【Arm】Arm 处理器的半主机(semihosting)机制
  • 25年01月HarmonyOS应用基础认证最新题库
  • 医学图像分析工具02:3D Slicer || 医学影像可视化与分析工具 支持第三方插件
  • Centos源码安装MariaDB 基于GTID主从部署(一遍过)
  • SQL使用视图
  • 使用javascript+canvas显示二叉树
  • DedeCMS最新注入漏洞(CNVD-2024-44514、CVE-2024-9076)
  • 怎么为开源项目做贡献提PR?
  • 企业经营数据分析系统:提升决策能力的利器
  • git中配置ssh的方法
  • 【计算机网络】实验15:VLAN间通信的实现方法“单臂路由”
  • 分布式事物各方案常见使用场景
  • PHP和GD库如何在图片上添加文字
  • 【IT】测试用例模版(含示例)
  • 踩坑日记-@Data注释的使用
  • 【机器学习】机器学习的基本概念、算法的工作原理、实际应用案例
  • 文生图模型开源之光!ComfyUI - AuraFlow本地部署教程
  • 如何拦截伪蜘蛛、假蜘蛛
  • 【漫话机器学习系列】002.拟合度:调整R方(Adjusted R-Squared)
  • 迅为RK3576开发板满足了4G/5G、wifi6、多网口、NPU等扩展需求
  • vue入门实战(二)父子组件显示,参数传递
  • minio参考官方文档实现多节点部署,基于ubuntu,还是失败了。。。。
  • 香港科技大学广州|智能交通学域博士招生宣讲会—同济大学专场
  • Cesium 问题: 添加billboard后移动或缩放地球,标记点位置会左右偏移
  • 设置笔记本同时连接内外网