内核启动参数
Linux 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。启动参数标记列表以标记 ATAG_CORE 开始,以标记 ATAG_NONE 结束。每个标记由标识被传递参数的 tag_header 结构以及随后的参数值数据结构来组成。数据结构 tag 和 tag_header 定义在 Linux 内核源码的include/asm/setup.h 头文件中:
// 文件首部定义了struct tag的指针:
static struct tag *params;
// include/arm_asm/setup.h文件定义了一些Tag相关的结构
struct tag {
struct tag_header hdr; // 每个tag都有头
union { // tag的类型
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;
struct tag_acorn acorn;
struct tag_memclk memclk;
} u;
};
===================================================================
// 得到下一个tag段地址
#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
// 获得tag的大小,长度都是以4字节为单位
#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
#define ATAG_NONE 0x00000000
// tag的头定义
struct tag_header {
u32 size;
u32 tag;
};
// ATAG_CORE相关定义
#define ATAG_CORE 0x54410001
struct tag_core {
u32 flags; /* bit 0 = read-only */
u32 pagesize;
u32 rootdev;
};
// setup_start_tag用于设置ATAG_CORE段(起始段)
static void setup_start_tag (bd_t *bd)
{
params = (struct tag *) bd->bi_boot_params;
params->hdr.tag = ATAG_CORE; // 设置core段tag
// 得到tag标记大小(单位字)
// #define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
// 包含tag头和本tag结构体数据
params->hdr.size = tag_size (tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
// #define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
// 得到下一个tag段位置的指针, 用于接下来的tag标记保存
params = tag_next (params);
}
// ATAG_MEM相关定义
#define ATAG_MEM 0x54410002
struct tag_mem32 {
u32 size;
u32 start; /* physical start address */
};
// 内存段tag的设置
static void setup_memory_tags (bd_t *bd)
{
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); // 取得下一个tag地址
}
}
// 命令行参数设置
#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;
for (p = commandline; *p == ' '; p++); // 去掉字符串之前的空格
// 不存在commandline时使用默认的(没有时使用系统默认的)
if (*p == '\0')
return;
params->hdr.tag = ATAG_CMDLINE; // 命令行tag起始
params->hdr.size = // 设置字符串长度
(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
strcpy (params->u.cmdline.cmdline, p); // 拷贝命令行参数
params = tag_next (params);
}
// Ramdisk设置,当系统中存在这个段时需要进行设置,如果不需要就不用设置了
#define ATAG_INITRD2 0x54420005
struct tag_initrd {
u32 start; /* physical start address */
u32 size; /* size of compressed ramdisk image in bytes */
};
static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
{
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);
}
(本文章发表于psbec的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如有任何问题,请留言或者发邮件给psbec,地址)
阅读(1191) | 评论(0) | 转发(0) |