Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->嵌入式系统 ->正文

嵌入式系统 Boot Loader 技术内幕

来源:IBM DW中国 作者:詹荣开  时间:2007-04-22 点击: [收藏] [投稿]

在用上述算法检测完系统的内存映射情况后,Boot Loader 也可以将内存映射的详细信息打印到串口。

3.2.3 加载内核映像和根文件系统映像

(1) 规划内存占用的布局

这里包括两个方面:(1)内核映像所占用的内存范围;(2)根文件系统所占用的内存范围。在规划内存占用的布局时,主要考虑基地址和映像的大小两个方面。

对于内核映像,一般将其拷贝到从(MEM_START+0x8000) 这个基地址开始的大约1MB大小的内存范围内(嵌入式 Linux 的内核一般都不操过 1MB)。为什么要把从 MEM_START 到 MEM_START+0x8000 这段 32KB 大小的内存空出来呢?这是因为 Linux 内核要在这段内存中放置一些全局数据结构,如:启动参数和内核页表等信息。

而对于根文件系统映像,则一般将其拷贝到 MEM_START+0x0010,0000 开始的地方。如果用 Ramdisk 作为根文件系统映像,则其解压后的大小一般是1MB。

(2)从 Flash 上拷贝

由于像 ARM 这样的嵌入式 CPU 通常都是在统一的内存地址空间中寻址 Flash 等固态存储设备的,因此从 Flash 上读取数据与从 RAM 单元中读取数据并没有什么不同。用一个简单的循环就可以完成从 Flash 设备上拷贝映像的工作:

 
while(count) {
	*dest++ = *src++; /* they are all aligned with word boundary */
	count -= 4; /* byte number */
};

3.2.4 设置内核的启动参数

应该说,在将内核映像和根文件系统映像拷贝到 RAM 空间中后,就可以准备启动 Linux 内核了。但是在调用内核之前,应该作一步准备工作,即:设置 Linux 内核的启动参数。

Linux 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。启动参数标记列表以标记 ATAG_CORE 开始,以标记 ATAG_NONE 结束。每个标记由标识被传递参数的 tag_header 结构以及随后的参数值数据结构来组成。数据结构 tag 和 tag_header 定义在 Linux 内核源码的include/asm/setup.h 头文件中:


/* The list ends with an ATAG_NONE node. */
#define ATAG_NONE	0x00000000

struct tag_header {
	u32 size; /* 注意,这里size是字数为单位的 */
	u32 tag;
};
……
struct tag {
	struct tag_header hdr;
	union {
		struct tag_core		core;
		struct tag_mem32	mem;
		struct tag_videotext	videotext;
		struct tag_ramdisk	ramdisk;
		struct tag_initrd	initrd;
		struct tag_serialnr	serialnr;
		struct tag_revision	revision;
		struct tag_videolfb	videolfb;
		struct tag_cmdline	cmdline;

		/*
		 * Acorn specific
		 */
		struct tag_acorn	acorn;

		/*
		 * DC21285 specific
		 */
		struct tag_memclk	memclk;
	} u;
};

在嵌入式 Linux 系统中,通常需要由 Boot Loader 设置的常见启动参数有:ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等。

比如,设置 ATAG_CORE 的代码如下:


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 成员表示的是字数。

 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<

上一页 1 2 3 45 下一页


上一篇:FREEBSD下使用crunch集成编译程序   下一篇:嵌入式Linux 中的应用中的GTK+

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
·从Linux BIOS的起源 看未来主板框架
·怎么样从FireWire 设备引导Linux
·教你怎么样从FireWire 设备引导Linux
·嵌入式程序员应知道的几个基本问题(2)
·嵌入式程序员应知道的几个基本问题(1)
·Linux 助力 Nokia 770
·嵌入式Linux 中的应用中的GTK+
·嵌入式系统 Boot Loader 技术内幕
·FREEBSD下使用crunch集成编译程序
·ucLinux下sqlite数据库移植全攻略
推荐文章
·Linux操作系统的嵌入式领域面临新挑
·Linux串口上网的简单实现
·精华:学习嵌入式Linux的笔记和体会
·几种Linux嵌入式开发环境的简单介绍
·谈嵌入式Linux技术的现状与发展动向
·Linux 助力 Nokia 770
·教你轻松控制 uClinux 嵌入式开发过
·嵌入式系统中的模块动态加载技术
精彩文章
·TimeStorm——刮来嵌入式Linux的实
·Linux操作系统的嵌入式领域面临新挑
·嵌入式系统 Boot Loader 技术内幕
·向嵌入式Linux移植实时设备驱动程序
·从Linux BIOS的起源 看未来主板框架
·嵌入式uClinux的内核结构和开发环境
·BusyBox 简化嵌入式 Linux 系统
·把设备驱动程序编译进嵌入式Linux内
·嵌入式Linux 中的应用中的GTK+
·Linux下的硬件驱动——USB设备(下
·嵌入式Linux操作系统启动信息完全注
·Qt/Embedded在嵌入式Linux中的应用
·嵌入式操作系统的两种远程调试方案
·教你轻松控制 uClinux 嵌入式开发过
·Linux嵌入式系统开发平台选型探讨
·嵌入式Linux系统中应用的GTK+和X分
·基于GTK+和X的GUI在嵌入式Linux的应
·必看:嵌入式系统及系统级可编程产
·改进嵌入式Linux系统实时性新方案
·擂台战 嵌入式Linux面临图形化挑战
·嵌入式Linux中的GUI系统的研究与移
·一种嵌入式Linux平台的软硬件设计
·实时嵌入式系统的图形界面支持系统
·ESG携手飞漫软件提供嵌入式Linux服
·嵌入式系统 MiniGUI 背景 发展及优
·基于嵌入式Linux平台的多协议路由器
Power by linux-cn.com 粤ICP备05006655号