bootloader 内核启动参数
2013-04-05 11:16
357 查看
Bootloader与内核的交互
Bootloader与内核的交互是单向的,Bootloader将各类参数传给内核。由于它们不能同时运行,传递办法只有一个:Bootloader将参数放在某个约定的地方之后,再启动内核,内核启动后从这个地方获得参数。
除了约定好参数存放的地址外,还要规定参数的结构。Linux 2.4.x 以后的内核都期望以标记列表(taggedlist)的形式来传递启动参数。标记,就是一种数据结构;标记列表,就是挨着存放的多个标记。标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束。标记的数据结构为tag,它由一个tag_header结构和一个联合(union)组成。tag_header结构表示标记的类型及长度,比如是表示内存还是表示命令行参数等。对于不同类型的标记使用不同的联合(union),比如表示内存时使用tag_mem32,表示命令行时使用tag_cmdline。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中:
1、启动参数标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束。每个标记由标识被传递的tag_header结构和随后的参数值结构组成。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中。
static struct tag *params;
struct tag {
struct tag_header hdr;//每个tag都有头
union {
struct tag_core
core;//tag的类型
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;
};
#define tag_next(t)
((struct tag *)((u32 *)(t) + (t)->hdr.size))//得到下一个tag段地址
#define tag_size(type)
((sizeof(struct tag_header) + sizeof(struct type)) >> 2)//获得tag的大小,长度都是以4个字节为单位
/* The list ends with an ATAG_NONE node. */
#define ATAG_NONE 0x00000000 //表单以ATAG_NONE node点结束
struct tag_header { //tag的头定义
u32 size;
u32 tag;
};
2、/* The list must start with an ATAG_CORE node */
#define ATAG_CORE 0x54410001 //表单必须以ATAG_CORE node点开始
struct tag_core { //ATAG_CORE相关定义
u32 flags;
/* bit 0 = read-only */
u32 pagesize;
u32 rootdev;
};
static void setup_start_tag (bd_t *bd)//用于设置ATAG_CORE段(起始段)
{
params = (struct tag *) bd->bi_boot_params;//地址
params->hdr.tag = ATAG_CORE;//设置core段tag
params->hdr.size = tag_size (tag_core);//得到tag标记大小,包含tag头和tag结构体数据
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);//得到下一个tag段位置的指针,用于接下来的tag标记保存
}
3、/* it is allowed to have multiple ATAG_MEM nodes */
#define ATAG_MEM 0x54410002
struct tag_mem32 {
u32 size;
u32 start;
/* physical start address */物理起始地址
};
#ifdef CONFIG_SETUP_MEMORY_TAGS
static void setup_memory_tags (bd_t *bd)//内存段tag的设置
{
int i;
//系统在存在的内存段来设定此参数,存在多个内存段是需要单独设置
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM; //内存段类型设置
params->hdr.size = tag_size (tag_mem32);//设置大小
params->u.mem.start = bd->bi_dram[i].start;//起始地址
params->u.mem.size = bd->bi_dram[i].size;//大小
params = tag_next (params);
}
}
#endif /* CONFIG_SETUP_MEMORY_TAGS */
4、/* command line: \0 terminated string */命令行
#define ATAG_CMDLINE 0x54410009
struct tag_cmdline {
char cmdline[1];
/* this is the minimum size */
};
static void setup_commandline_tag (bd_t *bd, char *commandline)
{
char *p;
if (!commandline)
return;
/* 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);
}
5、/* describes where the compressed ramdisk image lives (physical address) */
#define ATAG_INITRD2 0x54420005
struct tag_initrd {
u32 start;
/* physical start address */
u32 size;
/* size of compressed ramdisk image in bytes */
};
#ifdef CONFIG_INITRD_TAG
static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
{
/* an ATAG_INITRD node tells the kernel where the compressed
* ramdisk can be found. ATAG_RDIMG is a better name, actually.
*/
params->hdr.tag = ATAG_INITRD2;
params->hdr.size = tag_size (tag_initrd);
params->u.initrd.start = initrd_start;
params->u.initrd.size = initrd_end - initrd_start;
params = tag_next (params);
}
#endif /* CONFIG_INITRD_TAG */
Bootloader与内核的交互是单向的,Bootloader将各类参数传给内核。由于它们不能同时运行,传递办法只有一个:Bootloader将参数放在某个约定的地方之后,再启动内核,内核启动后从这个地方获得参数。
除了约定好参数存放的地址外,还要规定参数的结构。Linux 2.4.x 以后的内核都期望以标记列表(taggedlist)的形式来传递启动参数。标记,就是一种数据结构;标记列表,就是挨着存放的多个标记。标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束。标记的数据结构为tag,它由一个tag_header结构和一个联合(union)组成。tag_header结构表示标记的类型及长度,比如是表示内存还是表示命令行参数等。对于不同类型的标记使用不同的联合(union),比如表示内存时使用tag_mem32,表示命令行时使用tag_cmdline。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中:
1、启动参数标记列表以标记ATAG_CORE开始,以标记ATAG_NONE结束。每个标记由标识被传递的tag_header结构和随后的参数值结构组成。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中。
static struct tag *params;
struct tag {
struct tag_header hdr;//每个tag都有头
union {
struct tag_core
core;//tag的类型
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;
};
#define tag_next(t)
((struct tag *)((u32 *)(t) + (t)->hdr.size))//得到下一个tag段地址
#define tag_size(type)
((sizeof(struct tag_header) + sizeof(struct type)) >> 2)//获得tag的大小,长度都是以4个字节为单位
/* The list ends with an ATAG_NONE node. */
#define ATAG_NONE 0x00000000 //表单以ATAG_NONE node点结束
struct tag_header { //tag的头定义
u32 size;
u32 tag;
};
2、/* The list must start with an ATAG_CORE node */
#define ATAG_CORE 0x54410001 //表单必须以ATAG_CORE node点开始
struct tag_core { //ATAG_CORE相关定义
u32 flags;
/* bit 0 = read-only */
u32 pagesize;
u32 rootdev;
};
static void setup_start_tag (bd_t *bd)//用于设置ATAG_CORE段(起始段)
{
params = (struct tag *) bd->bi_boot_params;//地址
params->hdr.tag = ATAG_CORE;//设置core段tag
params->hdr.size = tag_size (tag_core);//得到tag标记大小,包含tag头和tag结构体数据
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);//得到下一个tag段位置的指针,用于接下来的tag标记保存
}
3、/* it is allowed to have multiple ATAG_MEM nodes */
#define ATAG_MEM 0x54410002
struct tag_mem32 {
u32 size;
u32 start;
/* physical start address */物理起始地址
};
#ifdef CONFIG_SETUP_MEMORY_TAGS
static void setup_memory_tags (bd_t *bd)//内存段tag的设置
{
int i;
//系统在存在的内存段来设定此参数,存在多个内存段是需要单独设置
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM; //内存段类型设置
params->hdr.size = tag_size (tag_mem32);//设置大小
params->u.mem.start = bd->bi_dram[i].start;//起始地址
params->u.mem.size = bd->bi_dram[i].size;//大小
params = tag_next (params);
}
}
#endif /* CONFIG_SETUP_MEMORY_TAGS */
4、/* command line: \0 terminated string */命令行
#define ATAG_CMDLINE 0x54410009
struct tag_cmdline {
char cmdline[1];
/* this is the minimum size */
};
static void setup_commandline_tag (bd_t *bd, char *commandline)
{
char *p;
if (!commandline)
return;
/* 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);
}
5、/* describes where the compressed ramdisk image lives (physical address) */
#define ATAG_INITRD2 0x54420005
struct tag_initrd {
u32 start;
/* physical start address */
u32 size;
/* size of compressed ramdisk image in bytes */
};
#ifdef CONFIG_INITRD_TAG
static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
{
/* an ATAG_INITRD node tells the kernel where the compressed
* ramdisk can be found. ATAG_RDIMG is a better name, actually.
*/
params->hdr.tag = ATAG_INITRD2;
params->hdr.size = tag_size (tag_initrd);
params->u.initrd.start = initrd_start;
params->u.initrd.size = initrd_end - initrd_start;
params = tag_next (params);
}
#endif /* CONFIG_INITRD_TAG */
相关文章推荐
- bootloader 内核启动参数
- 通过bootloader向内核传输启动参数
- 通过bootloader向内核传输启动参数
- bootloader 内核启动参数
- 增加自定义的内核启动参数(转)
- 【转载】在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- BootLoader与Linux内核的参数传递
- 通过 bootloader 向其传输启动参数
- Linux操作系统内核启动参数详细解析
- 内核启动时怎么处理启动参数
- 用户空间与内核空间数据交换的方式(5)------内核启动参数
- 在linux上给grub添加内核启动参数
- linux-3.2.36内核启动1-启动参数(arm平台 启动参数的获取和处理,分析setup_arch)
- 内核参数修改导致数据库无法启动
- arm-linux内核start_kernel之前启动分析(1)-接过bootloader的衣钵
- linux内核常用启动参数
- man bootparam 内核启动参数文档
- Linux操作系统内核启动参数详细解析
- Linux内核启动参数
- 【转载】在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink