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

 
bootloader 通过 tags 传递配置参数到 linux kernel
tags 的定义:
 Tag tagcore 开始,以  null 结束
      unsigned * ptr=tags tags 是存放 tag 的物理地址)
        Ptr++=2
        Ptr++=ATAG_CORE;
        以上是开始
   …………………………… 其他 tag
        Tag 是这样的一个结构体。第一个偏移是 tag 的大小,第二个是 tag 号。接下来就是 tag 大小 -2 tag 数据。注意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 的虚拟地址空间中
 
做个备忘

转载于:https://www.cnblogs.com/soc-linux-driver/archive/2012/07/10/2584612.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值