1、uboot引导kernel:
u-boot中有个bootm命令,它可以引导内存中的应用程序映像(Kernel),bootm命令对应
common/cmd_bootm.c中的do_bootm()函数,此函数实现下面几个功能:
1)读flash中的内核映像文件
2)解压内核
3)校验内核
4)跳到内核执行(调用do_bootm_linux()函数)
    {

1、Stage1 start.S代码结构 u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下

(1) 定义入口。:

该工作通过修改连接器脚本来完成。

(2)设置异常向量(Exception Vector)。

(3)设置CPU的速度、时钟频率及终端控制寄存器。

(4)初始化内存控制器。

(5)将ROM中的程序复制到RAM中。

(6)初始化堆栈。

(7)转到RAM中执行,该工作可使用指令ldr pc来完成。

2、Stage2 C语言代码部分 lib_arm/board.c中的start arm boot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数只要完成如下操作:

(1)调用一系列的初始化函数。

(2)初始化Flash设备。

(3)初始化系统内存分配函数。

(4)如果目标系统拥有NAND设备,则初始化NAND设备。

(5)如果目标系统有显示设备,则初始化该类设备。

(6)初始化相关网络设备,填写IP、MAC地址等。

(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。

}

2、kernel引导fs:
    1)获得可运行的Linux内核
    2)内核装载时的内存空间映射
    3)内核启始相关文件分析
    4)arch/i386/boot/bootsect.S
    5)arch/i386/boot/setup.S
    6)arch/i386/boot/compressed/head.S
    7)arch/i386/kernel/head.S
    8)start_kernel
    {

在start_kernel()函数中:

  输出Linux版本信息(printk(_banner))

  设置与体系结构相关的环境(setup_arch())

  页表结构初始化(paging_init())

  使用"arch/alpha/kernel/entry.S"中的入口点设置系统自陷入口(trap_init())

  使用alpha_mv结构和entry.S入口初始化系统IRQ(init_IRQ())

  核心进程调度器初始化(包括初始化几个缺省的Bottom-half,sched_init())

  时间、定时器初始化(包括读取CMOS时钟、估测主频、初始化定时器中断等,time_init())

  提取并分析核心启动参数(从环境变量中读取参数,设置相应标志位等待处理,(parse_options())

  控制台初始化(为输出信息而先于PCI初始化,console_init())

  剖析器数据结构初始化(prof_buffer和prof_len变量)

  核心Cache初始化(描述Cache信息的Cache,kmem_cache_init())

  延迟校准(获得时钟jiffies与CPU主频ticks的延迟,calibrate_delay())

  内存初始化(设置内存上下界和页表项初始值,mem_init())

  创建和设置内部及通用cache("slab_cache",kmem_cache_sizes_init())

  创建uid taskcount SLAB cache("uid_cache",uidcache_init())

  创建文件cache("files_cache",filescache_init())

  创建目录cache("dentry_cache",dcache_init())

  创建与虚存相关的cache("vm_area_struct","mm_struct",vma_init())

  块设备读写缓冲区初始化(同时创建"buffer_head"cache用户加速访问,buffer_init())

  创建页cache(内存页hash表初始化,page_cache_init())

  创建信号队列cache("signal_queue",signals_init())

  初始化内存inode表(inode_init())

  创建内存文件描述符表("filp_cache",file_table_init())

  检查体系结构漏洞(对于alpha,此函数为空,check_bugs())

  SMP机器其余CPU(除当前引导CPU)初始化(对于没有配置SMP的内核,此函数为空,smp_init())

  启动init过程(run_init_process() 创建第一个核心线程,调用init()函数,原执行序列调用cpu_idle() 等待调度,init())

  至此start_kernel()结束,基本的核心环境已经建立起来了。

    }
    9)第一个内核线程 - kernel_init
三、start_kernel函数流程:
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[]; smp_setup_processor_id();//首先判断是否是SMP (对称多处理器)对单核SOC来说,mpidr = 0; /*
* Need to run as early as possible, to initialize the
* lockdep hash:
*/
lockdep_init(); //只初始化该哈希表一次
debug_objects_early_init(); /*
* Set up the the initial canary ASAP:
*/
boot_init_stack_canary();//stack_canary的是带防止栈溢出攻击保护的堆栈 /**
* cgroup_init_early - cgroup initialization at system boot
*
* Initialize cgroups at system boot, and initialize any
* subsystems that request early init.
*/
cgroup_init_early();  local_irq_disable();
early_boot_irqs_disabled = true; /*
 * Interrupts are still disabled. Do necessary setups, then
 * enable them
 */
//初始化time ticket,时钟
tick_init();  //用以启动的CPU进行初始化。也就是初始化CPU0
boot_cpu_init(); //初始化页面
page_address_init(); printk(KERN_NOTICE "%s", linux_banner); //CPU架构相关的初始化
setup_arch(&command_line); //初始化内存管理
mm_init_owner(&init_mm, &init_task);
mm_init_cpumask(&init_mm); //处理启动命令行
setup_command_line(command_line); //可能多余的初始化可能去判断cpu的最大支持个数
setup_nr_cpu_ids(); //为每个CPU开辟一块区域?
setup_per_cpu_areas(); //准备boot_cpu.如果是SMP环境,则设置boot CPU的一些数据。在引导过程中使用的CPU称为boot CPU
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ //Linux将所有物理内存分为三个区,ZONE_DMA, ZONE_NORMAM, ZONE_HIGHMEM
build_all_zonelists(NULL); //初始化page allocation相关结构
page_alloc_init(); printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); //解 析启动参数
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param,
  __stop___param - __start___param,
  &unknown_bootoption);
/*
* These use large bootmem allocations and must precede
* kmem_cache_init()
*/
setup_log_buf(0); //初始化process ID hash表
pidhash_init(); //文件系统caches预初始化
vfs_caches_init_early(); //初始化exception table
sort_main_extable(); //初始化trap,用以处理错误执行代码
trap_init(); //初始化内存管理
mm_init(); /*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/ //进程调度初始化
sched_init();
/*
* Disable preemption - early bootup scheduling is extremely
* fragile until we cpu_idle() for the first time.
*/
// 后当前进程将不能被强抢占
preempt_disable(); /*判断中断是否关闭,若打开则关闭中断*/
if (!irqs_disabled()) {
printk(KERN_WARNING "start_kernel(): bug: interrupts were "
"enabled *very* early, fixing it\n");
local_irq_disable();
} idr_init_cache();
perf_event_init(); //Read_Copy_Update机制初始 /*初始化互斥机制*/  
rcu_init();
radix_tree_init(); /*中断向量的初始化*/  
/* init some links before init_ISA_irqs() */
early_irq_init(); //初始化中断
init_IRQ();
prio_tree_init(); /*初始化定时器*/  
init_timers(); // 初始化高精时钟
hrtimers_init(); // 初始化软中断
softirq_init(); // 初始化时钟源
timekeeping_init(); /*初始化系统时钟*/  
time_init(); /* 对内核的profile(一个内核性能调式工具)功能进行初始化 */    
profile_init(); call_function_init();//???
if (!irqs_disabled())
printk(KERN_CRIT "start_kernel(): bug: interrupts were "
"enabled early\n");
early_boot_irqs_disabled = false; /*打开IRQ中断*/ 
local_irq_enable(); /* Interrupts are enabled now so all GFP allocations are safe. */
gfp_allowed_mask = __GFP_BITS_MASK; //初始化CPU Cache
kmem_cache_init_late(); /*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
 
//初始化console
console_init();
if (panic_later)
panic(panic_later, panic_param); lockdep_info(); /*
* Need to run this when irqs are enabled, because it wants
* to self-test [hard/soft]-irqs on/off lock inversion bugs
* too:
*/
 
//自测试锁
locking_selftest(); #ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
   page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
   "disabling it.\n",
   page_to_pfn(virt_to_page((void *)initrd_start)),
   min_low_pfn);
initrd_start = 0;
}
#endif //页面初始
page_cgroup_init(); //页面分配debug启用
enable_debug_pagealloc();
debug_objects_mem_init(); //memory leak 侦测初始化
kmemleak_init(); //设置每个CPU的页面集合
setup_per_cpu_pageset();
numa_policy_init();
if (late_time_init)
late_time_init(); //初始化调度时钟
sched_clock_init(); /*校验延时函数的精确度*/  
calibrate_delay(); /*进程号位图初始化,一般用一个page来只是所有的进程PID占用情况*/ 
pidmap_init(); //anonymous page?什么意思?
anon_vma_init(); #ifdef CONFIG_X86
if (efi_enabled)
efi_enter_virtual_mode();
#endif //初始化thread info
thread_info_cache_init(); //credential
cred_init(); //初始化fork
fork_init(totalram_pages); //初始化/proc的cache?
proc_caches_init(); buffer_init();
key_init();
security_init();
dbg_late_init(); //文件系统cache初始化
vfs_caches_init(totalram_pages);
signals_init(); /* rootfs populating might need page-writeback */
page_writeback_init(); #ifdef CONFIG_PROC_FS
proc_root_init();//本文件系统??
#endif cgroup_init();
cpuset_init();
taskstats_init_early();
delayacct_init(); check_bugs(); acpi_early_init(); /* before LAPIC and SMP init */ //simple firmware interface
sfi_init_late(); ftrace_init(); /* Do the rest non-__init'ed, we're now alive */
rest_init();
}

嵌入式 uboot引导kernel,kernel引导fs的更多相关文章

  1. mini2440 uboot使用nfs方式引导内核,文件系统

    mini2440 uboot使用nfs方式引导内核,文件系统 成于坚持,败于止步 看了一段时间的u-boot了,到今天才真正完全实现u-boot引导内核和文件系统,顺利开机,在此记录完整过程 1.首先 ...

  2. 【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介

    作者 : 韩曙亮 转载请出名出处 : http://blog.csdn.net/shulianghan/article/details/38636827 一. Linux 内核简介 1. 内核功能简介 ...

  3. sd卡无法启动及zc706更改主频后可以进入uboot无法启动kernel的坑

    好长的标题 +_+ 1.sd卡无法启动 起因:kernel底下通过dd测试速度,擦写了sd卡,再启动时发现无法启动 于是重新格式化,再将BOOT.bin 相关dtb u-rootfs zImage和u ...

  4. 【转载】Windows上那些值得推荐的良心软件-整理 easybcd 引导工具 easyuefi 引导工具

    您查询的关键词是:清理dism知乎 以下是该网页在北京时间 2019年03月17日 21:56:16 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. 百度和网页 htt ...

  5. 嵌入式 uboot引导kernel,kernel引导fs【转】

    转自:http://www.cnblogs.com/lidabo/p/5383934.html#3639633 1.uboot引导kernel: u-boot中有个bootm命令,它可以引导内存中的应 ...

  6. 嵌入式 uboot、fs、kernel制作和烧录简记-hi3518c

    NULL RAM : mkdir ramdisk_test  临时挂在点 dd if=/dev/zero of=rootfs.ramdisk bs=1k count=10000 建立空硬盘//1500 ...

  7. 嵌入式 uboot以及kernel添加看门狗临时记录(个人记录未整理乱)

    Uboot_Kernerl_Add_Watch_Dog: U-Boot 2010.06 (Nov 01 2013 - 15:28:44) DRAM:  128 MiBCheck spi flash c ...

  8. 一文搞懂嵌入式uboot、kernel、文件系统的关系

    总览: 在linux系统软件架构可以分为4个层次(从低到高分别为):   1.引导加载程序         引导加载程序(Bootloader)是固化在硬件Flash中的一段引导代码,用于完成硬件的一 ...

  9. 【linux】U-BOOT与linux kernel通信: struct tag

      欢迎转载,转载时需保留作者信息. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http://b ...

随机推荐

  1. Python概述_软件安装_常见问题

    1.  Python安装 目前python有2个大版本,2和3,由于2和3语法有差别,现有的许多库都是基于python2开发,本系列文章以python2为主. 1.1  重要概念 1. 动态语言 运行 ...

  2. Gravitational Teleport 是一个先进的 SSH 服务器,基于 Golang SSH 构建,完全兼容 OpenSSH

    Gravitational Teleport 是一个先进的 SSH 服务器,可通过 SSH 或者 HTTPS 远程访问 Linux 服务器.其目的是为了替代 sshd.Teleport 可以轻松让团队 ...

  3. linux shell 命令学习(4) cut - remove sections from each line of files

    之前写了split命令,split主要是按照行来进行文件的分割,而cut 是按照列来进行文件内容的选取 cut OPTION... [FILE]... 描述: 按列选取FILE的内容进行输出 -d : ...

  4. Java:文件类File的详解

    File类的常用方法: 1.创建     boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false.和输出流不一样,输出流对象一建立创建文件,而 ...

  5. SSIS ->> Script Debugging and Troubleshooting

    Breakpoint是调试过程中最重要的手段,不仅对于Script Task和Script Component,对于任何其他的组件也是如此.可以在某个Event(如OnError)触发的时候设置断点来 ...

  6. Spring AOP基础知识

    Spring AOP使用动态代理技术在运行期织入增强的代码,两种代理机制包括:一是基于JDK的动态代理,另一种是基于CGLib的动态代理.之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的 ...

  7. ubuntu 12.10无法用apt-get安装软件 Err http://us.archive.ubuntu.com quantal-updates/main Sources 404 Not

     之前执行apt-get 不管是什么软件或apt-get update都会遇到fail to fetch http://us.archive.ubuntu.com quantal-updates/ma ...

  8. 脉络清晰的BP神经网络讲解,赞

    学习是神经网络一种最重要也最令人注目的特点.在神经网络的发展进程中,学习算法的研究有着十分重要的地位.目前,人们所提出的神经网络模型都是和学习算 法相应的.所以,有时人们并不去祈求对模型和算法进行严格 ...

  9. 14_把文件存放在SDCard

    权限添加 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> /** ...

  10. cmd执行mssql脚本或者执行mysql脚本

    private static int ExecuteMSSql(DbInfo db, string sqlPath) { Console.WriteLine("=============== ...