linux启动分析(1)---bootloader启动内核过程

void (*startkernel)(int zero, int arch, unsigned int params_addr) = (void(*)(int, int, unsigned int))KERNEL_RAM_BASE;

其中KERNEL_RAM_BASE为内核在ram中启动的地址,ARCH_NUMBER是Machine Type Number,kernel_params_start是参数在ram的偏移地址。

linux启动分析(2)---内核启动地址的确定

其中TEXTADDR就是内核启动的虚拟地址,定义在kernel/arch/arm/Makefile中:ifeq ($(CONFIG_CPU_32),y)

PROCESSOR    = armv

TEXTADDR     = 0xC0008000

LDSCRIPT     = arch/arm/vmlinux-armv.lds.in

endif

内核编译链接过程是依靠vmlinux.lds文件,以arm为例vmlinux.lds文件位于kernel/arch/arm/vmlinux.lds,但是该文件是由vmlinux-armv.lds.in生成的,根据编译选项的不同源文件还可以是vmlinux-armo.lds.in,vmlinux-armv-xip.lds.in。

vmlinux-armv.lds.in文件的内容:

OUTPUT_ARCH(arm)

ENTRY(stext)

SECTIONS

{

. = TEXTADDR;

.init : {           /* Init code and data       */

_stext = .;

__init_end = .;

}

一般情况下都在生成vmlinux后,再对内核进行压缩成为zImage,压缩的目录是kernel/arch/arm/boot。下载到flash中的是压缩后的zImage文件,zImage是由压缩后的vmlinux和解压缩程序组成,如下图所示:

linux启动分析(3)---内核解压缩过程

它将调用函数decompress_kernel(),这个函数在文件arch/arm/boot/compressed/misc.c中,decompress_kernel()又调用proc_decomp_setup(),arch_decomp_setup()进行设置,然后使用在打印出信息“Uncompressing Linux...”后,调用gunzip()。将内核放于指定的位置。

linux启动分析(4)---汇编启动 arch/arm/kernel/head.S

__HEAD

ENTRY(stext)

setmode    PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode

@ and irqs disabled

mrc    p15, 0, r9, c0, c0        @ get processor id

bl    __lookup_processor_type        @ r5=procinfo r9=cpuid

movs    r10, r5                @ invalid processor (r5=0)?

THUMB( it    eq )        @ force fixup-able long branch encoding

beq    __error_p            @ yes, error 'p'

#ifndef CONFIG_XIP_KERNEL

adr    r3, 2f

ldmia    r3, {r4, r8}

sub    r4, r3, r4            @ (PHYS_OFFSET - PAGE_OFFSET)

add    r8, r8, r4            @ PHYS_OFFSET

#else

ldr    r8, =PLAT_PHYS_OFFSET

#endif

/*

* r1 = machine no, r2 = atags or dtb,

* r8 = phys_offset, r9 = cpuid, r10 = procinfo

*/

bl    __vet_atags

#ifdef CONFIG_SMP_ON_UP

bl    __fixup_smp

#endif

#ifdef CONFIG_ARM_PATCH_PHYS_VIRT

bl    __fixup_pv_table

#endif

bl    __create_page_tables

/*

* The following calls CPU specific code in a position independent

* manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of

* xxx_proc_info structure selected by __lookup_processor_type

* above.  On return, the CPU will be ready for the MMU to be

* turned on, and r0 will hold the CPU control register value.

*/

ldr    r13, =__mmap_switched        @ address to jump to after

@ mmu has been enabled

adr    lr, BSYM(1f)            @ return (PIC) address

mov    r8, r4                @ set TTBR1 to swapper_pg_dir

ARM(    add    pc, r10, #PROCINFO_INITFUNC    )

THUMB(    add    r12, r10, #PROCINFO_INITFUNC    )

THUMB(    mov    pc, r12                )

1:    b    __enable_mmu

ENDPROC(stext)

head-common.S

__INIT

__mmap_switched:

adr    r3, __mmap_switched_data

ldmia    r3!, {r4, r5, r6, r7}

cmp    r4, r5                @ Copy data segment if needed

1:    cmpne    r5, r6

ldrne    fp, [r4], #4

strne    fp, [r5], #4

bne    1b

mov    fp, #0                @ Clear BSS (and zero fp)

1:    cmp    r6, r7

strcc    fp, [r6],#4

bcc    1b

ARM(    ldmia    r3, {r4, r5, r6, r7, sp})

THUMB(    ldmia    r3, {r4, r5, r6, r7}    )

THUMB(    ldr    sp, [r3, #16]        )

str    r9, [r4]            @ Save processor ID

str    r1, [r5]            @ Save machine type

str    r2, [r6]            @ Save atags pointer

bic    r4, r0, #CR_A            @ Clear 'A' bit

stmia    r7, {r0, r4}            @ Save control register values

b    start_kernel

ENDPROC(__mmap_switched)

__lookup_processor_type

__lookup_architecture_type

__create_page_tables

__mmap_switched

b   start_kernel

linux启动分析(5)---C程序入口函数start_kernel

init\main.c

asmlinkage void __init start_kernel(void)

{

printk(KERN_NOTICE "%s", linux_banner);

setup_command_line(command_line);

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);

console_init();

fork_init(totalram_pages);

rest_init();

}

static noinline void __init_refok rest_init(void)

{

kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

cpu_idle();

}

static int __init kernel_init(void * unused)

{

/* Open the /dev/console on the rootfs, this should never fail */

if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)

printk(KERN_WARNING "Warning: unable to open an initial console.\n");

init_post();

return 0;

}

linux启动6 init_post

static noinline int init_post(void)

{

if (execute_command) {

run_init_process(execute_command);

printk(KERN_WARNING "Failed to execute %s.  Attempting "

"defaults...\n", execute_command);

}

run_init_process("/sbin/init");

run_init_process("/etc/init");

run_init_process("/bin/init");

run_init_process("/bin/sh");

panic("No init found.  Try passing init= option to kernel. "

"See Linux Documentation/init.txt for guidance.");

}

arm-linux启动,linux启动流程arm相关推荐

  1. 织女星开发板能移植linux吗,织女星开发板启动模式修改——从ARM M4核启动

    前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档,原来RV32M1芯片默认从RISC-V核启动,如果 ...

  2. uboot启动Linux内核(一):uboot启动流程

    1. uboot介绍:    uboot是bootloader的一种,是Linux内核的引导启动程序.会初始化嵌入式平台上的一些外设(比如:ddr等),把Linux内核镜像从flash中加载到内存,在 ...

  3. uboot启动linux内核流程分析(三)

    uboot bootz命令流程图 Uboot启动linux内核是使用bootz命令,bootz是如何启动linux内核?uboot的生命周期是怎么终止的?linux是如何启动? 启动linux内核的时 ...

  4. Linux系统管理-开机启动流程

    Linux系统管理-开机启动流程 文章目录 Linux系统管理-开机启动流程 CentoOS6的开机启动流程 CentOS6忘记root密码 Linux的关机指令 CentOS7的开机启动流程 Cen ...

  5. Linux·启动脚本·启动流程

    目录 1.关于/sbin/init与/etc/inittab 2. 关于etc/rc.d/rc.sysinit 和 /etc/rc.d/rc.Nd Linux系统脚本和登录环境 下面是一张Linux启 ...

  6. linux忽略abort信号,ARM Linux Data Abort 异常处理流程

    // 本文部分内容来自网络 //基于内核版本3.4 发生Data Abort异常后,ARM处理器首先根据向量表找到对应异常入口,向量表位于arch/arm/kernel/entry-armv.S: . ...

  7. linux 文件系统 启动,linux kernel文件系统启动部分

    现在的kernel里,有个叫做ramfs的文件系统,会把initrd(或者ramdisk,为惯性叫法)里的东西挂载到early-rootfs里(即rootfs,是ramfs的一个特殊实例),执行一些在 ...

  8. ARM视频 嵌入式linux培训班视频》[DVDRip]

    ARM视频 嵌入式linux培训班视频>[DVDRip] 2008-11-15 12:09 eMule资源   http://www.verycd.com/topics/250252/ 下面是用 ...

  9. Linux内核学习(七):linux kernel内核启动(一):概述篇

    Linux内核学习(七):linux kernel内核启动(一):概述篇 这一篇让我们来大致的了解一下Linux内核的启动过程 这篇文章不涉及源码,重在让你知道这个linux内核的启动过程,源码详细的 ...

  10. linux 嵌入式 快照_基于Linux的嵌入式启动优化的研究

    基于Linux的嵌入式启动优化的研究 论文 开题分析 周报 启动 基于Linux嵌入式系统启动加速的研究 一. 所选课题的目的和意义 随着科学技术的蓬勃发展,计算机被更多的人使用,并与人类对额生活结合 ...

最新文章

  1. Vue报错:Error while running task D:\vue\forum:build with message‘spawn vue-cli-service ENOENT‘
  2. C# List集合转Json字符串示例代码
  3. rancher使用fluentd-pilot收集日志分享
  4. 如何在VB例程中接收自定义消息
  5. 目标检测系列(五)——Faster R-CNN译文
  6. html5点击按钮出现弹窗 怎么实现_HTML5游戏开发过程中的二三事
  7. 微软Cloud+AI本地化社区贡献指南
  8. mysql脚本解读_一篇很好的关于mysqld_safe脚本源码解读的文章,收藏了!!
  9. JavaScript:执行上下文执行上下文栈
  10. ios控件 UIViewController
  11. 集成系列:低代码对接泛微e-cology
  12. 【游戏开发指路】Unity学习路线,三万字大纲(面试题大纲 | 知识图谱 | Unity游戏开发工程师)
  13. 在 Windows 中为高级用户配置 IPv6 的指南
  14. gitgub常用按钮说明
  15. Java流(Stream)
  16. 2020牛客寒假算法基础集训营4 - G 音乐鉴赏-全概率公式
  17. 改图片分辨率怎么改?教你一招一分钟修改图片dpi
  18. Ubuntu 卸载程序
  19. wpf 响应键盘按键
  20. linux创建任务栏图标

热门文章

  1. 正则表达式 Tricks
  2. struts2值栈分析
  3. (转)初识suse——linux
  4. Linux-shell获取天气
  5. 用BULK INSERT命令导入数据详解
  6. linux 开机默认启动windows系统时间,Windows和Linux双系统批改默认启动项、超时时间...
  7. Knockout获取数组元素索引的2种方法,在MVC中实现
  8. python 学习DAY12
  9. Ubuntu12.04中eclipse提示框黑色背景色修改
  10. SQL Server数据库纵向转横向