linux initcall

Initcall 的实现
initcall是内核提供的一种挂接机制,利用这种机制可以让内核在特定的时刻调用自己,例如,某些驱动程序就有这种需要。

typedef int (*initcall_t)(void);
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn
level的合理取值为0-7,0s-7s(2.6.19.2)
数值小的将排在前面,相同数值的s排在非s后面
/*
* A "pure" initcall has no dependencies on anything else, and purely
* initializes variables that couldn't be statically initialized.
*
* This only exists for built-in code, not for modules.
*/
#define pure_initcall(fn) __define_initcall("0",fn,1)
#define core_initcall(fn) __define_initcall("1",fn,1)
#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
#define postcore_initcall(fn) __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
#define arch_initcall(fn) __define_initcall("3",fn,3)
#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
#define subsys_initcall(fn) __define_initcall("4",fn,4)
#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
#define fs_initcall(fn) __define_initcall("5",fn,5)
#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
#define late_initcall(fn) __define_initcall("7",fn,7)
#define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
内核调用链
start_kernel -> rest_init -> init -> do_basic_setup -> do_initcalls
1,所有可以initcall的函数都必须符合下面形式
int foo(void);
2,__define_initcall宏导出函数到内核映像的.initcalln.init段
__define_initcall("1",foo,1)或core_initcall(foo)
展开后形成如下申明
static initcall_t __initcall_foo1 __attribute_used__
__attribute__((__section__(".initcall1.init"))) = foo;
所有的申明形成一个initcall_t数组
3,内核在do_initcalls函数中历遍该数组
static void __init do_initcalls(void)
{
...
for (call = __initcall_start; call < __initcall_end; call++) { ...
//对启动参数initcall_debug的支持
if (initcall_debug) {
printk("Calling initcall 0x%p", *call);
print_fn_descriptor_symbol(": %s()",
(unsigned long) *call);
printk("\n");
}
result = (*call)();
...
}
}
4,驱动中用到的重要申明module_init(x)实际就是initcall的特化: #define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6)。

合集下载

Linux终端中的系统启动和关机命令

Linux终端中的系统启动和关机命令

Linux终端中的系统启动和关机命令Linux作为一个开源的操作系统,具有强大的灵活性和自定义性。

在Linux终端中,我们可以使用一些命令来控制系统的启动和关机。

本文将详细介绍一些常用的系统启动和关机命令,并探讨它们的功能和使用方法。

一、系统启动命令1. rebootreboot命令用于重新启动系统。

在终端中输入reboot后,系统将会立即重启。

这个命令非常有用,尤其是在需要迅速重启系统的情况下,如在安装软件或更新内核后。

2. shutdownshutdown命令用于正常关机系统。

默认情况下,输入shutdown命令后系统将在一分钟后执行关机操作。

如果需要设置关机时间,可以使用“shutdown -h now”命令来立即关机,或者使用“shutdown -h +分钟数”命令来设置延迟关机的时间。

除了关机命令,shutdown还可以用于重启系统。

例如,使用“shutdown -r now”命令将会立即重启系统。

3. initinit命令是Linux系统的初始化命令,用于切换系统的运行级别。

运行级别是电脑中一种特定的工作状态,对应着一组特定的功能服务。

Linux系统共有七个运行级别,分别是0-6。

其中,0表示关机,6表示重启。

要切换运行级别,可以使用“init 数字”命令进行操作。

例如,“init 3”将将系统切换到文本模式,而“init 5”则进入图形模式。

二、系统关机命令1. halthalt命令用于立即关机系统。

它会发送一个信号给内核,告诉系统立即关闭。

输入“halt”命令后,系统将会停止所有进程并关机。

2. poweroffpoweroff命令用于正常关机系统。

它会先发送一个信号给所有运行的进程,告诉它们系统即将关机。

这个命令会在关机前允许进程的保存和关闭操作,确保数据的完整性。

3. init在上一节中我们已经介绍了init命令的用途。

当我们使用“init 0”或“init 6”命令时,系统将会执行关机或重启操作。

嵌入式linux系统的启动流程

嵌入式linux系统的启动流程

嵌入式linux系统的启动流程
嵌入式Linux系统的启动流程一般包括以下几个步骤:
1.硬件初始化:首先会对硬件进行初始化,例如设置时钟、中
断控制等。

这一步骤通常是由硬件自身进行初始化,也受到系统的BIOS或Bootloader的控制。

2.Bootloader引导:接下来,系统会从存储介质(如闪存、SD
卡等)的Bootloader区域读取引导程序。

Bootloader是一段程序,可以从存储介质中加载内核镜像和根文件系统,它负责进行硬件初始化、进行引导选项的选择,以及加载内核到内存中。

3.Linux内核加载:Bootloader会将内核镜像从存储介质中加载到系统内存中。

内核镜像是包含操作系统核心的一个二进制文件,它由开发者编译并与设备硬件特定的驱动程序进行连接。

4.内核初始化:一旦内核被加载到内存中,系统会进入内核初
始化阶段。

在这个阶段,内核会初始化设备驱动程序、文件系统、网络协议栈等系统核心。

5.启动用户空间:在内核初始化完毕后,系统将启动第一个用
户空间进程(init进程)。

init进程会读取并解析配置文件(如
/etc/inittab)来决定如何启动其他系统服务和应用程序。

6.启动其他系统服务和应用程序:在用户空间启动后,init进
程会根据配置文件启动其他系统服务和应用程序。

这些服务和应用程序通常运行在用户空间,提供各种功能和服务。

以上是嵌入式Linux系统的基本启动流程,不同的嵌入式系统可能会有一些差异。

同时,一些特定的系统也可以添加其他的启动流程步骤,如初始化设备树、加载设备固件文件等。

Linux内核中系统调用详解

Linux内核中系统调用详解

Linux内核中系统调用详解什么是系统调用?(Linux)内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。

用户可以通过系统调用命令在自己的应用程序中调用它们。

从某种角度来看,系统调用和普通的函数调用非常相似。

区别仅仅在于,系统调用由(操作系统)核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。

随Linux核心还提供了一些(C语言)函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统调用。

为什么要用系统调用?实际上,很多已经被我们习以为常的C语言标准函数,在Linux 平台上的实现都是靠系统调用完成的,所以如果想对系统底层的原理作深入的了解,掌握各种系统调用是初步的要求。

进一步,若想成为一名Linux下(编程)高手,也就是我们常说的Hacker,其标志之一也是能对各种系统调用有透彻的了解。

即使除去上面的原因,在平常的编程中你也会发现,在很多情况下,系统调用是实现你的想法的简洁有效的途径,所以有可能的话应该尽量多掌握一些系统调用,这会对你的程序设计过程带来意想不到的帮助。

系统调用是怎么工作的?一般的,进程是不能访问内核的。

它不能访问内核所占内存空间也不能调用内核函数。

(CPU)(硬件)决定了这些(这就是为什么它被称作"保护模式")。

系统调用是这些规则的一个例外。

其原理是进程先用适当的值填充(寄存器),然后调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置(当然,这个位置是用户进程可读但是不可写的)。

在(Intel)CPU中,这个由中断0x80实现。

硬件知道一旦你跳到这个位置,你就不是在限制模式下运行的用户,而是作为操作系统的内核--所以你就可以为所欲为。

进程可以跳转到的内核位置叫做sysem_call。

这个过程检查系统调用号,这个号码告诉内核进程请求哪种服务。

然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。

arm版本linux系统的启动流程

arm版本linux系统的启动流程

arm版本linux系统的启动流程ARM架构是一种常见的处理器架构,被广泛应用于嵌入式设备和移动设备中。

在ARM版本的Linux系统中,启动流程是非常重要的,它决定了系统如何从开机到正常运行。

本文将详细介绍ARM版本Linux系统的启动流程。

一、引导加载程序(Bootloader)引导加载程序是系统启动的第一阶段,它位于系统的固化存储器中,比如ROM或Flash。

在ARM版本的Linux系统中,常用的引导加载程序有U-Boot和GRUB等。

引导加载程序的主要功能是加载内核镜像到内存中,并将控制权转交给内核。

二、内核初始化引导加载程序将内核镜像加载到内存后,控制权被转交给内核。

内核初始化是系统启动的第二阶段,它主要完成以下几个步骤:1. 设置异常向量表:ARM架构中,异常是指硬件产生的中断或故障,比如系统调用、中断请求等。

内核需要设置异常向量表,以便正确处理异常。

2. 初始化处理器:内核对处理器进行初始化,包括设置页表、启用缓存、初始化中断控制器等。

3. 启动第一个进程:内核创建第一个用户进程(一般是init进程),并将控制权转交给它。

init进程是系统中所有其他进程的父进程,负责系统的初始化工作。

三、设备树(Device Tree)设备树是ARM版本Linux系统中的一种机制,用于描述硬件设备的相关信息。

在内核初始化过程中,内核会解析设备树,并建立设备树对象,以便后续的设备驱动程序使用。

设备树描述了硬件设备的类型、地址、中断等信息,以及设备之间的连接关系。

它使得内核能够在运行时自动识别和配置硬件设备,大大提高了系统的可移植性和灵活性。

四、启动初始化(Init)启动初始化是系统启动的第三阶段,它是用户空间的第一个进程(init进程)接管系统控制权后的操作。

启动初始化主要完成以下几个任务:1. 挂载根文件系统:启动初始化会挂载根文件系统,使得用户可以访问文件系统中的文件和目录。

2. 加载系统服务:启动初始化会加载并启动系统服务,比如网络服务、日志服务、时间同步服务等。

嵌入式 Linux 启动时间优化

嵌入式 Linux 启动时间优化

嵌入式Linux 启动时间优化1 简介本章包含的话题有启动时间的测量、分析、人因工程(human factors)、初始化技术和优化技巧等。

产品花在启动方面的时间直接影响终端用户对该产品的第一印象。

一个消费电子设备不管如何引人注目或者设计得怎么好,设备从关机状态到可交互的使用状态所需的时间对于获得正面的用户体验尤为关键。

案例#1 就是在关机状态从头启动一个设备的例子。

启动一个设备涉及到许多步骤和一系列的事件。

为了使用前后一致的术语,消费电子Linux 论坛(CE Linux Forum)的启动时间优化工作组起草了一个术语词汇表,该表包括了相关术语在该领域内通用的定义。

该词汇表如下:启动时间相关的词汇表2 技术/项目主页下面主要介绍与减少Linux 启动时间有关的各种技术。

有一部分描述了 上可以下载的本地补丁,而其余部分则介绍了在其他地方维护的项目或者补丁。

2.1 测量启动时间Printk Times –用于显示每个printk 的执行时间内核函数跟踪(Ftrace)–用于报告内核中每个函数的调用时间Linux 跟踪工具箱(LTT)–用于报告确切的内核和进程事件的时间数据Oprofile(译注:最新替代品是perf)–通用的Linux 分析器(Profile)Bootchart –用于Linux 启动过程的性能分析和数据展示。

收集启动过程中的用户空间部分的资源使用情况和进程信息,然后渲染成PNG、SVG 或者EPS 格式的图表。

Bootprobe –一组用于分析系统启动过程的System Tap 脚本当然,别忘了cat /proc/uptime (译注:统计系统已经运行的时间)grabserial –Tim Bird (译注:CE Linux Forum 主席)写的一个非常赞的工具用于记录控制台输出并打上时间戳进程跟踪–同样是Tim Bird 写的一个简单补丁,用于记录exec、fork 和exit 系统调用。

linux系统请求接口方法

linux系统请求接口方法

linux系统请求接口方法【1.Linux系统简介】Linux系统是一款开源的操作系统,广泛应用于服务器、嵌入式设备和超级计算机等领域。

它的安全性、稳定性和高性能等特点使其成为众多场景的首选操作系统。

在Linux系统中,请求接口方法是用户和操作系统内核进行交互的重要途径。

【2.请求接口的定义与作用】请求接口,又称系统调用,是用户程序和操作系统内核之间进行通信的一种方式。

通过请求接口,用户程序可以请求操作系统内核提供服务,如文件操作、进程管理、内存管理等。

请求接口的作用是将用户空间的请求传递给内核空间,并由内核来处理这些请求。

【3.Linux系统中的请求接口方法】3.1 系统调用在Linux系统中,用户程序通过系统调用向内核发起请求。

系统调用是操作系统提供的一组函数,它们在内核空间中有对应的实现。

用户程序通过调用这些函数,可以将请求传递给内核,并由内核来处理。

如open、close、read、write等文件操作系统调用。

3.2 应用程序接口(API)应用程序接口是一种更高级别的请求接口方式。

它提供了一组封装好的函数,供开发者调用。

API通常具有更好的可读性和可维护性,使得开发者可以更加专注于业务逻辑的实现。

在Linux系统中,有许多应用程序接口,如C库、Python库等。

3.3 信号处理信号处理是另一种在Linux系统中进行请求接口的方式。

当程序接收到特定的信号(如中断、异常等)时,可以进行相应的处理。

信号处理通常用于进程管理、错误处理等场景。

通过信号处理,程序可以对突发事件作出快速响应。

【4.请求接口实例】以一个简单的例子来说明请求接口的应用。

假设有一个程序需要读取文件内容,可以使用系统调用read来实现。

以下是一个简单的C代码示例:```c#include <stdio.h>#include <unistd.h>int main() {int fd = open("example.txt", O_RDONLY);if (fd < 0) {perror("open");return 1;}char buffer[1024];ssize_t bytes_read = read(fd, buffer, sizeof(buffer));if (bytes_read < 0) {perror("read");close(fd);return 1;}printf("File content: %s", buffer);close(fd);return 0;}```在这个示例中,我们使用了系统调用open、read和close来完成文件操作。

linux下module_init,module_exit解读

linux下module_init,module_exit解读linux下module_init,module_exit 解读linux 内核通常包含3个头⽂件:●Init.h //驱动初始化与退出相关函数●Module.h //内核模块相关函数,变量,以及宏●Kernel.h //函数原型已经宏定义_initlist 对应⼀个initlist结构体变量存放在initlist 区段,即在改区段可以找到所有初始化函数的指针。

initlist 区段地址:_initlist_start , initlist_end 两个变量来标识,既可以通过这2个变量来访问所有初始化函数的指针。

我们平时的驱动初始化函数与退出函数,⽆需固定地址,其实有连接器帮助我们把驱动初始化函数与退出函数固定好位置。

如何存放呢?我们来看下module_init(x)宏定义:__section__()函数作⽤:告诉连接器,变量存放在initlist区段__initlist_func_6 : 加载到内核映像的initcall区段,这⾥的6表⽰加载优先级.,内核加载时,会搜索“。

initcall”中所有条⽬,并按照有优先级加载。

数值越⼩,加载优先级越⾼,数值为0,优先级最⾼。

Module_init()作⽤:●初始化加载●后期内存释放即Linux→kernel →device’s driver code 中得初始化函数与反初始化函数代码所含内存,是可以被释放的只需要初始化⼀次的函数,都附上了_init属性__init 宏// 如果这个模块需要编译,则把这个函数放到.init.text区段Module_eixt(func)功能类似,忽略清理函数,因为内核模块不需要清理。

具体的函数执⾏流程:最终调⽤如下函数,释放initlist区段。

参考⽂档:《/doc/48d3e725bcd126fff7050b66.html /view/c9a1b2e9172ded630b1cb66d.html》。

linux系统初始化脚本init.rc的语法介绍

Android初始化语言包含了四种类型的声明:Actions(行动)、Commands(命令)、Services(服务)和Options(选项)。

所有这些都是以行为单位的,各种记号由空格来隔开。

C语言风格的反斜杠号可用于在记号间插入空格。

双引号也可用于防止字符串被空格分割成多个记号。

行末的反斜杠用于折行。

注释行以井号(#)开头(允许以空格开头)。

Actions和Services声明一个新的分组。

所有的命令或选项都属于最近申明的分组。

位于第一个分组之前的命令或选项将会被忽略。

Actions和Services有唯一的名字。

如果有重名的情况,第二个申明的将会被作为错误忽略。

(???我们是否应该以覆盖来代替忽略) Actions(行动) ---------- Actions其实就是一序列的Commands(命令)。

Actions都有一个trigger(触发器),它被用于决定action的执行时间。

当一个符合action触发条件的事件发生时,action会被加入到执行队列的末尾,除非它已经在队列里了。

队列中的每一个action都被依次提取出,而这个action中的每个command(命令)都将被依次执行。

Init在这些命令的执行期间还控制着其他的活动(设备节点的创建和注销、属性的设置、进程的重启)。

Actions的形式如下: on 《trigger》 《command》 《command》 《command》 Services(服务) ---------- Services(服务)是一个程序,他在初始化时启动,并在退出时重启(可选)。

Services(服务)的形式如下: service 《name》《pathname》 [ 《argument》 ]* 《option》 《option》 ... Options(选项) ---------- Options(选项)是一个Services(服务)的修正者。

linux中init命令的详细解释

linux中init命令的详细解释linxu下的init命令是进程初始化工具。

下面由店铺为大家整理了linux的init命令的详细解释的相关知识,希望对大家有帮助!一、linux中的init命令的详细解释init命令init命令是Linux下的进程初始化工具,init进程是所有Linux的进程的父进程,它的进程号为1。

init命令是Linux操作系统中不可缺少的程序之一,init进程是Linux内核引导运行的,是系统中的第一个进程。

语法init(选项)(参数)选项-b:不执行相关脚本而直接进入单用户模式;-s:切换到单用户模式。

参数运行等级:指定Linux系统要切换到的运行等级。

二、linux中的init命令的详解实例几个常用的命令查看系统进程命令:ps -ef | head查看init的配置文件:more /etc/inittab查看系统当前运行的级别:runlevel运行级别到底什么是运行级呢?简单的说,运行级就是操作系统当前正在运行的功能级别。

这个级别从0到6 ,具有不同的功能。

你也可以在/etc/inittab中查看它的英文介绍。

#0 停机(千万不能把initdefault 设置为0)#1 单用户模式#2 多用户,没有 NFS(和级别3相似,会停止部分服务)#3 完全多用户模式#4 没有用到#5 x11(Xwindow)#6 重新启动(千万不要把initdefault 设置为6)三、linux的init命令的六种模式简介6种模式中有两种是系统内定的:0:停止系统运行。

init 0〈回车〉相当于 halt〈回车〉。

6:重启系统。

init 6〈回车〉相当于 reboot〈回车〉。

如果你了解/etc/inittab文件,就千万不要把0设为缺省登录模式,否则你的Linux的运行就只能两点一线了&mdash;&mdash;开机&larr;&rarr;停机,或者是开机&larr;&rarr;重启的无限循环。

文件系统加载过程

linux文件系统初始化过程(1)---概述术语表:struct task:进程struct mnt_namespace:命名空间struct mount:挂载点struct vfsmount:挂载项struct file:文件struct super_block:超级块struct dentry:目录struct inode:索引节点一、目的linux文件系统主要分为三个部分:文件系统调用;虚拟文件系统(VFS);挂载到VFS 的实际文件系统。

其中,VFS是核心,linux文件系统的本质就是在内存中创建一棵VFS树。

当根目录被创建后,用户就可以使用系统调用在VFS上创建文件、删除文件、挂载各种文件系统等操作。

该系列文章主要分析linux3.10文件系统初始化过程,分为三个阶段:1、挂载根文件系统(rootfs);2、加载initrd;3、挂载磁盘文件系统;二、常用数据结构linux文件系统中重要的数据结构有:文件、挂载点、超级块、目录项、索引节点等。

每个数据结构的具体实现请参见源代码,这里不再描述。

为了直观的表示数据结构之间的关系,请参见图1:图中含有两个文件系统(红色和绿色表示的部分),并且绿色文件系统挂载在红色文件系统tmp目录下。

一般来说,每个文件系统在VFS层都是由挂载点、超级块、目录和索引节点组成;当挂载一个文件系统时,实际也就是创建这四个数据结构的过程,因此这四个数据结构的地位很重要,关系也很紧密。

由于VFS要求实际的文件系统必须提供以上数据结构,所以不同的文件系统在VFS层可以互相访问。

如果进程打开了某个文件,还会创建file(文件)数据结构,这样进程就可以通过file来访问VFS的文件系统了。

另外,该图只给出了主要的关系结构,忽略了部分细节。

图1三、函数调用关系图2描述了文件系统初始化过程中主要的函数调用关系。

linux文件系统初始化过程主要分为三个阶段:1、vfs_caches_init()负责挂载rootfs文件系统,并创建了第一个挂载点目录:'/';2、rest_init()负责加载initrd文件,扩展VFS树,创建基本的文件系统目录拓扑;3、init程序负责挂载磁盘文件系统,并将文件系统的根目录从rootfs切换到磁盘文件系统;图2四、总结linux文件系统初始化过程主要分为三个阶段:挂载rootfs,提供第一个挂载点''/;加载initrd,扩展VFS树;执行init程序,完成linux系统的初始化。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档