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. hbuilder 打包 vueAPP

    1:设置状态栏颜色 在manifest.json 找到 plus 下添加 "statusbar": { "immersed": true/*沉浸式状态栏*/ 设 ...

  2. Charles篡改后台数据

    1.打开Charles找到相对应的接口 2.在接口上右键选择Breakpoints打断点. 3.重新请求截断接口,Charles会多弹出一个截断窗口如下图(第一个修改请求的,第二图是修改返回的) 点击 ...

  3. 第三篇 Flask 中的 request

    第三篇 Flask 中的 request   每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前 ...

  4. docker简单搭建gitlab

    docker启动非常简单: docker run --detach --hostname 192.168.0.33 --publish 443:443 --publish 80:80 \ --publ ...

  5. Mybateis mapper 接口 example 用法

    注意:希望通过此篇文章分享 可以使大家对mapper接口以及example 用法更加深入理解 MyBatis的Mapper接口以及Example的实例函数及详解 一.mapper接口中的方法解析 ma ...

  6. HTTP协议转码

    为什么要有转义的功能? 一些特殊字符需要转义,才能被访问,否则变为空格 UrlEnCode与UrlDeCode 有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的 ...

  7. android一个app打开另一个app的指定页面

    一个app打开另一个app的指定页面方法 有以下几种 1.通过包名.类名 2.通过intent的 action 3.通过Url 方案1. ComponentName componentName = n ...

  8. vue自定义滚动条

    参照element-ui的el-scroll自己实现了一个自定义组件,代码如下: <template> <div class="c-scroll-box" ref ...

  9. boost asio死锁一例

    socket close -> sendmessage -> io_service stop 先关闭socket句柄,再给windows窗口发送消息,然后io_service停止. 当se ...

  10. Curl测试socks5 or http 代理命令

    测试socks5命令:curl --socks5 125.119.175.48:8909 http://example.com/ 测试http命令: curl --connect-timeout 2 ...