u-boot向linux内核传递启动参数

U-BOOT 在启动内核时,会向内核传递一些参数.而这些参数是通过 structtag来传递的。 U-boot 把要传递给 kernel 的东西保存在 struct tag数据结构中,启动 kernel 时,把这个结构体的物理地址传给 kernelLinux kernel通过这个地址分析出u-boot传递的参数。
 
   例如u-boot-1.3.4在arm平台下,该函数的实现位于:lib_arm\Bootm.c文件中.
   在文件中有如下代码:(可以参照《完全手册》的244页)
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
    defined(CONFIG_CMDLINE_TAG) || \
    defined(CONFIG_INITRD_TAG) || \
    defined(CONFIG_SERIAL_TAG) || \
    defined(CONFIG_REVISION_TAG) || \
    defined(CONFIG_LCD) || \
    defined(CONFIG_VFD)
static void setup_start_tag (bd_t *bd)
{
    params =(struct tag *) bd->bi_boot_params;

   params->hdr.tag = ATAG_CORE;
   params->hdr.size = tag_size (tag_core);

   params->u.core.flags = 0;
   params->u.core.pagesize = 0;
   params->u.core.rootdev = 0;

    params =tag_next (params);
}
   上面是初始化tag链表(在SDRAM里),最后一句是作为链表的最关键部分,它的定义是:
#definetag_next(t)   ((struct tag *)((u32 *)(t) +(t)->hdr.size)) 作用是指向下一个tag结构体。
其中 defined (CONFIG_SETUP_MEMORY_TAGS) 和defined (CONFIG_CMDLINE_TAG)是必不可少的。前者是标记内存的信息,而后者是设置命令行标记(比如“root=/dev/mtdblock2init=/linuxrc console=ttySAC0”)
    /common/cmd_bootm.c文件中, bootm 命令对应的do_bootm函数,当分析 uImage 中信息发现 OS Linux 调用./lib_arm/bootm.c文件中的 do_bootm_linux函数来启动 Linuxkernel

       do_bootm_linux函数中:

voiddo_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char*argv[],

                 ulong addr, ulong *len_ptr, int verify)

{

......

#if defined(CONFIG_SETUP_MEMORY_TAGS) || \

   defined (CONFIG_CMDLINE_TAG) || \

   defined (CONFIG_INITRD_TAG) || \

   defined (CONFIG_SERIAL_TAG) || \

   defined (CONFIG_REVISION_TAG) || \

   defined (CONFIG_LCD) || \

   defined (CONFIG_VFD)

      setup_start_tag(bd);     // 初始化tag 结构体开始

#ifdefCONFIG_SERIAL_TAG

      setup_serial_tag(&params);

#endif

#ifdefCONFIG_REVISION_TAG

      setup_revision_tag(&params);

#endif

#ifdefCONFIG_SETUP_MEMORY_TAGS

      setup_memory_tags(bd);     // 设置 RAM 参数

#endif

#ifdefCONFIG_CMDLINE_TAG

      setup_commandline_tag (bd, commandline);

#endif

#ifdefCONFIG_INITRD_TAG

      if (initrd_start &&initrd_end)

             setup_initrd_tag (bd, initrd_start,initrd_end);

#endif

#if defined(CONFIG_VFD) || defined (CONFIG_LCD)

      setup_videolfb_tag ((gd_t *) gd);

#endif

      setup_end_tag(bd);             // 初始化tag 结构体结束

#endif

......

......

      theKernel (0, machid,bd->bi_boot_params);

// 传给 Kernel 的参数=(struct tag*) 型的 bd->bi_boot_params

当然,有很多的宏来选择是否传递相应的tag到linuxkenel.实际是这些所以针对于 bd->bi_boot_params这个变量.这个变量是个整形变量,代表存放所有tag的buffer的地址.
例如,在 smdk2410.c 中的 board_init() 函数中,对于这个变量进行了如下赋值:
   
   gd->bd->bi_boot_params = 0x30000100;
0x30000100这个值可以随意指定, 但是要保证和内核中相应的mach_type 一致.以smdk2410为例:
在内核中始终这个值的地方是: arch\arm\mach-s3c2410\mach-smdk2410.c的最后
MACHINE_START(SMDK2410, "SMDK2410")
   
   .phys_ram    =S3C2410_SDRAM_PA,
   .phys_io    =S3C2410_PA_UART,
   .io_pg_offst   = (((u32)S3C24XX_VA_UART) >> 18)& 0xfffc,
    .boot_params   = S3C2410_SDRAM_PA + 0x100,
   .map_io       =smdk2410_map_io,
   .init_irq    =smdk2410_init_irq,
   .timer       =&s3c24xx_timer,
MACHINE_END
红色部分的值, 必须等于0x30000100, 否者将会出现无法启动的问题.
内核启动后,会读取0x300000100位置的值, 当然,内核会把这个地址转换成逻辑地址在操作. 因为内核跑起来后,MMU已经工作,必须要把
0x300000100这个物理地址转成逻辑地址然后在操作.
对于u- boot传给内核的参数中(tag), 内核比较关系memory的信息,比如memory地址的起始,大小等.
如果没有得到,那么内核无法启 动,内核会进入BUG()函数,然后死在那里.
memory的信息是由
CONFIG_SETUP_MEMORY_TAGS宏决定的. 因此当这个宏没有被定义时,内核跑不起来. 初始化meminfo时会失败.现象就是: 
Starting Kernel ...
死掉.
一般需要定义:
#defineCONFIG_SETUP_MEMORY_TAGS
#defineCONFIG_CMDLINE_TAG

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

$_server['php_self'] 漏洞,Discuz! $_SERVER['PHP_SELF'] XSS Vulnerability

在common.inc.php文件的69行:$PHP_SELF $_SERVER[PHP_SELF] ? $_SERVER[PHP_SELF] : $_SERVER[SCRIPT_NAME];$SCRIPT_FILENAME str_replace(\\\\, /, (isset($_SERVER[PATH_TRANSLATED]) ? $_SERVER[PATH_TRANSLATED] : $_SERVER[SCRIPT_FILENAME]));$boardurl …

【前端破解系列之一】一分钟教你破解下载虾米音乐

虾米音乐网站上有很多高品质的音乐和精心组织的精选集,但普通用户只能试听,不能下载,下载的话需要使用“米”,这个“米”除了极少数的新手任务可以获得之外,基本上都要靠付费来购买,很多人没有网银或者没有…

网络编程常用接口的内核实现----sys_listen()

listen()函数仅在TCP服务器端调用,它做两个事情:将套接字转换到LISTEN状态和设置套接上的最大连接队列。listen()对应的内核实现为sys_listen(),下面开始对其实现作具体的分析。 一、sys_listen()函数 sys_listen()的源码实现及分析如下所示…

linux查看启动配置文件内容,Linux开机启动项的查看和设置方法总结

一、查看开机自启项1.Centos7自启项查看方式从Centos6的chkconfig改为:systemctl list-unit-files2.用grep过滤查看,比如:查看启动项:systemctl list-unit-files | grep enable查看sshd服务自启动情况:systemctl list-…

sql SET DATEFORMAT对日期处理的影响

--1./*--说明SET DATEFORMAT设置对使用CONVERT把字符型日期转换为日期的处理也具有影响但不影响明确指定了style的CONVERT处理。--*/--示例 ,在下面的示例中,第一个CONVERT转换未指定style,转换的结果受SET DATAFORMAT的影响,第二…

linux怎么设置tomcat自动启动,linux添加tomcat服务并设置开机启动

一,脚本文件,编辑好后放在/etc/rc.d/init.d/下面#!/bin/sh#chkconfig: 2345 10 90# description: Starts and Stops the Tomcat daemon.#by jj###############################################Startup script for Tomcat on Linux#filename tomcat.sh#M…

Linux操作系统内核启动参数详细解析

Linux内核在启动的时候,能接收某些命令行选项或启动时参数。当内核不能识别某些硬件进而不能设置硬件参数或者为了避免内核更改某些参数的值,可以通过这种方式手动将这些参数传递给内核。 如果不使用启动管理器,比如直接从BIOS或者把内核文…

XP Embedded:不同的用户使用不同的外壳程序

摘要: 能够使应用程序成为外壳程序是 Windows XP Embedded 的关键功能之一。设备可以在自定义外壳程序而不是 Explorer 外壳程序中启动,这提供了两个好处。第一个好处是系统能够更快地启动。Explorer 外壳程序需要花费大量的时间来加载所有支持库和文件…

linux系统中 库分为静态库和,Linux系统中“动态库”和“静态库”那点事儿-【经典好文】...

今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻。在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情。在linux操作系统中,普遍使用ELF格式作为可执行程序或者程序生成过程中的中间格式。ELF(Exec…

u-boot环境变量设置

这是我uboot的环境变量设置,在该设置下可以运行initram内核(从内存下载到nandflash再运行),但是运行nfs根文件系统的时候一直出错,各种错误。查看了很多资料后猜想应该是uboot传递给linux内核的参数有问题,…

RHEL6 下Cfengine V3 安装测试1

Cfengine 是一种 GNU 开源配置管理框架,用于计算机系统自动化。此框架是轻量的,可针对几乎所有平台构建。它能运行在所有常见平台上,其中包括 AIX、Linux、UNIX、Apple 和 Windows。 cf-promises 承诺的检验者和编译者,在试图执行…

linux下grpc安装编译,linux下安装grpc插件 (c++和go语言)

在debian/ubuntu系统下,需要做如下准备操作:$ [sudo] apt-getinstallbuild-essential autoconf libtoolpkg-config如果你想要从源码编译并且运行测试,同时运行下面的安装:$ [sudo] apt-getinstalllibgflags-dev libgtest-dev$ [su…

SIP资料汇总

SIP协议 SIP协议过程概念及分析 SIP入门开发之路(含SIP开发需要学习的资源及网址) SIP揭密(中文版) 使用Java的SIP Servlet进行SIP开发 Asterisk: Asterisk安装及测试 Asterisk十问十答 Asterisk入门教程 Asterisk介绍-Asterisk RealTime SIP asterisk配…

Nand Flash Yaffs系统大量写入数据失败问题的解决方法。

一个朋友的问题,我们共同分析后搞定。其实以前也遇到过同样问题,时间长了,没总结。 事发:在Nand Flash上使用2.6.14的linux kernel,三星2440的板子,连续写入文件,到一定大小限制就删除&#xff…

linux上的壁纸软件下载,Ubuntu 17.10上安装开源壁纸工具Wallch 4.0

在Ubuntu 17.04上安装WallchWallch是一款免费的开源通用壁纸更换器,用户可以在设置的时间更改桌面背景图片。它会在桌面上更改并显示随机图片或维基百科的当天图片。它还具有一个实时地球Living Earth壁纸,每30分钟更换桌面背景,以显示阳光和…

Asp.NET 获取网站根目录

http://www.cnblogs.com/Leo_wl/archive/2010/06/12/1757148.html转载于:https://www.cnblogs.com/imihiroblog/archive/2012/05/23/2514649.html

小议同步IO :fsync与fdatasync

对于提供事务支持的数据库,在事务提交时,都要确保事务日志(包含该事务所有的修改操作以及一个提交记录)完全写到硬盘上,才认定事务提交成功并返回给应用层。 一个简单的问题:在*nix操作系统上,怎…

linux c++ queue 多线程,C++多线程,消息队列用法

进程是没有活力的,它只是一个静态的概念。为了让进程完成一些工作,进程必须至少占有一个线程,所以线程是描述进程内的执行,正是线程负责执行包含在进程的地址空间中的代码。实际上,单个进程可以包含几个线程&#xff0…

获取磁盘类型

1. GetLogicalDriveStrings获取所以的分区字符串 2. GetDriveType("C:\\"); 对每个分区字符串分别调用GetDriveType获得分区所在磁盘的磁盘类型。 0 DRIVE_UNKNOWN未知的磁盘类型   1 DRIVE_NO_ROOT_DIR说明lpRootPathName是无效的   2 DRIVE_REM…

css3 (2)

Php1情景模拟:如果是在C盘,遇到熊猫,数据丢失。我们要重装系统,格C盘。我们要更改对应的访问的目录。需要改apache下面的配置文件Appserv 是集成环境包,里面也是apache服务器在运行网页请求。Apache目录下面有一个conf…