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. 使用rke快速安装K8s集群

    操作系统 centos 7.5 yum update -y yum install docker -y 关闭防火墙.selinux 下载rke helm https://github.com/helm ...

  2. VS2017 连接Linux

    喜欢测试各种工具. 注意选择 使用C++的Linux开发 ! 配置ssh连接 工具->选项 添加ssh连接. 添加头文件 我的路径是:C:\Program Files (x86)\Microso ...

  3. 【Android端】【日志收集上报SDK相关内容测试的方案梳理总结】

    测试方案: 主要从几个方面关注,功能 性能 服务端策略(目前所有的这些上报收集等都会通过开关的精细化,通过接口方式将信息返回给APP端,APP端根据相关内容进行上报,因此基于此的上报机制及收集机制都需 ...

  4. 关于sqlserver使用in不报错问题

    最近使用CI处理接口时自己拼装了个函数,直接把数字implode(',',$arr)之后就放在了in中,发现一直返回空数据,以为数据库就是无匹配的,但是后面发现有对应的数据,多搬检测没发现问题,后面发 ...

  5. 分布式系统-主键唯一id,订单编号生成-雪花算法-SnowFlake

    分布式系统下 我们每台设备(分布式系统-独立的应用空间-或者docker环境) * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作 ...

  6. T4设计时模板调试

    在Visual Studio内调试T4设计时模板有多个方法:安装使用带调试功能的第三方工具,利用System.Diagnostics.Debugger实时调试器,VS内置的T4调试工具.使用第三方工具 ...

  7. AutoMapper 忽略某个字段

    以前要在定义中忽略 Mapper.CreateMap<Source, Destination>() .ForMember(dest => dest.SomeValuefff, opt ...

  8. 安装mysql后,sql语句中表名区分大小写的问题

    今天安装完mysql后,执行查询语句select * from user,结果报user表不存在,但是实际是存在的,查了一下才知道是因为mysql的my.cnf文件中少了一个大小写敏感的配置,若不配置 ...

  9. scrapy 爬取小说

    QiushuSpider # -*- coding: utf-8 -*- import scrapy import time from qiushu.items import QiushuItem c ...

  10. Oracle启动和停止

    概述 只有具备sysdba和sysoper系统特权的用户才能启动和关闭数据库. 在启动数据库之前应该启动监听程序,否则就不能利用命令方式来管理数据库,包括启动和关闭数据库. 虽然数据库正常运行,但如果 ...