Chinaunix首页 | 论坛 | 博客
  • 博客访问: 77636
  • 博文数量: 28
  • 博客积分: 1415
  • 博客等级: 上尉
  • 技术积分: 351
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-15 13:18
个人简介

I bet you dont want to know.

文章分类

全部博文(28)

分类: LINUX

2008-08-01 23:45:06

内核启动参数
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) |
给主人留下些什么吧!~~