Bootloader与内核的交互
Bootloader与内核的交互是单向的,Bootloader将各类参数传给内核。由于它们不能同时运行,传递办法只有一个:Bootloader将参数放在某个约定的地方之后,再启动内核,内核启动后从这个地方获得参数。
除了约定好参数存放的地址外,还要规定参数的结构。Linux 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。标记,就是一种数据结构;标记列表,就是挨着存放的多个标记。标记列表以标记ATAG_CORE 开始,以标记ATAG_NONE 结束。标记的数据结构为tag,它由一个tag_header结构和一个联合(union)组成。tag_header结构表示标记的类型及长度,比如是表示内存还是表示命令行参数等。对于不同类型的标记使用不同的联合(union),比如表示内存时使用tag_mem32,表示命令行时使用
tag_cmdline。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中:
struct tag_header {
u32 size;
u32 tag;
};
<br>struct tag {
struct tag_header hdr;
union {
struct tag_corecore;
struct tag_mem32mem;
struct tag_videotextvideotext;
struct tag_ramdiskramdisk;
struct tag_initrdinitrd;
struct tag_serialnrserialnr;
struct tag_revisionrevision;
struct tag_videolfbvideolfb;
struct tag_cmdlinecmdline;
<br>/*
* Acorn specific
*/
struct tag_acornacorn;
<br>/*
* DC21285 specific
*/
struct tag_memclkmemclk;
} u;
};
下面以设置内存标记、命令行标记为例说明参数的传递:
(1)设置标记 ATAG_CORE。
标记列表以标记 ATAG_CORE开始,假设Bootloader与内核约定的参数存放地址为0x30000100,则可以以如下代码设置标记 ATAG_CORE:
params = (struct tag *) 0x30000100;
<br>params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
<br>params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
<br>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;
params->u.mem.size = 0x4000000;
params = tag_next (params);
(3)设置命令行标记。
命令行就是一个字符串,它被用来控制内核的一些行为。比如"root=/dev/mtdblock2 init="/linuxrc" console="ttySAC0""表示根文件系统在MTD2分区上,系统启动后执行的第一个程序为/linuxrc,控制台为ttySAC0(即第一个串口)。
命令行可以在Bootloader中通过命令设置好,然后如下构造标记传给内核:
char *p = "root=/dev/mtdblock2 init="/linuxrc" console="ttySAC0"";
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);
(4)设置标记ATAG_NONE。
标记列表以标记ATAG_NONE结束,如下设置:
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
除了约定好参数存放的地址外,还要规定参数的结构。Linux 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。标记,就是一种数据结构;标记列表,就是挨着存放的多个标记。标记列表以标记ATAG_CORE 开始,以标记ATAG_NONE 结束。标记的数据结构为tag,它由一个tag_header结构和一个联合(union)组成。tag_header结构表示标记的类型及长度,比如是表示内存还是表示命令行参数等。对于不同类型的标记使用不同的联合(union),比如表示内存时使用tag_mem32,表示命令行时使用
tag_cmdline。数据结构tag和tag_header定义在Linux内核源码的include/asm/setup.h头文件中:
struct tag_header {
u32 size;
u32 tag;
};
<br>struct tag {
struct tag_header hdr;
union {
struct tag_corecore;
struct tag_mem32mem;
struct tag_videotextvideotext;
struct tag_ramdiskramdisk;
struct tag_initrdinitrd;
struct tag_serialnrserialnr;
struct tag_revisionrevision;
struct tag_videolfbvideolfb;
struct tag_cmdlinecmdline;
<br>/*
* Acorn specific
*/
struct tag_acornacorn;
<br>/*
* DC21285 specific
*/
struct tag_memclkmemclk;
} u;
};
下面以设置内存标记、命令行标记为例说明参数的传递:
(1)设置标记 ATAG_CORE。
标记列表以标记 ATAG_CORE开始,假设Bootloader与内核约定的参数存放地址为0x30000100,则可以以如下代码设置标记 ATAG_CORE:
params = (struct tag *) 0x30000100;
<br>params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
<br>params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
<br>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;
params->u.mem.size = 0x4000000;
params = tag_next (params);
(3)设置命令行标记。
命令行就是一个字符串,它被用来控制内核的一些行为。比如"root=/dev/mtdblock2 init="/linuxrc" console="ttySAC0""表示根文件系统在MTD2分区上,系统启动后执行的第一个程序为/linuxrc,控制台为ttySAC0(即第一个串口)。
命令行可以在Bootloader中通过命令设置好,然后如下构造标记传给内核:
char *p = "root=/dev/mtdblock2 init="/linuxrc" console="ttySAC0"";
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);
(4)设置标记ATAG_NONE。
标记列表以标记ATAG_NONE结束,如下设置:
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
分享到:
相关推荐
u-boot启动后会运行液晶初始化程序并显示启动LOGO,但进入linux系统之后,又重新初始化一次,而且uboot与linux定义的显存地址也不一致,导致会有短暂的白屏闪烁。此补丁解决从uboot到linux启动完成一直保持LOGO不变...
uBoot和Linux的参数传递的关系 uBoot和Linux的参数传递的关系
Uboot命令和内核启动参数的设置方法 Uboot命令和内核启动参数的设置方法
arm linux启动资料,关于uboot等arm linux启动资料,关于uboot等arm linux启动资料,关于uboot等arm linux启动资料,关于uboot等arm linux启动资料,关于uboot等
正点原子Uboot和linux源码
这个资料有开发板修改后的uboot和linux、imx6ul芯片资料包、原理图。uboot和linux基于官方的开发进行针对性修改。
imx6 从uboot到linux logo显示不间断 补丁,解决闪屏问题
nxp源码(官方原版uboot以及linux源码)
NXP官方原版Uboot和Linux源码
详细描述,Uboot是如何启动Linux内核,难得的好资源,大家可以参考参考有帮助的。
uboot启动参数,包含了很多的启动和加载内核的方式及各种常用的指令使用方式,包含了nandflash、usb、spi启动及操作,还有nfs、ramdisk、jffs2的启动参数配置。非常适合嵌入式开发参考
uboot的启动参数介绍, bootcmd 和bootargs,可以参考参考,非常有用的。
介绍了如何实现在线升级linux系统,即uboot,kernel,rootfs, 以及相关的前提知识和准备工作 目录 1. 正文之前 3 1.1. 此文目的 3 1.2. 一点说明 3 2. 嵌入式系统中,如何在Linux运行的时候去升级Linux系统 4 2.1. ...
这是华清远见嵌入式开发 关于uboot移植和linux内核移植的实验手册 具有很高的参考价值 是自学的很好的资料(这是内部资料哦)
Linux uboot 自引导内核 Linux uboot 自引导内核 Linux uboot 自引导内核
uboot,只支持nand启动,其他功能还未实现
uboot和Linux内核移植
uboot 2410 nand 启动代码.uboot 2410 nand 启动代码.uboot 2410 nand 启动代码.uboot 2410 nand 启动代码.uboot 2410 nand 启动代码.uboot 2410 nand 启动代码.uboot 2410 nand 启动代码.
uboot linux 很全的移植资料,网上真理的大家分享,希望大家多学习东西啊。
uboot和Linux