首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>Linux 嵌入式>文章内容
嵌入式系统 Boot Loader 技术内幕
来源:IBM DW中国 作者:詹荣开 发布时间:2007-05-29  

params = (struct tag *)BOOT_PARAMS;

	params->hdr.tag = ATAG_CORE;
	params->hdr.size = tag_size(tag_core);

	params->u.core.flags = 0;
	params->u.core.pagesize = 0;
	params->u.core.rootdev = 0;

	params = tag_next(params);

其中,BOOT_PARAMS 表示内核启动参数在内存中的起始基地址,指针 params 是一个 struct tag 类型的指针。宏 tag_next() 将以指向当前标记的指针为参数,计算紧临当前标记的下一个标记的起始地址。注意,内核的根文件系统所在的设备ID就是在这里设置的。

下面是设置内存映射情况的示例代码:


for(i = 0; i < NUM_MEM_AREAS; i++) {
		if(memory_map[i].used) {
			params->hdr.tag = ATAG_MEM;
			params->hdr.size = tag_size(tag_mem32);

			params->u.mem.start = memory_map[i].start;
			params->u.mem.size = memory_map[i].size;
			
			params = tag_next(params);
		}
}

可以看出,在 memory_map[]数组中,每一个有效的内存段都对应一个 ATAG_MEM 参数标记。

Linux 内核在启动时可以以命令行参数的形式来接收信息,利用这一点我们可以向内核提供那些内核不能自己检测的硬件参数信息,或者重载(override)内核自己检测到的信息。比如,我们用这样一个命令行参数字符串"console=ttyS0,115200n8"来通知内核以 ttyS0 作为控制台,且串口采用 "115200bps、无奇偶校验、8位数据位"这样的设置。下面是一段设置调用内核命令行参数字符串的示例代码:


char *p;

	/* eat leading white space */
	for(p = commandline; *p == ' '; p++)
		;

	/* skip non-existent command lines so the kernel will still
    * use its default command line.
	 */
	if(*p == '\0')
		return;

	params->hdr.tag = ATAG_CMDLINE;
	params->hdr.size = (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;

	strcpy(params->u.cmdline.cmdline, p);

	params = tag_next(params);

请注意在上述代码中,设置 tag_header 的大小时,必须包括字符串的终止符'\0',此外还要将字节数向上圆整4个字节,因为 tag_header 结构中的size 成员表示的是字数。

下面是设置 ATAG_INITRD 的示例代码,它告诉内核在 RAM 中的什么地方可以找到 initrd 映象(压缩格式)以及它的大小:


	params->hdr.tag = ATAG_INITRD2;
	params->hdr.size = tag_size(tag_initrd);
	
	params->u.initrd.start = RAMDISK_RAM_BASE;
	params->u.initrd.size = INITRD_LEN;
	
	params = tag_next(params);

下面是设置 ATAG_RAMDISK 的示例代码,它告诉内核解压后的 Ramdisk 有多大(单位是KB):


params->hdr.tag = ATAG_RAMDISK;
params->hdr.size = tag_size(tag_ramdisk);
	
params->u.ramdisk.start = 0;
params->u.ramdisk.size = RAMDISK_SIZE; /* 请注意,单位是KB */
params->u.ramdisk.flags = 1; /* automatically load ramdisk */
	
params = tag_next(params);

最后,设置 ATAG_NONE 标记,结束整个启动参数列表:


static void setup_end_tag(void)
{
	params->hdr.tag = ATAG_NONE;
	params->hdr.size = 0;
}

3.2.5 调用内核

Boot Loader 调用 Linux 内核的方法是直接跳转到内核的第一条指令处,也即直接跳转到 MEM_START+0x8000 地址处。在跳转时,下列条件要满足:

1. CPU 寄存器的设置:

  • R0=0;

  • R1=机器类型 ID;关于 Machine Type Number,可以参见 linux/arch/arm/tools/mach-types。

  • R2=启动参数标记列表在 RAM 中起始基地址;

2. CPU 模式:

  • 必须禁止中断(IRQs和FIQs);

  • CPU 必须 SVC 模式;

3. Cache 和 MMU 的设置:

  • MMU 必须关闭;

  • 指令 Cache 可以打开也可以关闭;

  • 数据 Cache 必须关闭;

如果用 C 语言,可以像下列示例代码这样来调用内核:

共6页: 上一页 [1] [2] [3] [4] 5 [6] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·嵌入式Linux系统下图形库讲解及
·Qt/Embedded在嵌入式Linux中的应
·嵌入式Linux:uClinux操作系统移
·嵌入式 用户图形接口uC/GUI的简
·基于GTK+和X的GUI在嵌入式Linux
·嵌入式Linux系统下的MiniGUI研究
·Linux串口上网的简单实现 (图解)
·在Ubuntu上建立Arm Linux的开发
·嵌入式Linux操作系统启动信息完
·Linux 2.6 内核的嵌入式系统应用
·嵌入式Linux在Blackfin处理器上
·嵌入式uClinux的内核结构和开发
  相关文章
·嵌入式程序员应知道的几个基本问
·基于μClinux的SoPC应用系统设计
·嵌入式Linux系统的图像采集与显
·主流嵌入式Linux系统下GUI解决方
·教你一种实现嵌入式Linux系统新
·Linux 2.6 内核的嵌入式系统应用
·关于嵌入式Linux系统进程调度的
·基于嵌入式Linux平台的多协议路
·嵌入式Linux系统的GDB远程调试的
·嵌入式Linux在Blackfin处理器上
·精华:学习嵌入式Linux的笔记和
·嵌入式Linux:uClinux操作系统移

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!