娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

Linux移植之tag參數列表解析過程分析

發布者:SerendipityRose最新更新時間:2024-08-26 來源: cnblogs關鍵字:Linux移植  tag 手機看文章 掃描二維碼
隨時隨地手機看文章

在Linux移植之內核啟動過程start_kernel函數簡析中已經指出了start_kernel函數的調用層次,這篇主要是對具體的tag參數列表進行解析。


1、內存參數ATAG_MEM參數解析


2、命令行參數ATAG_CMDLINE解析,以傳入的命令參數bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0為列:


  1)、noinitrd參數解析過程,當你沒有使用ramdisk啟動系統的時候,你需要使用noinitrd這個參數,但是如果使用了的話,就需要指定initrd=r_addr,size, r_addr表示initrd在內存中的位置,size表示initrd的大小。


  2)、root=/dev/mtdblock3參數解析過程


  3)、init=/linuxrc參數解析過程


  4)、 console=ttySAC0參數解析過程


start_kernel

    setup_arch                  //解析UBOOT傳入的啟動參數

    setup_command_line //解析UBOOT傳入的啟動參數

    do_early_param         //解析early參數,uboot中沒傳這個參數

    unknown_bootoption//解析到了命令行參數,saved_root_name在這塊初始化

    console_init();//控制臺初始化

    rest_init

        kernel_thread

            kernel_init

                prepare_namespace   //解析命令行參數解析成功掛接在哪個分區

                    mount_root//掛接根文件系統

                init_post

                    //執行應用程序


1、內存參數ATAG_MEM參數解析


看到archarmkernelSetup.c文件,在setup_arch函數里看到如下幾行,首先根據內核啟動時第一階段得到的machine_arch_type,取得mdesc結構體,這個結構體在Linux移植之內核啟動過程引導階段分析已經介紹過,這里主要關心的是boot_params參數,里面存放的是tag參數列表的存放地址,然后將取得的物理地址轉換為虛擬地址供后面使用tag。


776    console_init();//控制臺初始化

777    archarmkernelSetup.c

778

779    setup_processor();//設置處理器相關的一些設置

780    mdesc = setup_machine(machine_arch_type);//獲得開發板的machine_desc結構

781    machine_name = mdesc->name;//取得開發板的名稱

782

783    if (mdesc->soft_reboot)

784        reboot_setup('s');

785

786    if (mdesc->boot_params)//確定uboot傳入的啟動參數的地址

787        tags = phys_to_virt(mdesc->boot_params);//將啟動參數的物理地址轉換為虛擬地址


setup_arch函數繼續往下看


109    static struct meminfo meminfo __initdata = { 0, };


798    if (tags->hdr.tag == ATAG_CORE) {//ATAG_CORE為tag標記列表的開始

799        if (meminfo.nr_banks != 0)//如果已經在內核中定義了meminfo結構

780            squash_mem_tags(tags);//則忽略內存tag

781        parse_tags(tags);//解釋每個tag

782    }


其中meminfo就是處理完ATAG_MEN參數后,將里面的內容放去meninfo中,它的結構定義在includeasm-armSetup.h 中


207    struct meminfo {

208        int nr_banks;

209        struct membank bank[NR_BANKS];

210    };

接著繼續看parse_tags函數,它也位于archarmkernelSetup.c中



733    static void __init parse_tags(const struct tag *t)

734    {

735        for (; t->hdr.size; t = tag_next(t))//循環取出tag列表,然后處理

736            if (!parse_tag(t))                //處理取出的tag列表

737                printk(KERN_WARNING

738                    'Ignoring unrecognised tag 0x%08xn',

739                    t->hdr.tag);

740    }


接著分析parse_tag函數,它同樣位于archarmkernelSetup.c中


715    static int __init parse_tag(const struct tag *tag)

716    {

717        extern struct tagtable __tagtable_begin, __tagtable_end;

718        struct tagtable *t;

719

720        for (t = &__tagtable_begin; t < &__tagtable_end; t++)//從.taglist.init段找出符合的處理tag列表的結構

721            if (tag->hdr.tag == t->tag) {//找到符合的tag

722                t->parse(tag);//調用相應的處理tag的函數處理

723                break;

724            }

725    

726        return t < &__tagtable_end;//t<&__tagtable_end說明找到了tag

727    }


parse_tag會從.taglist.init段找出符合的tag,然后調用相應的處理函數處理。tagtable 的結構如下,它位于includeasm-armSetup.h 中


171    struct tagtable {

172        __u32 tag;//處理的tag值

173        int (*parse)(const struct tag *);//處理函數

174    };

我們需要的是處理ATAG_MEN參數的函數,搜搜ATAG_MEN,在archarmkernelSetup.c中找到了parse_tag_mem32處理ATAG_MEN參數的函數。它的功能就是取出內存的開始地址與大小信息后存放在meminfo結構中


614    static int __init parse_tag_mem32(const struct tag *tag)

615    {

616        if (meminfo.nr_banks >= NR_BANKS) {

617            printk(KERN_WARNING

618                   'Ignoring memory bank 0x%08x size %dKBn',

619                tag->u.mem.start, tag->u.mem.size / 1024);

620            return -EINVAL;

621        }

622        arm_add_memory(tag->u.mem.start, tag->u.mem.size);//取出內存的開始地址與大小信息后存放在meminfo結構中

623        return 0;

624    }

625

626    __tagtable(ATAG_MEM, parse_tag_mem32);//解析ATAG_MEM列表,函數為parse_tag_mem32


再看到__tagtable,同樣位于includeasm-armSetup.h中。主要就是將tagtable 這個結構體放在.taglist.init段


188    #define __tag __used __attribute__((__section__('.taglist.init')))

189    #define __tagtable(tag, fn)

190    static struct tagtable __tagtable_##fn __tag = { tag, fn }

到這里就分析完了tag列表中ATAG_MEM參數的處理,接下去分析ATAG_CMDLINE參數的處理。


2、命令行參數ATAG_CMDLINE解析


找到與ATAG_CMDLINE參數的過程與前面ATAG_MEM參數一樣的流程就不分析了,直接找到處理ATAG_CMDLINE參數的函數,它位于archarmkernelSetup.c中。它只是簡單的將tag->u.cmdline.cmdline的內容復制到default_command_line中。


702    static int __init parse_tag_cmdline(const struct tag *tag)

703    {

704        strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);//簡單的將tag的內容復制到字符串default_command_line中

705        return 0;

706    }

707

708    __tagtable(ATAG_CMDLINE, parse_tag_cmdline);


接著看到default_command_line,它定義在archarmkernelSetup.c中,它的大小為1024字節


114    static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;

它初始化為CONFIG_CMDLINE,位于includelinuxAutoconf.h中


374    #define CONFIG_CMDLINE 'root=/dev/hda1 ro init=/bin/bash console=ttySAC0'

所以拷貝之后


default_command_line[] = 'noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0'

繼續往下看default_command_line,在archarmkernelSetup.c下的setup_arch函數中:其中parse_cmdline是對位于.early_param.init段的內容進行前期的初始化。相應的命令有:cachepolicy=、nocache、nowb、ecc=、initrd=、mem=等等,我們的參數沒有涉及到這類命令,所以不去細細的分析這個函數了。


809    memcpy(boot_command_line, from, COMMAND_LINE_SIZE);//form指向default_command_line,將default_command_line中的內容拷貝到boot_command_line中

810    boot_command_line[COMMAND_LINE_SIZE-1] = '

主站蜘蛛池模板: 德格县| 喀喇| 板桥市| 岳池县| 香河县| 和田市| 崇明县| 海南省| 望江县| 许昌县| 潼南县| 蒲城县| 河间市| 莱阳市| 周口市| 潮安县| 雅安市| 武汉市| 利川市| 翁源县| 成都市| 关岭| 行唐县| 家居| 山西省| 恭城| 和硕县| 那曲县| 遵义市| 大足县| 颍上县| 绥芬河市| 伽师县| 鹤山市| 建平县| 云林县| 屏山县| 景德镇市| 通河县| 隆德县| 通海县|