03.uboot分析之源码第二阶段

举报
嵌入式与Linux那些事 发表于 2022/03/28 23:26:09 2022/03/28
【摘要】 首先要明确:uboot目标是从flash读出内核(nand read.jffs2 0x30007FC0 kernel;),启动它(bootm 0x30007FC0)。 一、分析uboot源码 /*初始...

首先要明确:uboot目标是从flash读出内核(nand read.jffs2 0x30007FC0 kernel;),启动它(bootm 0x30007FC0)。

一、分析uboot源码
/*初始化nor flash*/
#ifndef CFG_NO_FLASH
	/* configure available FLASH banks */
	size = flash_init ();
	display_flash_config (size);
#endif /* CFG_NO_FLASH */

/*初始化nand flash*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
	puts ("NAND:  ");
	nand_init();		/* go init the NAND */
#endif
/*完成以上两个步骤后,已经有能力去读写flash*/

/*环境变量的初始化,uboot中输入printf后输出的一些变量如波特率,IP地址等*/

	/* initialize environment */
	env_relocate ();

	/* main_loop() can return to retry autoboot, if so just run it again. 跳转mainloop*/
	for (;;) {
		main_loop ();
	}

main_loop
/*启动命令*/
#ifdef CONFIG_BOOTCOUNT_LIMIT
	if (bootlimit && (bootcount > bootlimit)) {
		printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
		        (unsigned)bootlimit);
		s = getenv ("altbootcmd");
	}
	else
#endif /* CONFIG_BOOTCOUNT_LIMIT */
/*启动内核bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0*/
		s = getenv ("bootcmd");
/*倒数计时*/
	if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
# ifdef CONFIG_AUTOBOOT_KEYED
		int prev = disable_ctrlc(1);	/* disable Control C checking */
# endif

/*如果倒数计时前没有按空格 打印那句话*/

# ifndef CFG_HUSH_PARSER
        {
            printf("Booting Linux ...\n");   
            /*运行上面s命令,内核的启动依赖于bootcmd*/         
    	    run_command (s, 0);
        }
# else
		parse_string_outer(s, FLAG_PARSE_SEMICOLON |
				    FLAG_EXIT_FROM_LOOP);
# endif

/*启动菜单*/
   run_command("menu", 0)
/*死循环 等待输入*/
PROMPT:
#ifdef CFG_HUSH_PARSER
	parse_file_outer();
	/* This point is never reached */
	for (;;);
#else
	for (;;) {
#ifdef CONFIG_BOOT_RETRY_TIME
		if (rc >= 0) {
			/* Saw enough of a valid command to
			 * restart the timeout.
			 */
			reset_cmd_timeout();
		}
#endif

/*读取串口数据*/
len = readline (CFG_PROMPT);

/*又是bootcmd*/
		rc = run_command (lastcommand, flag);

/*处理宏*/
		/* find macros in this token and replace them */
		process_macros (token, finaltoken);

/*解析输入的文字*/
/*例如 在uboot输入 md.w 0 则argv[0]="md.w"  argv[1]="0"*/
	if ((argc = parse_line (finaltoken, argv)) == 0) {
			rc = -1;	/* no command at all */
			continue;

/*查找名字的一个结构体,里面有name,maxargs等参数*/
		if ((cmdtp = find_cmd(argv[0])) == NULL) {
			printf ("Unknown command '%s' - try 'help'\n", argv[0]);
			rc = -1;	/* give up after bad command */
			continue;

/*进入find_cmd*/
/*链接文件中定义的	
	__u_boot_cmd_start = .;
	.u_boot_cmd : { *(.u_boot_cmd) }
	__u_boot_cmd_end = .;
*/
	for (cmdtp = &__u_boot_cmd_start;
	     cmdtp != &__u_boot_cmd_end;
	     cmdtp++) {
	     /*比较名字成功则返回结构体*/
		if (strncmp (cmd, cmdtp->name, len) == 0) {
			if (len == strlen (cmdtp->name))
				return cmdtp;	/* full match */
				/*不成功则指向下一个*/
			cmdtp_temp = cmdtp;	/* abbreviated command ? */
			n_found++;

/*bootcmd到底是什么东西,搜索bootcmd*/
U_BOOT_CMD(
 	bootm,	CFG_MAXARGS,	1,	do_bootm,
 	"bootm   - boot application image from memory\n",
 	"[addr [arg ...]]\n    - boot application image stored in memory\n"
 	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
 	"\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE
	"\tWhen booting a Linux kernel which requires a flat device-tree\n"
	"\ta third argument is required which is the address of the of the\n"
	"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
	"\tuse a '-' for the second argument. If you do not pass a third\n"
	"\ta bd_info struct will be passed instead\n"
#endif

/*command.h*/
#define Struct_Section  _attribute_((unused,section(".u_boot_cmd")))

/*U_BOOT_CMD定义方式*/
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

/*展开U_BOOT_CMD*/
/*定义了 __u_boot_cmd_结构体,结构体类型cmd_tbl_t 。强制把段属性设置为section(".u_boot_cmd"),正好和链接文件对应。U_BOOT_CMD宏展开后如下。所有用U_BOOT_CMD声明的都会定义一个__u_boot_cmd_结构体。所有的命令都会集中到链接文件的__u_boot_cmd_。开始就是__u_boot_cmd_start ,结束就是__u_boot_cmd_end*/
cmd_tbl_t __u_boot_cmd_##bootm _attribute_((unused,section(".u_boot_cmd"))) = {#bootm , CFG_MAXARGS, 1, do_bootm,"bootm   - boot application image from memory\n",
	"[addr [arg ...]]\n    - boot application image stored in memory\n"
 	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
 	"\t'arg' can be the address of an initrd image\n"}
);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
二、实验增加hello word

hello_command.c

/*包含Cmd_bootm.c(common)头文件*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <malloc.h>
#include <zlib.h>
#include <bzlib.h>
#include <environment.h>
#include <asm/byteorder.h>

int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	printf ("hello,word!, %d\n",argc);
	/*打印参数看下*/
	for (i=0;i<argc;i++)
	{
		printf ("argv[]: %s\n",i,argv[i]);
	}
	return 0;

}

U_BOOT_CMD(
 	hello,	CFG_MAXARGS,	1,	do_bootm,
 	"hello- just for test\n",
 	"hello- long help ...................\n",
);



  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

将文件拖入linux中common文件夹下,修改common下的makefile,增加cmd_hello.o。使用make 100ask24x0_config命令重新编译uboot。编译完成,将uboot.bin烧写进板子。输入help命令后会输出hello,word!等。

文章来源: blog.csdn.net,作者:嵌入式与Linux那些事,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_16933601/article/details/102827639

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。