Linux-Android启动之Machine-Init函数

本文详细分析了Linux启动过程中Machine-Init函数的调用位置、相关解析过程,包括machine_desc结构体、开发板的machine_desc初始化,以及Machine-Init的导出方式。Machine-Init在Linux启动中的优先级最高,类似Win CE/Windows Mobile的OEMInit。

Linux/Android启动之Machine-Init函数

 

前言

前面写过两篇Linux/Android的启动过程分析,这篇接着前两篇的知识点进行分析。

Linux/Android的启动过程包括了很多内容,其中有些需要了解,有些则需要在系统移植的时候进行修改。本篇文章主要来讲述Machine-Init函数在系统启动过程中如何被调用的以及在何时被调用。

Linux中的Machine-Init在功能和调用位置上类似于Win CE/ Windows Mobile中的OAL初始化函数OEMInit

哈哈。如果有不正确或者不完善的地方,欢迎前来拍砖留言或者发邮件到guopeixin@126.com进行讨论,先行谢过。

 

基础知识

1. Linux启动过程中驱动模块初始化的位置

Linux OS的启动过程中将会去创建线程kernel_init,该线程负责Driver初始化等一系列工作。线程kernel_init将会依次调用do_basic_setup()àdo_initcalls()àdo_one_initcall(),并在do_initcalls()中完成对各个驱动模块Init函数的调用。

这部分代码如下:

函数do_basic_setup()如下:

/*

* Ok, the machine is now initialized. None of the devices

* have been touched yet, but the CPU subsystem is up and

* running, and memory and process management works.

*

* Now we can finally start doing some real work..

*/

static void __init do_basic_setup(void)

{

rcu_init_sched(); /* needed by module_init stage. */

init_workqueues();

usermodehelper_init();

driver_init();

init_irq_proc();

do_initcalls();

}

函数do_initcalls()

extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];

static void __init do_initcalls(void)

{

initcall_t *call;

 

for (call = __early_initcall_endcall < __initcall_endcall++)

do_one_initcall(*call);

 

/* Make sure there is no pending stuff from the initcall sequence */

flush_scheduled_work();

}

函数do_one_initcall(initcall_t fn)如下:

int initcall_debug;

core_param(initcall_debuginitcall_debugbool, 0644);

 

int do_one_initcall(initcall_t fn)

{

int count = preempt_count();

ktime_t calltimedeltarettime;

char msgbuf[64];

struct boot_trace_call call;

struct boot_trace_ret ret;

 

if (initcall_debug) {

call.caller = task_pid_nr(current);

printk(

### Android系统中Linux内核启动流程 #### 1. 启动背景 Android系统的启动依赖于底层的Linux内核,而Linux内核的启动过程在整个Android系统启动中占据重要地位。无论是标准Linux发行版还是Android系统,它们的核心差异在于`init`程序的选择及其功能实现[^1]。 #### 2. 内核加载阶段 在嵌入式设备(如ARM架构下的Android设备)中,通常由引导加载程序(BootLoader)负责将Linux内核映像从存储介质复制到RAM中,并调用特定函数启动内核。这一过程通过如下代码片段完成: ```c void call_linux(unsigned long arg0, unsigned long machine_type, void *params); ``` 此函数被用于传递必要的参数给内核,例如机器类型和内核命令行参数地址[^2]。 #### 3. 内核入口点 当控制权转移到内核后,第一个被执行的C语言函数位于`init/main.c`文件中的`start_kernel(void)`。这是整个内核初始化的核心逻辑所在,它完成了以下几项关键任务: - 初始化硬件抽象层。 - 设置内存管理子系统。 - 建立进程调度机制。 - 配置中断控制器和其他核心组件。 这些操作共同构成了一个稳定运行的基础环境,使得后续更高层次的服务能够正常工作[^4]。 #### 4. init进程创建 随着内核初始化工作的结束,最后一个重要的步骤就是启动首个用户空间进程——即`init`进程。对于Android而言,这个特殊的`init`进程是由`system/core/init/init.cpp`定义并编译而成的一个二进制文件。通过调用`run_init_process()`函数执行指定路径下的`/init`脚本或可执行文件,从而开启一系列服务与守护进程[^3]。 以下是简化版本的伪代码表示如何启动init进程的过程: ```c int run_init_process(const char* filename) { argv[0] = (char*)filename; execve(filename, argv, environ); } ``` 最终,在成功启动之后,`init`进程将继续按照预设配置逐步激活其他必要组件直至呈现完整的图形化界面供用户体验。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值