uboot代码2:stage2代码,启动内核
一、uboot最终目的:
1.读出内核 do_nand read kernel
{
flash上存的内核:uImage = 头部 + 真正的内核;
}
2.启动内核。 do_bootm_linux
{
(1)设置启动参数; uboot到kernel的启动参数的传递, 靠的就是告诉kernel参数存放的绝对地址,并按照约定好的格式存放。具体的格式约定比较复杂,见uboot
(2)跳到入口地址.
}
二、在uboot里,打印一下环境变量,下面两句是启动kernel的关键字:
bootcmd=nand read 0x30000000 0x60000 0x200000;bootm 0x30000000
bootargs=noinitrd root=/dev/nfs nfsroot=192.168.2.109:/home/fs/work/nfs_root/fs_mini_mdev ip=192.168.2.111:192.168.2.109:192.168.2.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
三、分析uboot代码,看它是如何实现上述功能的:
写的比较抽象,仅供个人理解。
//uImage头部
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address 加载地址, 要运行内核时, 先把内核放在哪里*/
uint32_t ih_ep; /* Entry Point Address 要运行内核时,直接跳到这个地址就可以了*/
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t; //uboot和kernel传递参数所依赖的结构体,详细内容见 include/asm-arm/setup.h
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;
};
//cmd_nand.c
//bootcmd-- nand read 0x30000000 0x60000 0x200000
int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
nand_read_opts(nand, &opts); // nand_read_opts : drivers/nand/nand_util.c
} //cmd_bootm.c
//bootcmd-- bootm 0x30000000
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
addr = simple_strtoul(argv[], NULL, );
//printf ("## Booting image at %08lx ...\n", addr);
memmove (&header, (char *)addr, sizeof(image_header_t));
//puts (" Verifying Checksum ... "); //unsigned long int data = start addr of kernel int the sdram after the cmd of nand read;
if(ntohl(hdr->ih_load) == data) //如果期望的kernel运行地址 = 实际从nand 读入内存的kernel起始地址。(都不含头)
{// 不需要移动
printf (" XIP %s ... ", name);
}
else
{// 需要移动
//printf (" Loading %s ... ", name);
len = ntohl(hdr->ih_size);
memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
} do_bootm_linux (cmdtp, flag, argc, argv,
addr, len_ptr, verify)
{
void (*theKernel)(int zero, int arch, uint params);
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep); setup_start_tag (bd)/设置内核启动参数的其实存放地址bi_boot_params
{
bd_t *bd = gd->bd; //gd->bd->bi_boot_params = 0x30000100;
}
//这之后从bi_boot_params开始,依次存入各启动参数
setup_memory_tags (bd);
setup_commandline_tag (bd, commandline);// char *commandline = getenv ("bootargs");
setup_end_tag (bd);//表示完成启动参数的传递。 theKernel (, bd->bi_arch_number, bd->bi_boot_params);//跳到入口地址
}
} //uboot的核心:通过run_command实现各种功能
void main_loop (void)
{
getenv ("bootdelay"); //uboot如何启动内核:
s = getenv ("bootcmd");
printf("Booting Linux ...\n");
run_command (s, )
{
(cmdtp->cmd) (cmdtp, flag, argc, argv);
} //uboot如何接受用户命令:
for (;;)
{
readline (CFG_PROMPT); //read input into console_buffer
strcpy (lastcommand, console_buffer);
run_command (lastcommand, flag);
} }
uboot代码2:stage2代码,启动内核的更多相关文章
- 嵌入式Linux驱动学习之路(六)u-boot启动内核
内核启动是需要必要的启动参数.不能开机自动完全从0开始启动,需要uboot帮助内核实现重定位并提供参数. 首先,uboo会从Kernel分区中读取bootcmd环境变量,根据环境变量可自动启动. 分区 ...
- 第2阶段——编写uboot之启动内核和制作Makefile(2)
目标: 1 添加头文件setup.h和serial.h 2 写main函数 2.1 帮内核设置串口0, (内核启动会打印出启动信息) 2.2把内核读入到SDRAM 2.3设置参数(参考u- ...
- MPC8313ERDB在Linux从NAND FLASH读取UBoot环境变量的代码分析
MPC8313ERDB在Linux从NAND FLASH读取UBoot环境变量的代码分析 Yao.GUET@2014-05-19 一.故事起因 由于文件系统的增大,已经大大的超出了8MB的NOR FL ...
- uboot启动内核的实现
前面我们分析了uboot 的整个流程,我们知道uboot启动以后所有功能都是通过命令来实现的,启动kernel就是执行了bootcmd里面的命令.命令执行过程在uboot中是非常重要的现在我们就来看u ...
- UBOOT启动内核过程
1.摘要 (1).启动4步骤第一步:将内核搬移到DDR中第二步:校验内核格式.CRC等第三步:准备传参第四步:跳转执行内核(2).涉及到的主要函数是:do_bootm和do_bootm_linux(3 ...
- u-boot学习(五):u-boot启动内核
u-boot的目的是启动内核.内核位于Flash中,那么u-boot就要将内核转移到内存中.然后执行命令执行之.这些操作是由bootcmd命令完毕的. bootcmd=nand read.jffs2 ...
- U-boot 启动内核
1:什么是UBOOT,为什么要有UBOOT? UBOOT的主要作用是用来启动linux内核,因为CPU不能直接从块设备中执行代码,需要把块设备中的程序复制到内存中,而复制之前还需要进行很多初始化工作, ...
- linux的几个内核镜像格式Image 和 u-boot启动内核和文件系统时的一些环境变量的设置
关于编译powerpc linux的几个Image参考原文 http://blog.sina.com.cn/s/blog_86a30b0c0100wfzt.html 转载▼ PowerPC架构 L ...
- 嵌入式linux开发uboot启动内核的机制(二)
一.嵌入式系统的分区 嵌入式系统部署在Flash设备上时,对于不同SoC和Flash设备,bootloader.kernel.rootfs的分区是不同的.三星S5PV210规定启动设备的分区方案如下: ...
随机推荐
- Kali Rolling在虚拟机安装后的设置
Kali Linux在2016年的第一个发行版——Kali Rolling是Debian的即时更新版,只要Debian中有更新,更新包就会放入Kali Rolling中,供用户下载使用.它为用户提供了 ...
- Python网络编程——处理套接字错误
在网络应用中,经常会遇到这种情况:一方尝试连接,但另一方由于网络媒介失效或者其他原因无法响应. Python的Socket库提供了一个方法,能通过socket.error异常优雅地处理套接字错误. 1 ...
- Regex阅读笔记(一)之入门
在检查一行文本时,^代表一行的开始,$代表结束. 字符数组:[],在里面列举任意多个字符,可以匹配其中任意一个字符,字符组元字符'-'表示一个范围. ^$表示一个空行(没有任何字符,包括空白字符) [ ...
- 基于visual Studio2013解决C语言竞赛题之0304整除数
题目 解决代码及点评 按照题目要求,判断数值对3和5取模的结果,是否为0 #include <stdio.h> #include <stdlib.h> void m ...
- Apache JMeter - load test tool
What is it? ->>>> http://jmeter.apache.org/index.html (Please read!) Where to get it? - ...
- HDU 1069 monkey an banana DP LIS
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64uDescription 一组研究人员正在 ...
- Linux DM9000网卡驱动程序完全分析
Linux DM9000网卡驱动程序完全分析http://blog.csdn.net/ypoflyer/article/details/6209922
- VMware-WorkStation 去掉VM工具栏
链接地址:http://jingyan.baidu.com/article/8275fc86b95c6246a03cf629.html VMware 是目前用得最多的虚拟机.当开启虚拟机的全屏模式时, ...
- IOS某个ViewController禁止自动旋转
IOS屏幕自动旋转,强制横竖屏方法: - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientat ...
- ajax请求响应中用window.open打开新窗口会被浏览器拦截的解决方式
一.问题描述 ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是会被浏览器给拦截了,需要用户点下. 二.问题分析 浏览器之所以拦截新开窗口是因为该操作并 ...