zoukankan      html  css  js  c++  java
  • Bootloader 与 内核的交互

    以下内容源自于:韦东山老师的《嵌入式Linux应用开发 》

    目的:了解Bootloader与内核交互的原理

      由于Bootloader和内核交互是单向的,只能是B将参数传给内核,且不能同时运行,那传递参数方法就只有:Bootloader将参数放在某个约定的地方,再启动内核,内核启动后去这个地方获得参数。

      自然,二者还要规定标记参数的结构 --- tagged list --- 标记列表。通过标记列表来传递启动参数。标记的数据结构为 tag ,由一个tag_head结构和一个联合union组成。tag_head表示标记的类型和长度,比如是表示内存还是命令行参数等。对于不同类型的标记使用不同的union,如表示内存就用tag_mem32,表示命令行时使用tag_cmdline。

      在include/asm/setup.h

    struct tag_header {
            __u32 size;
            __u32 tag;
    };

      其中 size:表示整个tag 结构体的大小(用字的个数来表示,而不是字节的个数),等于tag_header 的大小加上u 联合体的大小,例如,参数结构体ATAG_CORE 的
    size=(sizeof(tag->tag_header)+sizeof(tag->u.core))>>2,一般通过函数 tag_size(struct * tag_xxx)来获得每个参数结构体的size。其中tag:表示整个tag 结构体的标记,如:ATAG_CORE等。

    struct tag {
            struct tag_header hdr;
            union {
                    struct tag_core         core;
                    struct tag_mem32        mem;
                    struct tag_videotext    videotext;
                    struct tag_ramdisk      ramdisk;
                    struct tag_initrd       initrd;
                    struct tag_serialnr     serialnr;
                    struct tag_revision     revision;
                    struct tag_videolfb     videolfb;
                    struct tag_cmdline      cmdline;
                    struct tag_acorn        acorn;
              struct tag_memclk memclk; } u; };

      联合体u 包括了所有可选择的内核参数类型

    下面通过设置内存标记、内存标记、命令行标记为例说明参数的传递。(详见韦书)

      (1)设置标记ATAG_CORE

      标记列表以ATAG_CORE开始,以ATAG_NONE 结束。这里的ATAG_CORE,ATAG_NONE 是各个参数的标记,本身是一个32 位值,例如:ATAG_CORE=0x54410001。

      假设Bootloader与内核约定的参数传递地址为0x30000100,则可以以如下代码设置标记ATAG_CORE:

    params = (struct tag *) 0x30000100;
    
    params->hdr.tag = ATAG_CORE;
    params->hdr.size = tag_size (tag_core);
    params->u.core.flags = 0;
    parama->u.core.pagesize = 0;
    params->u.core.rootdev =  0;
    
    params = tag_next (params);

      其中,tag_next指向当前标记末尾;

    #define tag_next(t) ((struct tag*)((u32*)(t)+(t)->hdr.size))

      (2)设置内存标记

    //假设开发板使用的内存起始地址0x30000000,大小为0x4000000
    params
    ->hdr.tag = ATAG_MEM; params->hdr.size = tag_size (tag_mem32); params->u.mem.start = 0x30000000; parama->u.mem.size = 0x4000000; params = tag_next (params);

      (3)设置命令行标记

    命令行即字符串,可控制内核行为,比如:

    " root=/dev/mtdblock 2     init=/linuxrc     console = tty SAC0 "

     表示根文件系统在MTD2分区上,系统启动后执行第一个程序为linuxrc,控制台为ttySAC0即第一个串口。

      命令行可以在BootLoader中通过命令标记设置好,然后按照以下构造传给内核:

    char *p = " root=/dev/mtdblock 2     init=/linuxrc     console = tty SAC0 "
    
    params->hdr.tag = ATAG_CMDLINE;
    params->hdr.size = ((sizeof(struct tag_header)+strlen(p) +1 +4 ) >> 2);
    
    strcpy (params->u.cmdline.cmdline, p);
    
    params = tag_next (params);
  • 相关阅读:
    【转贴】判断sql server表是否存在的方法
    SQL SERVER 中将重复记录合并为一条记录
    数据清洗:将字段值全部为数字的记录置空
    【转贴】PLSQL不安装客户端连接远程oracle
    Datalength() 与 Len()的区别
    SQL SERVER 查询重复的记录的方法
    连接mysql利用jsp实现简单的登陆操作
    jsp包含文件的两种方法
    preparedStatment的用法
    request内置对象介绍和使用
  • 原文地址:https://www.cnblogs.com/y4247464/p/12339982.html
Copyright © 2011-2022 走看看