bootloader 传递参数给内核 atag的用法

 
bootloader 通过tags传递配置参数到linux kernel
tags的定义:
 Tagtagcore开始,以 null结束
      unsigned * ptr=tags tags是存放tag的物理地址)
        Ptr++=2
        Ptr++=ATAG_CORE;
        以上是开始
   ……………………………其他tag
        Tag是这样的一个结构体。第一个偏移是tag的大小,第二个是tag号。接下来就是tag大小-2tag数据。注意tag中的每一项都是4字节对齐的。
       
        Ptr++=0
        Ptr++=0
以上是结束
下面是一个例子
 1 void boot_linux(void *kernel, unsigned *tags,
 2         const char *cmdline, unsigned machtype,
 3         void *ramdisk, unsigned ramdisk_size)
 4 {
 5     unsigned *ptr = tags;
 6         /* CORE */
 7     *ptr++ = 2;
 8     *ptr++ = 0x54410001;   构建tag 头 0x54410001这个数就是ATAG_CORE
 9     if (ramdisk_size) {
10         *ptr++ = 4;
11         *ptr++ = 0x54420005;
12         *ptr++ = (unsigned)ramdisk;
13         *ptr++ = ramdisk_size;  构建内容 ramdisl
14     }
15     ptr = target_atag_mem(ptr); 构建内容 mem
16         }
17         }
18     /* END */
19     *ptr++ = 0;
20     *ptr++ = 0;  构建结束标志
21     dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d)\n",
22         kernel, ramdisk, ramdisk_size);
23     
24 }
 上面显示了构建一个tag的方法
  
构建tags 头: tag头是以ATAG_CORE tags标志的一段内存
构建tags的内容: 下面的代码显示构建过程
构建tags尾: null结束
#define SIZE_44M              0x02C00000 // 44M
#define EBI1_ADDR_1026M       0x40200000
#define SIZE_128M             0x08000000 // 128M
#define EBI1_ADDR_1152M       0x48000000
#define SIZE_256M             0x10000000 // 256M
#define EBI1_ADDR_1280M       0x50000000
#define SIZE_768M             0x30000000 // 256M + 512M
#define EBI1_CS1_ADDR_BASE    0x00A40024
unsigned* target_atag_mem(unsigned* ptr)
{
    unsigned value = 0;
    /* ATAG_MEM */
    *ptr++ = 4;
    *ptr++ = 0x54410002;
    *ptr++ = SIZE_44M;
    *ptr++ = EBI1_ADDR_1026M;
    *ptr++ = 4;
    *ptr++ = 0x54410002;
    *ptr++ = SIZE_128M;
    *ptr++ = EBI1_ADDR_1152M;
    value = readl(EBI1_CS1_ADDR_BASE);
    value = (value >> 8) & 0xFF;
    if (value == 0x50)
    {
        /* For 512MB RAM*/
        *ptr++ = 4;
        *ptr++ = 0x54410002;
        *ptr++ = SIZE_256M;
        *ptr++ = EBI1_ADDR_1280M;
    }
    else if (value == 0x60)
    {
        /* For 1GB RAM*/
        *ptr++ = 4;
        *ptr++ = 0x54410002;
        *ptr++ = SIZE_768M;
        *ptr++ = EBI1_ADDR_1280M;
    }
    return ptr;
}
atag的解析
 
1 定义一个tag  ATAG_MSM_PARTITION 0X4D534D70
 2 编写tag处理函数
     Static int __init parse_tag_msm_partition(const struct tag * tag)
 3 注册tag
__tagtable(ATAG_MSM_PARTITION, parse_tag_msm_partition)
 到此 parse_tag_msm_partition 函数在系统启动时会调用
memtag的解析
 
Setup.c
static int __init parse_tag_mem32(const struct tag *tag)
{
return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
}
__tagtable(ATAG_MEM, parse_tag_mem32);
arm_add_memory 会把tag中的mem块添加到meminfo 结构中,在系统安装mem时会把他们连续的映射到linux的虚拟地址空间中
 
做个备忘
posted @ 2012-07-10 14:32  camera&tunning  阅读(1381)  评论(0编辑  收藏  举报