Arm Linux系统启动流程分析

1. 引言

在当前的计算机系统中,操作系统作为计算机系统中的重要组成部分,其负责实现对计算机系统中各种资源的管理和分配,提供服务接口并保证计算机系统高效稳定地运行。即使随着硬件性能的不断提升,操作系统的重要性也不会有所下降,相反,在某些场景下,操作系统可能会对系统的性能和稳定性起着更加重要的作用。本文将重点探讨Arm Linux系统启动的过程。

2. Arm Linux系统启动的过程

2.1 开机自检和bootloader的加载

在计算机加电后,计算机进行自检操作并启动bootloader,后者是负责加载操作系统内核到计算机操作存储器中的低级程序。

其中的一些常见的启动引导程序包括U-Boot和Grub2。在这些启动引导程序的实现中,除了初始化硬件设备、加载内核文件外,还可以提供对文件系统的支持,用于引导计算机系统。这些操作很大程度上相当于BIOS的功能,旨在确保操作系统的安全加载及其启动。

void start_kernel(void) {

/*

* We try each of these until one succeeds.

*/

try_name(boot_command_line, "/boot/vmlinuz-%s", linux_banner);

try_name("", "/boot/vmlinuz-%s", linux_banner);

panic("Unable to locate any valid\n"

"kernel image\n");

}

U-Boot作为流行的启动引导程序,其在启动过程中会通过serial、flash和net等方式加载内核进入内存,然后将控制权转移到内核,并且内核会在页面设置和内核数据结构的初始化阶段对内存进行初始化。

2.2 内核的初始化

内核的初始化主要包含以下几个方面:

1. 内存管理的初始化:内核首先会进行内存管理的初始化,包括访问控制、内存映射、缺页中断处理等。其中,其中会调用arch/arm/kernel/head.S头文件中实现的arm_setup_cpu_cache()来初始化cache信息。

void arm_setup_cpu_cache(void)

{

CP15_CACHE_TYPE c;

cpu_cache_wb = cachepages_alloc();

/*

* Because we are assumed to be the only user of the cache

* we can assume we won't find one with a conflicting virtual

* address.

*/

cpu_cache_wb_phys = page_to_phys(cpu_cache_wb);

c = read_cpuid_cachetype();

cpu_dcache_line_size = c.dminline << c.dlinesize;

cpu_icache_line_size = c.uminline << c.ulinesize;

}

2. 中断和异常管理的初始化:内核启动后,会开启CPU对所有中断和异常的响应,并通过设置相应的中断向量表实现这一点。

asmlinkage void __exception do_undefined_instruction(unsigned int instr,

struct pt_regs *regs)

{

pr_emerg("Undefined instruction: pc=%08x\n", regs->ARM_pc);

arm_notify_die("Undefined instruction", regs, NULL);

}

3. 进程管理的初始化:内核会初始化进程管理数据结构,例如任务队列、调度器、进程标识等。

4. 硬件设备的初始化:最后,内核会初始化一些具有硬件特定的数据结构,例如网络设备以及输入/输出接口等。

2.3 用户空间的初始化

内核初始化后,系统会启动用户空间,执行/sbin/init等文件,例如RHEL系统会执行systemd systemctl等文件进行后续的用户管理操作。

pid = kernel_thread(do_init, NULL, CLONE_FS | CLONE_SIGHAND | CLONE_SIGNAL | SIGCHLD);

free_initrd_mem();

if (pid < 0)

panic("Failed to execute init (%d)\n", pid);

/*

* We do waitpid(-1) later to pick up the init process

*/

schedule();

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

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

2.4 总结

本文从开机自检和bootloader的加载、内核的初始化和用户空间的初始化三个方面介绍了Arm Linux系统启动的过程。为了确保操作系统能够安全加载和启动,启动引导程序需要提供对操作系统的支持,并且跟踪和修复任何与启动过程相关的错误。在启动内核之后,内核将需要初始化内存管理、中断和异常管理、进程管理以及硬件设备等管理数据结构,将关注点从硬件初始化转移到系统管理。

操作系统标签