arm-linux启动,linux启动流程arm
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相关推荐
- 织女星开发板能移植linux吗,织女星开发板启动模式修改——从ARM M4核启动
前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档,原来RV32M1芯片默认从RISC-V核启动,如果 ...
- uboot启动Linux内核(一):uboot启动流程
1. uboot介绍: uboot是bootloader的一种,是Linux内核的引导启动程序.会初始化嵌入式平台上的一些外设(比如:ddr等),把Linux内核镜像从flash中加载到内存,在 ...
- uboot启动linux内核流程分析(三)
uboot bootz命令流程图 Uboot启动linux内核是使用bootz命令,bootz是如何启动linux内核?uboot的生命周期是怎么终止的?linux是如何启动? 启动linux内核的时 ...
- Linux系统管理-开机启动流程
Linux系统管理-开机启动流程 文章目录 Linux系统管理-开机启动流程 CentoOS6的开机启动流程 CentOS6忘记root密码 Linux的关机指令 CentOS7的开机启动流程 Cen ...
- Linux·启动脚本·启动流程
目录 1.关于/sbin/init与/etc/inittab 2. 关于etc/rc.d/rc.sysinit 和 /etc/rc.d/rc.Nd Linux系统脚本和登录环境 下面是一张Linux启 ...
- linux忽略abort信号,ARM Linux Data Abort 异常处理流程
// 本文部分内容来自网络 //基于内核版本3.4 发生Data Abort异常后,ARM处理器首先根据向量表找到对应异常入口,向量表位于arch/arm/kernel/entry-armv.S: . ...
- linux 文件系统 启动,linux kernel文件系统启动部分
现在的kernel里,有个叫做ramfs的文件系统,会把initrd(或者ramdisk,为惯性叫法)里的东西挂载到early-rootfs里(即rootfs,是ramfs的一个特殊实例),执行一些在 ...
- ARM视频 嵌入式linux培训班视频》[DVDRip]
ARM视频 嵌入式linux培训班视频>[DVDRip] 2008-11-15 12:09 eMule资源 http://www.verycd.com/topics/250252/ 下面是用 ...
- Linux内核学习(七):linux kernel内核启动(一):概述篇
Linux内核学习(七):linux kernel内核启动(一):概述篇 这一篇让我们来大致的了解一下Linux内核的启动过程 这篇文章不涉及源码,重在让你知道这个linux内核的启动过程,源码详细的 ...
- linux 嵌入式 快照_基于Linux的嵌入式启动优化的研究
基于Linux的嵌入式启动优化的研究 论文 开题分析 周报 启动 基于Linux嵌入式系统启动加速的研究 一. 所选课题的目的和意义 随着科学技术的蓬勃发展,计算机被更多的人使用,并与人类对额生活结合 ...
最新文章
- Vue报错:Error while running task D:\vue\forum:build with message‘spawn vue-cli-service ENOENT‘
- C# List集合转Json字符串示例代码
- rancher使用fluentd-pilot收集日志分享
- 如何在VB例程中接收自定义消息
- 目标检测系列(五)——Faster R-CNN译文
- html5点击按钮出现弹窗 怎么实现_HTML5游戏开发过程中的二三事
- 微软Cloud+AI本地化社区贡献指南
- mysql脚本解读_一篇很好的关于mysqld_safe脚本源码解读的文章,收藏了!!
- JavaScript:执行上下文执行上下文栈
- ios控件 UIViewController
- 集成系列:低代码对接泛微e-cology
- 【游戏开发指路】Unity学习路线,三万字大纲(面试题大纲 | 知识图谱 | Unity游戏开发工程师)
- 在 Windows 中为高级用户配置 IPv6 的指南
- gitgub常用按钮说明
- Java流(Stream)
- 2020牛客寒假算法基础集训营4 - G 音乐鉴赏-全概率公式
- 改图片分辨率怎么改?教你一招一分钟修改图片dpi
- Ubuntu 卸载程序
- wpf 响应键盘按键
- linux创建任务栏图标