u-boot(三)启动文件
title: u-boot(三)启动文件
tags: linux
date: 2018-09-24 20:56:05
u-boot(三)启动文件
汇编
cpu/arm920t/start.S
u-boot也是一个牛逼的单片机程序,所以也就需要:
- 硬件相关初始化
- 看门狗
- 时钟
- sdram
- nand copy程序
- 设置sp
- 接下去就是读取内核,启动内核等
程序实际的步骤是:
1.set the cpu to SVC32 mode
2.turn off the watchdog
3.mask all IRQs
4.判断是不是从内部ram启动还是仿真直接烧写到链接地址,如果不在正确的加载地址的话,执行cpu_init_crit
cpu_init_crit执行SDRAM初始化
flush v4 I/D caches,
disable MMU stuff and caches,
lowlevel_init 这个会去初始化sdram,这个函数在lowlevel_init.S in your board directory
也就是board\100ask24x0\lowlevel_init.S
5.Set up the stack
6.clock_init board\100ask24x0\boot_init.c
7.relocate 自动识别当前是nor还是nand启动,nand启动时自动cp到内部ram中运行,所以可写
8.bss段清零
9.调用C函数 _start_armboot
堆栈设置如下
| 0x33F80000 | uboot程序 |
|---|---|
| ·=-CFG_MALLOC_LEN | malloc area |
| .=-CFG_GBL_DATA_SIZE | bdinfo |
| .=-CONFIG_STACKSIZE_IRQ | IRQ 的栈 |
| .=-CONFIG_STACKSIZE_FIQ | FRQ的栈 |
| .=-12 | leave 3 words for abort-stack |
| sp的初始位置 |
内存图:

C:_start_armboot
文件路径:lib_arm\board.c,这里就是u-boot执行C代码的地方了.
分配了一个gd的结构体内存
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); //在这里,_armboot_start=_start,根据链接脚本,这也就是代码段的起始=0x33F80000
//也就是指向了内存图128的地方了
init_sequence这里执行一些初始化
board_init中设置了gd->bd->bi_arch_number = MACH_TYPE_S3C2440;,设置了一个参数gd->bd->bi_boot_params = 0x30000100;这个就是启动内核参数的地址
flash/nand 初始化
堆栈初始化
环境变量的设置存储(一种是代码写死,一种在FLASH上保存)
进入主循环
main_loop
代码摘要
void start_armboot (void)
{
//-----
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
//-----
//函数指针,初始化设备
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
//---- flash初始化,识别
#ifndef CFG_NO_FLASH
/* configure available FLASH banks */
size = flash_init ();
display_flash_config (size);
#endif /* CFG_NO_FLASH */
////---- nand初始化
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
//------
//分配堆
/* armboot_start is defined in the board-specific linker script */
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
//-----
//uboot的环境变量
/* initialize environment */
env_relocate ();
//-----
//经过一系列的初始化
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();
}
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
#endif
dram_init, /* configure available RAM banks */
display_dram_config,
NULL,
};
int board_init (void)
{
---
/* support both of S3C2410 and S3C2440, by www.100ask.net */
if (isS3C2410)
{
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
}
else
{
/* arch number of SMDK2440-Board */
gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
}
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
}
C:main_loop
common/main.c
内核启动
这里实现了u-boot的倒计时,有打印命令,获取环境变量等,最关键的代码是
s = getenv ("bootcmd");
if(倒计时结束)
{
printf("Booting Linux ...\n");
run_command (s, 0);
}
实际的环境变量是bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0,读取内核,启动内核
菜单处理(自定义实现)
如果倒计时结束前输入了空格,进入命令模式run_command("menu", 0);
命令处理
- 死循环
- 读取串口输入
len = readline (CFG_PROMPT); - 执行命令
rc = run_command (lastcommand, flag);
u-boot(三)启动文件的更多相关文章
- 第三百三十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式
第三百三十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式 我们自定义一个main.py来作为启动文件 main.py #!/usr/bin/en ...
- 启动bash shell的三种方式下,检查的启动文件
启动bash shell的三种方式 1.登录时当做默认登录shell 2.作为非登录shell的交互式shell 3.作为运行脚本的非交互shell 一.登录shell 登录Linux系统时,bash ...
- Oracle启动中,spfile.ora、init<SID>.ora、spfile<SID>.ora 这三个文件正确的先后顺序是什么?
Oracle启动中,spfile.ora.init<SID>.ora.spfile<SID>.ora 这三个文件正确的先后顺序是什么? 解答:启动数据库,使用startup命令 ...
- Spring Boot(三):Spring Boot中的事件的使用 与Spring Boot启动流程(Event 事件 和 Listeners监听器)
前言:在讲述内容之前 希望大家对设计模式有所了解 即使你学会了本片的内容 也不知道什么时候去使用 或者为什么要这样去用 观察者模式: 观察者模式是一种对象行为模式.它定义对象间的一种一对多的依赖关系, ...
- spring boot容器启动详解
目录 一.前言 二.容器启动 三.总结 =======正文分割线====== 一.前言 spring cloud大行其道的当下,如果不了解基本原理那么是很纠结的(看见的都是约定大于配置,但是原理呢?为 ...
- 让Spring Boot项目启动时可以根据自定义配置决定初始化哪些Bean
让Spring Boot项目启动时可以根据自定义配置决定初始化哪些Bean 问题描述 实现思路 思路一 [不符合要求] 思路二[满足要求] 思路三[未试验] 问题描述 目前我工作环境下,后端主要的框架 ...
- 2.STM32启动文件
一.概念声明 中断向量:由硬件产生的中断标识码,一般用于存放中断服务程序的跳转指令.根据硬件产生的中断号查找中断向量表来确定对应的中断向量.CM3内核有15个异常 和240个中断源. 程序的内 ...
- Spring Boot(十七):使用Spring Boot上传文件
Spring Boot(十七):使用Spring Boot上传文件 环境:Spring Boot最新版本1.5.9.jdk使用1.8.tomcat8.0 一.pom包配置 <parent> ...
- Spring Boot 设置启动时banner
Spring Boot项目再启动的时候默认会在控制台输出一个字符banner图案,如下图: 我们可以通过下面的方法关闭启动时显示字符banner图案: 关闭banner方法一: public stat ...
随机推荐
- Git简介及安装
1 Git简介 Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理. Git是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码 ...
- Kibana-4.6.6 marvel插件license过期重新注册
1.注册新的license,https://register.elastic.co/marvel_register,注册完毕邮箱收取下载地址,将新的license下载到本地 2.到license所在目 ...
- HTML条件注释
前面的话 IE条件注释是微软从IE5开始就提供的一种非标准逻辑语句,作用是可以灵活的为不同IE版本浏览器导入不同html元素.很显然这种方法的最大好处就在于属于微软官方给出的兼容解决办法而且还能通过W ...
- P1200 你的飞碟在这儿
P1200 题目描述 众所周知,在每一个彗星后都有一只UFO.这些UFO时常来收集地球上的忠诚支持者.不幸的是,他们的飞碟每次出行都只能带上一组支持者. 因此,他们要用一种聪明的方案让这些小组提前知道 ...
- 【AtCoder - 2300】Snuke Line(树状数组)
BUPT2017 wintertraining(15) #9A 题意 有n个纪念品,购买区间是\([l_i,r_i]\).求每i(1-m)站停一次,可以买到多少纪念品. 题解 每隔d站停一次的列车,一 ...
- 深度分析Java的枚举类型—-枚举的线程安全性及序列化问题
原文:深度分析Java的枚举类型--枚举的线程安全性及序列化问题 枚举是如何保证线程安全的 要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和clas ...
- bzoj3514(LCT+主席树)
题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解 对于一个截止时间来说,越晚的变越好. 所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维 ...
- hdu 2149 (巴什博奕)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2149 Problem Description 虽然不想,但是现实总归是现实,Lele始终没有逃过退学的 ...
- pycharm安装TensorFlow
一.首先说下我在安装TensorFlow的过程中遇到的坑: 1.python的版本是3.5的版本,因为TensorFlow好像只支持到3.5现在.然后python需要安装64位的安装包,如果安装的是3 ...
- QTREE5 - Query on a tree V——LCT
QTREE5 - Query on a tree V 动态点分治和动态边分治用Qtree4的做法即可. LCT: 换根后,求子树最浅的白点深度. 但是也可以不换根.类似平常换根的往上g,往下f的拼凑 ...