前面我们了解到了0号进程是系统所有进程的先祖, 它的进程描述符init_task是内核静态创建的, 而它在进行初始化的时候, 通过kernel_thread的方式创建了两个内核线程,分别是kernel_init和kthreadd,其中kernel_init进程号为1 start_kernel在其最后一个函数rest_init的调用中,会通过kernel
如kernel将初始化要执行的init函数,分为7个级别,core_initcall, postcore_initcall, arch_initcall, subsys_initcall, fs_iitcall, device_initcall,late_initcall。这7个级别优先级递减,即先执行core_initcall, 最后执行late_initcall。通过使用文中提到的宏,gcc会将初始化代码按下面的结构安排: 在内核初始化...
kernel_init函数在内核态运行,是内核代码 init进程是内核启动并运行的第一个用户进程,运行在用户态下。 一号内核进程调用execve()从文件/etc/inittab中加载可执行程序init并执行,这个过程并没有使用调用do_fork(),因此两个进程都是1号进程。 当内核启动了自己之后(已被装入内存、已经开始运行、已经初始化了所有的...
打开Linux Kernel源代码树中的文件:include/init.h,可以看到有下面的宏定议: #define__init __attribute__ ((__section__ (".init.text"))) __cold#define__initdata __attribute__ (( __section__ (".init.data")))#define__exitdata __attribute__ (( __section__ (".exit.data")))#defin...
static int __ref kernel_init(void *unused) { kernel_init_freeable(); ... } init/main.c static noinline void __init kernel_init_freeable(void) { ... do_basic_setup(); ... } init/main.c static void __init do_basic_setup(void) { ...
打开Linux Kernel源代码树中的文件:include/init.h,可以看到有下面的宏定议: #define __init __attribute__ ((__section__ (".init.text"))) __cold #define __initdata __attribute__ (( __section__ (".init.data"))) #define __exitdata __attribute__ (( __section__ (".exit.data")...
在ramdisk环境下创建init进程时,需要在kernel CMDLINE中设置init程序的路径位置,如下所示: CONFIG_CMDLINE="...root=/dev/ram rdinit=/sbin/init..." 1. 在kernel代码中通过rdinit_setup()解析kernel CMDLINE中rdinit=字符串,赋值给全局...
其中,init.h 定义了驱动的初始化和退出相关的函数,kernel.h 定义了经常用到的函数原型及宏定义,module.h 定义了内核模块相关的函数、变量及宏。 /include/linux) 中)。没错,驱动的加载就靠它。为什么需要这样一个宏?原因是按照一般的编程想法,各部分的初始化函数会在一个固定的函数里调用比如: ...
代码这么修改,需要自动初始化函数的确是可以调到了,但是每次都写这么长长的一段static initcall_t __ attribute__(( __ used__,__ section__(".initcall.0.init"))),就是不舒服. linux kernel中通过宏来修改。 这个也一样。 添加 按照程序逻辑顺序执行的一些宏 ...
init/ --- Linux系统启动初始化相关的代码。 block/ --- 提供块设备的层次。 sound/ --- 音频相关的驱动及子系统,可以看作“音频子系统”。 drivers/ --- 设备驱动(在Linux kernel 3.10中,设备驱动占了49.4的代码量)。 lib/ --- 实现需要在内核中使用的库函数,例如CRC、FIFO、list、MD5等。 crypto/ ...