Linux内核启动时需要一些配置信息,如根文件系统的类型、flash分区情况、串口终端的编号、内存的使用情况等等,而由于U-Boot和Linux Kernel的镜像是独立的两个文件,所以只能两者约定好在内存的什么地方存放启动参数,这样U-Boot在启动引导时就将启动参数放置在相应的地址处,而Linux Kernel则去相应的地址读取,然后加以处理。

  对于Tiny210开发板,启动参数放置在DDR2 SDRAM起始地址后的0x100偏移处,U-Boot中board/samsung/goni/goni.c中有如下代码:

 int board_init(void)
{
/* Set Initial global variables */
s5pc110_gpio = (struct s5pc110_gpio *)S5PC110_GPIO_BASE; gd->bd->bi_arch_number = MACH_TYPE_GONI;
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; return ;
}

  PHYS_SDRAM_1在include/configs/s5p_goni.h中就被定义为DDR2 SDRAM的起始地址。

  而在内核中,arch/arm/mach-s5pv210/mach-mini210.c中也有相关的定义,两者的地址是一样的。

  那么参数应该如何在内存中组织呢?对于内核来说,它应该知道参数是从哪开始,从哪结束,这一点的解决方法是,第一个参数和最后一个参数都约定好形式,下面有说明。

  先看几个用到的数据结构。

 struct tag_header {
u32 size;
u32 tag;
}; 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; /*
* Acorn specific
*/
struct tag_acorn acorn; /*
* DC21285 specific
*/
struct tag_memclk memclk;
} u;
}; struct tag *params;

  在启动内核的函数中,全局变量被初始化为:

  params = ( struct tag *)bd->bi_boot_params;

  对U-Boot来说,只要牵住params这个变量,不断向后面写参数就行了,下面简单分析几个参数的填写过程。

  第一个参数必须是TAG_CORE
  

 设置ATAG_CORE的伪代码
params->hdr.tag = ATAG_CORE;
params->hdr.size = ( sizeof ( struct tag_header ) + sizeof( struct tag_core ) ) >> ;
params->u.core.flags = ;
params->u.core.pagesize = ;
params->u.core.rootdev = ;
params = params + params->hdr.size;

  重要的参数CMDLING_TAG

 设置ATAG_CMDLINE的伪代码
params->hdr.tag = ATAG_CMDLINE;
params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_cmdline ) ) >> ;
p = getenv( "bootargs" );
check_bootargs_not_null( p ) && bootargs_valid( p );
strcpy( params->u.cmdline.cmdline, p );
params = params + params->hdr.size;

  重要参数CONFIG_SETUP_MEMORY_TAGS

 for( i = ; i < CONFIG_NR_DRAM_BANKS; i++ )    //tiny210中此宏为1
{
params->hdr.tag = ATAG.MEM;
params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_mem32 ) ) >> ;
params->u.mem.start = bd->bi_dram.start;
params->u.mem.size = bd->bi_dram.size;
params = params + params->hdr.size; }

  可选参数CONFIG_REVISION_TAG

 params->hdr.tag = ATAG_REVISION;
params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_revision ) ) >> ;
revision = board_get_revision();
params->u.revision.rev = revision;
params = params + params->hdr.size;

  可选参数SERIAL_TAG

 params->hdr.tag = ATAG_SERIAL;
params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_serial ) ) >> ;
serialnr = board_get_serialnr();
params->u.serialnr.low = serialnr.low;
params->u.serialnr.high = serialnr.high
params = params + params->hdr.size;

  INITRD_TAG,所谓initrd 就是init ramdisk

 if( images->rd_start && images->rd_end )

setup_initrd_tag( gd->bd, images->rd_start, images->rd_end );
虽然s5p_goni.h中使用了宏定义,但是没有使用。
params->hdr.tag = ATAG_INITRD2; ATAG_INITRD是压缩的ramdisk image所在 的虚拟地址,ATAG_INITRD2是相应的物理地址。
params->hdr.size = ( sizeof( struct tag_header ) + sizeof( struct tag_initrd ) ) >> ;
params->u.initrd.start = initrd_start;
params->u.initrd.size = initrd_end - initrd_start;
params += params->hdr.size;

对应于开始的ATAG_CORE,最后一个也需要固定格式的tag:

 params->hdr.tag = ATAG_NONE;
params->hdr.size = ;

U-Boot bootargs简析的更多相关文章

  1. [Spring] 学习Spring Boot之一:基本使用及简析

    一.简介 使用 Spring Boot 目的主要是用来简化 Spring 应用的搭建及开发过程,因为使用 Spring 及 SpringMVC 框架时需要手动配置的地方非常多(各种包之间的依赖.各种配 ...

  2. Android 启动过程简析

    首先我们先来看android构架图: android系统是构建在linux系统上面的. 所以android设备启动经历3个过程. Boot Loader,Linux Kernel & Andr ...

  3. Linux 目录结构学习与简析 Part2

    linux目录结构学习与简析 by:授客 QQ:1033553122 ---------------接Part 1-------------- #1.查看CPU信息 #cat /proc/cpuinf ...

  4. Linux 磁盘分区方案简析

    Linux 磁盘分区方案简析 by:授客 QQ:1033553122   磁盘分区 任何硬盘在使用前都要进行分区.硬盘的分区有两种类型:主分区和扩展分区.一个硬盘上最多只能有4个主分区,其中一个主分区 ...

  5. Linux目录结构简析

    Linux目录结构简析 Linux继承了unix操作系统结构清晰的特点.在linux下的文件结构非常有条理.但是,上述的优点只有在对linux相当熟悉时,才能体会到.现在,虫虫就把linux下的目录结 ...

  6. Spring系列.@EnableRedisHttpSession原理简析

    在集群系统中,经常会需要将Session进行共享.不然会出现这样一个问题:用户在系统A上登陆以后,假如后续的一些操作被负载均衡到系统B上面,系统B发现本机上没有这个用户的Session,会强制让用户重 ...

  7. 简析.NET Core 以及与 .NET Framework的关系

    简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...

  8. 简析 .NET Core 构成体系

    简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...

  9. RecycleView + CardView 控件简析

    今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...

随机推荐

  1. EOS源码

    [EOS源码] 1.在 libraries/chain/include/eosio/chain/ 目录下. permission_level 定义如下:   account_name.permissi ...

  2. mongo中用嵌套结构优势是什么

    首先需要知道,MongoDB是NoSQL中的一种,是不直接支持Join的,这是NoSQL的一个特点,不需要直接支持Join,可以将横向扩展以及性能做到更好. 但是这不等于说MongoDB不能做Join ...

  3. 大数据实操2 - hadoop集群访问——Hadoop客户端访问、Java API访问

    上一篇中介绍了hadoop集群搭建方式,本文介绍集群的访问.集群的访问方式有两种:hadoop客户端访问,Java API访问. 一.集群客户端访问 Hadoop采用C/S架构,可以通过客户端对集群进 ...

  4. go语言变量

    变量可以通过变量名访问 Go 语言变量名由字母.数字.下划线组成,其中首个字符不能为数字 声明变量的一般形式是使用 var 关键字: var identifier type 变量声明 1. 指定变量类 ...

  5. vue使用qrcode插件生成二维码

    参考:https://www.jianshu.com/p/d3883e020d99 步骤: 第一步:vue-cli下载插件 cnpm install --save qrcodejs2 第二步:组件中引 ...

  6. springboot添加自定义注解

    spring拦截器是基于动态代理,注解就是拦截器,所以关于动态代理需要注意的坑,注解同样要注意. 1.创建注解类 /** * @Target 此注解的作用目标,括号里METHOD的意思说明此注解只能加 ...

  7. pythone函数基础(15)接口开发初识

    导入需要的第三方模块 import flaskimport toolsimport json,redisimport random server = flask.Flask(__name__)#新建一 ...

  8. 第一个spring简单的helloworld

    spring 是一个开源的框架 也是轻量级框架 1.导入jar包 spring的版本 4.0 目录: spring-framework-4.0.0.RELEASE-libs 下的jar  spring ...

  9. Eclipse常用快捷键--摘录他人

    Eclipse常用快捷键 1几个最重要的快捷键 代码助手:Ctrl+Space(简体中文操作系统是Alt+/) 快速修正:Ctrl+1 单词补全:Alt+/ 打开外部Java文档:Shift+F2显示 ...

  10. touch.js 手机端的操作手势

    使用原生的touchstart总是单击.长按有冒泡冲突事件,发现百度在几年开源的touch.js库,放在现在来解决手机端的操作手势,仍然很好用.