浅析setup_arch()函数tag_list的uboot由来

 1. linux中
//------------------------------------------------------
arch/ arm/ kernel/ setup. c- > setup_arch( )
void __init setup_arch( char * * cmdline_p)
{
    struct tag * tags = ( struct tag * ) & init_tags;
    struct machine_desc * mdesc;
    char * from = default_command_line;
    ROOT_DEV = MKDEV( 0, 255) ;
    setup_processor( ) ;
    mdesc = setup_machine( machine_arch_type) ;
    machine_name = mdesc- > name;
    if ( mdesc- > soft_reboot)
        reboot_setup( "s" ) ;
    if ( mdesc- > param_offset)
        tags = phys_to_virt( mdesc- > param_offset) ;     //tags指向AT91_SDRAM_BASE + 0x100地址,该地址处的tag list由uboot生成
    /*
     * Do the machine-specific fixups before we parse the
     * parameters or tags.
     */

    if ( mdesc- > fixup)
        mdesc- > fixup( mdesc, ( struct param_struct * ) tags,
             & from, & meminfo) ;
    /*
     * If we have the old style parameters, convert them to
     * a tag list.
     */

    if ( tags- > hdr. tag ! = ATAG_CORE)                   //2007-07-05 gliethttp 非tag list需要转换;不过uboot传递的是tag list
        convert_to_tag_list( tags) ;
    if ( tags- > hdr. tag = = ATAG_CORE) {
        if ( meminfo. nr_banks ! = 0)                   //具体的解析
            squash_mem_tags( tags) ;
        parse_tags( tags) ;
    }
    if ( meminfo. nr_banks = = 0) {
        meminfo. nr_banks = 1;
        meminfo. bank[ 0] . start = PHYS_OFFSET;
        meminfo. bank[ 0] . size = MEM_SIZE;
    }
    init_mm. start_code = ( unsigned long ) & _text;
    init_mm. end_code = ( unsigned long ) & _etext;
    init_mm. end_data = ( unsigned long ) & _edata;
    init_mm. brk     = ( unsigned long ) & _end;

    memcpy ( saved_command_line, from, COMMAND_LINE_SIZE) ;
    saved_command_line[ COMMAND_LINE_SIZE- 1] = '/0' ;
    parse_cmdline( & meminfo, cmdline_p, from) ;
    bootmem_init( & meminfo) ;
    paging_init( & meminfo, mdesc) ;
    request_standard_resources( & meminfo, mdesc) ;
    /*
     * Set up various architecture-specific pointers
     */

    init_arch_irq = mdesc- > init_irq;
# ifdef CONFIG_VT
# if defined( CONFIG_VGA_CONSOLE)
    conswitchp = & vga_con;
# elif defined( CONFIG_DUMMY_CONSOLE)
    conswitchp = & dummy_con;
# endif
# endif
}
//------------------------------------------------------
arch/ arm/ vmlinux- armv. lds. in
__arch_info_begin = . ;
    * ( . arch. info)
__arch_info_end = . ;
//------------------------------------------------------
include / asm - arm/ mach/ Arch. h
# define MACHINE_START( _type, _name)                    /
const struct machine_desc __mach_desc_# # _type        /
 __attribute__( ( __section__( ".arch.info" ) ) ) = {       /
    . nr        = MACH_TYPE_# # _type,                   /
    . name        = _name,

# define MAINTAINER( n)

# define BOOT_MEM( _pram, _pio, _vio)                     /
    . phys_ram    = _pram,                             /
    . phys_io    = _pio,                               /
    . io_pg_offst    = ( ( _vio) > > 18) & 0xfffc,

# define BOOT_PARAMS( _params)                          /
    . param_offset    = _params,

# define VIDEO( _start, _end)                            /
    . video_start    = _start,                         /
    . video_end    = _end,

# define DISABLE_PARPORT( _n)                           /
    . reserve_lp# # _n    = 1,

# define BROKEN_HLT /* unused */

# define SOFT_REBOOT                                  /
    . soft_reboot    = 1,

# define FIXUP( _func)                                  /
    . fixup        = _func,

# define MAPIO( _func)                                  /
    . map_io        = _func,

# define INITIRQ( _func)                                /
    . init_irq    = _func,

# define MACHINE_END                                  /
} ;
//------------------------------------------------------
arch/ arm/ mach- at91rm9200/ Core. c
MACHINE_START( AT91RM9200, "ATMEL AT91RM9200" )
    MAINTAINER( "SAN People / ATMEL" )
    BOOT_MEM( AT91_SDRAM_BASE, AT91C_BASE_SYS, AT91C_VA_BASE_SYS)
    BOOT_PARAMS( AT91_SDRAM_BASE + 0x100)
    FIXUP( at91rm9200_fixup)
    MAPIO( at91rm9200_map_io)
    INITIRQ( at91rm9200_init_irq)
MACHINE_END
//------------------------------------------------------
arch/ arm/ mach- at91rm9200/ Core. c- > at91rm9200_fixup( )
将ramdisk设为根文件系统
static void __init at91rm9200_fixup( struct machine_desc * desc, struct param_struct * unused,
         char * * cmdline, struct meminfo * mi)
{
# ifdef CONFIG_BLK_DEV_INITRD
    ROOT_DEV = MKDEV( RAMDISK_MAJOR, 0) ;
    setup_ramdisk( 1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE) ;
//    setup_initrd(0xc0100000, 3*1024*1024);
# endif
}
2. uboot中
//------------------------------------------------------
u- boot的include/ asm - arm/ setup. h定义了struct tag结构体
u- boot的lib_arm/ armlinux. c- > do_bootm_linux( )
- > setup_start_tag( )
- > setup_serial_tag( )
- > setup_revision_tag( )
- > setup_memory_tags( )
- > setup_commandline_tag( )
- > setup_initrd_tag( )
- > setup_videolfb_tag( )
- > setup_end_tag( )
//------------------------------------------------------
其中u- boot的setup_start_tag会将bd- > bi_boot_params传给params
static void setup_start_tag ( bd_t * bd)
{
    params = ( struct tag * ) bd- > bi_boot_params;
    params- > hdr. tag = ATAG_CORE;
    params- > hdr. size = tag_size ( tag_core) ;
    params- > u. core. flags = 0;
    params- > u. core. pagesize = 0;
    params- > u. core. rootdev = 0;
    params = tag_next ( params) ;
}
在board/ at91rm9200dk/ at91rm9200dk. c- > board_init( ) 函数中定义了bd- > bi_boot_params的初始值gd- > bd- > bi_boot_params = PHYS_SDRAM + 0x100; 所以这就刚好和linux中arch/ arm/ mach- at91rm9200/ Core. c的BOOT_PARAMS( AT91_SDRAM_BASE + 0x100) 对应起来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值