整理Linux启动流程

linux是怎么启动的呢?
回答:按下电源键,玩耍手机

基础概念

BL0:SOC内置在iROM里的代码,是芯片厂商事先烧好的代码,这部分代码会根据指定的引脚电平决定从什么设备启动。BL0就是Nand Flash,NorFlash,iNand等设备的复制函数(因为要读Flash,所以要简单初始化以下Flash),他的主要工作是把BL1从Flash中拷贝到iRAM或NorFlash上运行。(BL0是SOC出厂前设置的,芯片厂商也不知道板子上将来接的是什么样的DRAM,因此配置和初始化内存和Flash就交给BL1做)

BL1:是开发人员编写的代码,可以是自己写的裸机程序,也可以是uboot或其他。BL0只做了存储器的部分初始化,BL1需要关看门狗,设置时钟,设置异常中断向量表等工作。

iRAM:Internal SRAM 芯片内置的内存,可以直接运行程序。

SOC:System on Chip系统级别芯片,芯片内部集成cpu,内存,Flash等控制器,cache等

注:系统刚上电时,内存和Flash都没有被初始化而无法使用,只有iRAM(一般十几K)可以使用,而正真的代码在Flash里,Flash(Nor除外)不能直接运行程序。

芯片内部启动

就拿熟悉的s3c2440来说

内存地址表

在这里插入图片描述

如图所示,当外接了NandFlash并设置OM引脚为Nand启动,由于程序不能在nand上运行程序,所以片内4K内存(iRAM)的0地址就是整个内存的0地址;当外接了NorFlash并设置OM引脚为Nor启动时,NorFlash的0地址就是内存的0地址,片内RAM基地址为0x4000_0000。
S3C2440上电后从0地址开始运行,如果是nand启动则从iRAM上开始运行,如果时Nor启动就从NorFlash上开始运行。

外接Nand Flash时启动流程

此时iRAM(片内内存)基地址为内存0地址。
第一步:Reset复位后,Nand Flash控制器将Nand前4K代码复制到stepping stone中运行。
第二步:这部分代码负责配置内存和Flash,然后将uboot代码复制到内存中,然后跳转到内存中运行。
第三步:最后uboot启动Linux内核(OS),然后内核去挂载根文件系统,进入命令行启动应用程序。

在这里插入图片描述

外接Nor Flash时启动流程

此时NorFlash的0地址为内存0地址。
第一步:Reset复位后,程序直接从NorFlash开始运行,初始化内存,将uboot拷贝到内存中
第二步:跳转到内存中运行,然后启动内核

uboot开始引导

最近在某玩具厂搞科研,还有一个preloader的概念,不管是什么loader,包括我们在x86上面说的BIOS,也就是basic input output system。都是为了引导系统服务的,系统起来的之前是内核,所以这些东西都是为了引导内核服务的。
我们上面不是说了第一条指令会指向一个固定的ROM地址吗?这个地址里面执行的东西,从某种意义上来说也是bootloader的一部分。这些是概念性的东西,属于帮忙内核引导的,都可以认为是bootloader的一部分。但是因为芯片设计,系统设计的原因,可能会细分一些。

bootloader 怎么启动

上面提了一些bootloaer的作用是用来引导内核的,正常bootloaer会分成两个阶段。
第一个阶段就初始化一些基本的东西,让第二阶段的bootloader能够正常运行。
第二阶段我们还需要初始化中断向量,初始化内存,初始化定时器,看门狗,这些是比串口和现实屏更加重要的。
这些做完后,就要给内核造房子让内核住进去,也就是说,我们把内核的镜像加载进入内存,然后解压,准备运行内核。
内核的运行环境准备好后,就把pc指针指向内核执行地址,之后就是内核在运行了。
在这里插入图片描述

某玩具厂的会复杂一些

在这里插入图片描述

Linux启动

Linux 非压缩内核的入口位于文件/arch/arm/kernel/head-armv.S 中的 stext 段。该段的基地址就是压缩内核解压后的跳转地址。如果系统中加载的内核是非压缩的 Image,那么bootloader将内核从 Flash中拷贝到 RAM 后将直接跳到该地址处,从而启动 Linux 内核。

启动内核函数

start_kernel是所有 Linux 平台进入系统内核初始化后的入口函数,它主要完成剩余的与硬件平台相关的初始化工作,在进行一系列与内核相关的初始化后,调用第一个用户进程-init 进程并等待用户进程的执行,这样整个 Linux 内核便启动完毕。该函数所做的具体工作有:
1)处理器初始化 : 调用 setup_arch()函数进行与体系结构相关的第一个初始化工作,函数定义在arch/arm/kernel/Setup.c。它首先通过检测出来的处理器类型进行处理器内核的初始化,然后通过 bootmem_init()函数根据系统定义的 meminfo 结构进行内存结构的初始化,最后调用paging_init()开启 MMU,创建内核页表,映射所有的物理内存和 IO空间。
2) 创建异常向量表和初始化中断处理函数;
3) 初始化系统核心进程调度器和时钟中断处理机制;
4) 初始化串口控制台(serial-console);
ARM-Linux在初始化过程中一般都会初始化一个串口做为内核的控制台,这样内核在启动过程中就可以通过串口输出信息以便开发者或用户了解系统的启动进程。
5) 创建和初始化系统 cache,为各种内存调用机制提供缓存,包括;动态内存分配,虚拟文件系统(VirtualFile System)及页缓存。
6) 初始化内存管理,检测内存大小及被内核占用的内存情况;
7) 初始化系统的进程间通信机制(IPC);

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值