u_boot和Linux内核之间的参数传递

今天学了U_boot和Linux内核之间的参数传递,分享一下,写得不好勿怪......

u_boot完成的硬件的相关初始化,是知道Linux内核的相关信息的,但是Linux是直接被加载到内存中去的,刚开始对u_boot是一脸懵逼的,那怎么办呢?当然是u_boot告诉Linux内核一些信息,这就是所谓的参数传递。

u_boot主要传递给Linux内核3个参数:

r0:0x0   

r1 : 开发板的ID         ------------------ r1的参数,是让Linux内核自己去判断,它是否支持当前的开发板

r2 : 其他参数在内存中开始的地址

r2传递的开始地址中含有的信息

(1)内存的信息 -------- 内存的开始地址和内存的大小
   
(2)命令行参数:bootargs的内容--------------- 告诉Linux内核启动后,挂载文件系统的方式(例如:NFS方式)
 
(3)其他信息


r2只传递了开始的地址,并没有告诉Linux内核传递的参数内存的大小,那Linux内核是怎么知道什么时候结束的呢?

u_boot和Linux内核早就谈好了的,我们规定格式,双方按照规矩来办事。


目前Linux内核支持哪些格式的传递呢?

(1):通过struct parm_struct结构体来传递 (Linux 2.6之前使用的方式,已经过时,不便于扩展)

(2):通过tag列表来传递 (Linux 2.6开始使用的方式)       --------      一个tag节点包含了tag头 + 大小 + 内容



(3):通过设备树来传递(Linux 3.0开始使用的方式)   -----   u_boot 修改了设备树的节点,把需要传递的信息放在了设备树中



我的环境是:Linux内核版本----3.2.0-29-generic-pae

                       ubuntu版本是12.04-1

下面是部分源码,大家想看源码的可以去u_boot下的arch/arm/lib/bootm.c查看(这是我的u_boot的路径,不同的内核或者BootLoader都可能不同)

/* Main Entry point for arm bootm implementation
 *
 * Modeled after the powerpc implementation
 * DIFFERENCE: Instead of calling prep and go at the end
 * they are called if subcommand is equal 0.
 */
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
	/* No need for those on ARM */
	if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
		return -1;

	if (flag & BOOTM_STATE_OS_PREP) {
		boot_prep_linux(images);
		return 0;
	}

	if (flag & BOOTM_STATE_OS_GO) {
		boot_jump_linux(images);
		return 0;
	}

	boot_prep_linux(images);
	boot_jump_linux(images);
	return 0;
}

/* Subcommand: PREP */
static void boot_prep_linux(bootm_headers_t *images)
{
#ifdef CONFIG_CMDLINE_TAG
	char *commandline = getenv("bootargs");
#endif

#ifdef CONFIG_OF_LIBFDT
	if (images->ft_len) {
		debug("using: FDT\n");
		if (create_fdt(images)) {
			printf("FDT creation failed! hanging...");
			hang();
		}
	} else
#endif

/* Subcommand: GO */
static void boot_jump_linux(bootm_headers_t *images)
{
	unsigned long machid = gd->bd->bi_arch_number;
	char *s;
	void (*kernel_entry)(int zero, int arch, uint params);
	unsigned long r2;

	kernel_entry = (void (*)(int, int, uint))images->ep;

	s = getenv("machid");
	if (s) {
		strict_strtoul(s, 16, &machid);
		printf("Using machid 0x%lx from environment\n", machid);
	}

	debug("## Transferring control to Linux (at address %08lx)" \
		"...\n", (ulong) kernel_entry);
	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
	announce_and_cleanup();

#ifdef CONFIG_OF_LIBFDT
	if (images->ft_len)
		r2 = (unsigned long)images->ft_addr;
	else
#endif
		r2 = gd->bd->bi_boot_params;

	kernel_entry(0, machid, r2);
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值