Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15482793
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2007-08-02 08:16:55

浅析armlinux-setup_arch()->convert_to_tag_list()函数3

文章来源:http://gliethttp.cublog.cn

建议首先参考《浅析armlinux2_4_19启动程序[head-armv.s文件][http://gliethttp.cublog.cn]


//1.旧格式param_struct结构体
#define COMMAND_LINE_SIZE 1024
/* This is the old deprecated way to pass parameters to the kernel */
struct param_struct {
    union {
    struct {
     unsigned long page_size;           /* 0 */
     unsigned long nr_pages;            /* 4 */
     unsigned long ramdisk_size;        /* 8 */
     unsigned long flags;               /* 12 */
#define FLAG_READONLY    1
#define FLAG_RDLOAD    4
#define FLAG_RDPROMPT    8
     unsigned long rootdev;             /* 16 */
     unsigned long video_num_cols;      /* 20 */
     unsigned long video_num_rows;      /* 24 */
     unsigned long video_x;             /* 28 */
     unsigned long video_y;             /* 32 */
     unsigned long memc_control_reg;    /* 36 */
     unsigned char sounddefault;        /* 40 */
     unsigned char adfsdrives;          /* 41 */
     unsigned char bytes_per_char_h;    /* 42 */
     unsigned char bytes_per_char_v;    /* 43 */
     unsigned long pages_in_bank[4];    /* 44 */
     unsigned long pages_in_vram;       /* 60 */
     unsigned long initrd_start;        /* 64 */
     unsigned long initrd_size;         /* 68 */
     unsigned long rd_start;            /* 72 */
     unsigned long system_rev;          /* 76 */
     unsigned long system_serial_low;   /* 80 */
     unsigned long system_serial_high/* 84 */
     unsigned long mem_fclk_21285;      /* 88 */
    } s;
    char unused[256];
    } u1;
    union {
    char paths[8][128];
    struct {
     unsigned long magic;
     char n[1024 - sizeof(unsigned long)];
    } s;
    } u2;
    char commandline[COMMAND_LINE_SIZE];
};
//2.arch/arm/kernel/Compat.c->convert_to_tag_list()
//if (tags->hdr.tag != ATAG_CORE)//如果传递参数非tag list格式,那么就是param_struct格式
//convert_to_tag_list(tags);
//使用convert_to_tag_list将param_struct格式参数转化为tag list格式参数
void __init convert_to_tag_list(struct tag *tags)
{//tags地址为物理地址0x20000100[gliethttp]
    struct param_struct *params = (struct param_struct *)tags;
    build_tag_list(params, &params->u2);//将转换结果临时存储在¶ms->u2,之后拷贝到params
}
//3.arch/arm/kernel/Compat.c->build_tag_list()
static void __init build_tag_list(struct param_struct *params, void *taglist)
{struct tag *tag = taglist;
    if (params->u1.s.page_size != PAGE_SIZE) {
        printk(KERN_WARNING "Warning: bad configuration page, "
         "trying to continue\n");
        return;
    }
    printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
//ATAG_CORE 将params下core相关设置,转换成tag,形成list[gliethttp]
    tag->hdr.tag = ATAG_CORE;
    tag->hdr.size = tag_size(tag_core);
    tag->u.core.flags = params->u1.s.flags & FLAG_READONLY;
    tag->u.core.pagesize = params->u1.s.page_size;
    tag->u.core.rootdev = params->u1.s.rootdev;
//ATAG_RAMDISK 紧跟着ATAG_CORE继续存储
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_RAMDISK;
    tag->hdr.size = tag_size(tag_ramdisk);
    tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) |
                           (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0);
    tag->u.ramdisk.size = params->u1.s.ramdisk_size;
    tag->u.ramdisk.start = params->u1.s.rd_start;
//ATAG_INITRD 紧跟存储
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_INITRD;
    tag->hdr.size = tag_size(tag_initrd);
    tag->u.initrd.start = params->u1.s.initrd_start;
    tag->u.initrd.size = params->u1.s.initrd_size;
//ATAG_SERIAL
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_SERIAL;
    tag->hdr.size = tag_size(tag_serialnr);
    tag->u.serialnr.low = params->u1.s.system_serial_low;
    tag->u.serialnr.high = params->u1.s.system_serial_high;
//ATAG_REVISION
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_REVISION;
    tag->hdr.size = tag_size(tag_revision);
    tag->u.revision.rev = params->u1.s.system_rev;

#ifdef CONFIG_ARCH_ACORN//false
    if (machine_is_riscpc()) {
        int i;
        //4个memory块
        for (i = 0; i < 4; i++)
            tag = memtag(tag, PHYS_OFFSET + (i << 26),
                 params->u1.s.pages_in_bank[i] * PAGE_SIZE);
    } else
#endif
    //ok,只有一个32M[0x2000000]内存块,见后
    tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);

#ifdef CONFIG_FOOTBRIDGE//未用
    if (params->u1.s.mem_fclk_21285) {
        tag = tag_next(tag);
        tag->hdr.tag = ATAG_MEMCLK;
        tag->hdr.size = tag_size(tag_memclk);
        tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285;
    }
#endif

#ifdef CONFIG_ARCH_EBSA285//未用
    if (machine_is_ebsa285()) {
        tag = tag_next(tag);
        tag->hdr.tag = ATAG_VIDEOTEXT;
        tag->hdr.size = tag_size(tag_videotext);
        tag->u.videotext.x     = params->u1.s.video_x;
        tag->u.videotext.y     = params->u1.s.video_y;
        tag->u.videotext.video_page = 0;
        tag->u.videotext.video_mode = 0;
        tag->u.videotext.video_cols = params->u1.s.video_num_cols;
        tag->u.videotext.video_ega_bx = 0;
        tag->u.videotext.video_lines = params->u1.s.video_num_rows;
        tag->u.videotext.video_isvga = 1;
        tag->u.videotext.video_points = 8;
    }
#endif

#ifdef CONFIG_ARCH_ACORN//未用
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_ACORN;
    tag->hdr.size = tag_size(tag_acorn);
    tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg;
    tag->u.acorn.vram_pages = params->u1.s.pages_in_vram;
    tag->u.acorn.sounddefault = params->u1.s.sounddefault;
    tag->u.acorn.adfsdrives = params->u1.s.adfsdrives;
#endif
//ATAG_CMDLINE 
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_CMDLINE;
    tag->hdr.size = (strlen(params->commandline) + 3 +
             sizeof(struct tag_header)) >> 2;
    strcpy(tag->u.cmdline.cmdline, params->commandline);
//ATAG_NONE 明确的结尾标识
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_NONE;
    tag->hdr.size = 0;
//间缓存到taglist中的tag list数据转储到params
    memmove(params, taglist, ((int)tag) - ((int)taglist) +
            sizeof(struct tag_header)/*ATAG_NONE的长度*/);
}
//4.arch/arm/kernel/Compat.c->memtag()
static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size)
{
//ATAG_MEM 紧跟前一个tag,start=0x20000000
    tag = tag_next(tag);
    tag->hdr.tag = ATAG_MEM;
    tag->hdr.size = tag_size(tag_mem32);
    tag->u.mem.size = size;
    tag->u.mem.start = start;
    return tag;
}
//5.lib/String.c->memmove
void * memmove(void * dest,const void *src,size_t count)
{char *tmp, *s;
    if (dest <= src) {//如果dest在src的前面,那么顺序++拷贝绝对不会出现覆盖
        tmp = (char *) dest;
        s = (char *) src;
        while (count--)
            *tmp++ = *s++;
        }
    else {//如果dest在src的后面,那么从+count处,倒着拷贝不会出现覆盖[gliethttp]
        tmp = (char *) dest + count;
        s = (char *) src + count;
        while (count--)
            *--tmp = *--s;
        }
    return dest;
}

阅读(3080) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~