内核启动流程2-C语言部分的最后一个函数init_post()

最后分析最终调用用户空间init进程的函数init_post().

static noinline int init_post(void)这是一个非_init函数。强制让它为非内联函数,以防gcc让它内联到init()中成为init.text段的一部分。

async_synchronize_full();

free_initmem();

这两行用于释放所有init.*段所占用内存。

unlock_kernel();

释放大内核锁,使该线程可以在其他处理器上运行。

mark_rodata_ro();

通过修改页表,保证只读数据段为只读属性。对ARM架构而言是空操作。

system_state=SYSTEM_RUNNING;

设置系统状态为运行状态。

numa_default_policy();

设定NUMA系统的内存访问策略为默认。对于2440/6410,是空操作。

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

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

这是kernel_init打开的第一个文件,也是该进程的标准输入。这里需要打开"/dev/console",如果没有这个节点,系统就出错。可能的原因是:

1)制作文件系统时,忘记 创建/dev/console节点。

2)文件系统挂载问题,挂载上的文件系统不是什么都没有,就是挂载错了节点。

(void) sys_dup(0);

(void) sys_dup(0);

复制两次标准输入(0)的文件描述符(它是上面打开的"/dev/console",即系统控制台):

一个作为标准输出(1),另一个作为标准出错(2)。现在标准输入、标准输出、标准出错都是"/dev/console"了。

该console在内核启动参数中可以配置为某个串口(ttySACn、ttySn等等),也可以是虚拟控制台(tty0)。因此在串口或者显示器上看到之后的系统登录提示。

current->signal->flags |=SIGNAL_UNKILLABLE;

设置当前进程(init)为不可以杀进程(忽略致命的信号)

if(ramdisk_execute_command)

{

  run_init_process(ramdisk_execute_command);

  printk(KERN_WARNING "Failed to execute %s\n",ramdisk_execute_command);

如果指定了ramdisk_execute_command,则执行它表示的内存磁盘的用户空间init进程。

if(execute_command)

{

  run_init_process(execute_command);

  printk(KERN_WARNING "Failed to execute %s. attempting" "default...\n",execute_command);

}

execute_command在init_setup()函数中被初始化,而后者会将命令行参数中"init="的参数值赋值给execute_command,因此,如果在命令行参数中设置了"init"参数,则执行该参数指定用户空间init进程。

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

最后代码表示:在检查完ramdisk_execute_command和execute_command为空的情况下,顺序执行上述初始化程序,如果没有找到,就打印错误信息,并挂起内核。出现这个内核挂起错误的原因:

1)启动参数配置有问题,通过命令行参数指定的init程序系统没有找到,且默认的那4个程序也不在文件系统里。

2)文件系统挂载有问题,文件不存在。

3)init程序没有执行权限。

至此,内核的初始化结束,系统正式进入用户空间的init进程。

时间: 2024-11-05 02:31:46

内核启动流程2-C语言部分的最后一个函数init_post()的相关文章

Tiny4412 Linux 内核启动流程

Linux内核的启动分为压缩内核和非压缩内核两种,这里我们以压缩内核为例.压缩内核运行时,将运行一段解压缩程序,得到真正的内核镜像,然后跳转到内核镜像运行.此时,Linux进入非压缩内核入口,在非压缩内核入口中,完成各种初始化操作后跳转到C语言入口处运行.主要流程如下所示. 1.解压缩内核镜像 解压缩程序通常在arch/arm/boot/compressed/目录中 ├── atags_to_fdt.c ├── big-endian.S ├── decompress.c ├── head.S ├

Linux内核启动流程分析(二)【转】

转自:http://blog.chinaunix.net/uid-25909619-id-3380544.html S3C2410 Linux 2.6.35.7启动分析(第二阶段) 接着上面的分析,第一阶段的代码跳转后,会进入第二阶段的代码. 第二阶段的代码是从\arch\arm\kernel\head.S开始的. 内核启动第二阶段主要完成的工作有,cpu ID检查,machine ID(也就是开发板ID)检查,创建初始化页表,设置C代码运行环境,跳转到内核第一个真正的C函数startkerne

Linux学习笔记之内核启动流程与模块机制

本文旨在简单的介绍一下Linux的启动流程与模块机制: Linux启动的C入口位于/Linux.2.6.22.6/init/main.c::start_kernel() 下图简要的描述了一下内核初始化的流程: 本文我们分析一下do_initcalls ()函数,他负责大部分模块的初始化(比如U盘驱动就是在这里被初始化的). 1 static void __init do_initcalls(void) 2 { 3 initcall_t *call; 4 int count = preempt_c

linux内核启动流程[转]

启动流程一览 既然启动是很严肃的一件事,那我们就来了解一下整个启动的过程吧! 好让大家比较容易发现启动过程里面可能会发生问题的地方,以及出现问题后的解决之道! 不过,由於启动的过程中,那个启动管理程序 (Boot Loader) 使用的软件可能不一样,例如目前各大 Linux distributions 的主流为 grub,但早期 Linux 默认是使用 LILO . 但无论如何,我们总是得要了解整个 boot loader 的工作情况,才能了解为何进行多重启动的配置时, 老是听人家讲要先安装

内核启动流程

系统启动流程(1)       pc:os(linux)        POST(加电自检)-->BIOS (Boot sequence)(决定到哪里有启动操作系统的顺利)--MBR(bootloader ,446bit) -->Kernel  (文件系统.进程管理.内存管理.网络管理.安全功能.驱动程序)-->initrd    --/sbin/init (用户空间进程的管理)[启动系统模块,与相关的硬件信息的初始化文件 /etc/rc.d/rc.sysinit-->启动系统中所

Linux嵌入式驱动学习之路⑦Linux内核启动流程

编译的内核可能会很大,故这里可以压缩一下.而在内核文件中需要解压,所以就会有一段自解压代码. 在uboot启动内核的时候,调用了函数: thekernel(0,MACH_ID,params_addr ) 1. 首先处理uboot传入的参数. 获取处理器id,查看内核是否支持这个处理器. 获取uboot传入的机器ID,查看内核是否支持所运行该系统的单板. 挂载根文件系统. 最终目的是运行应用程序

linux、内核源码、内核编译与配置、内核模块开发、内核启动流程(转)

linux是如何组成的?答:linux是由用户空间和内核空间组成的为什么要划分用户空间和内核空间?答:有关CPU体系结构,各处理器可以有多种模式,而LInux这样的划分是考虑到系统的安全性,比如X86可以有4种模式RING0~RING3  RING0特权模式给LINUX内核空间RING3给用户空间linux内核是如何组成的?答:linux内核由SCI(System Call Interface)系统调用接口.PM(Process Management)进程管理.MM(Memory Managem

C语言计算程序中某一个函数或算法的执行时间

计算程序中某一个函数或算法的执行时间 #include <stdio.h> #include <time.h> #include <stdlib.h> int main() { long i = 10000000L; clock_t start, finish; double duration; printf( "Time to do %ld empty loops is ", i) ; start = clock(); while( i-- );

Linux内核启动

Linux内核启动过程概述 Linux的启动代码真的挺大,从汇编到C,从Makefile到LDS文件,需要理解的东西很多.毕竟Linux内核是由很多人,花费了巨大的时间和精力写出来的.而且直到现在,这个世界上仍然有成千上万的程序员在不断完善Linux内核的代码.今天我们主要讲解的是Linux-2.6.22.6这个内核版本.说句实话,博主也不确定自己能够讲好今天这个题目,因为这个题目太大太难.但是博主有信心,将自己学会的内容清楚地告诉大家,希望大家也能够有所收获. 1.启动文件head.S和hea