首页 > 其他分享 >内核初始化的过程

内核初始化的过程

时间:2023-10-20 23:33:45浏览次数:27  
标签:初始化 调用 kernel 文件系统 init task 内核 过程

内核的启动从入口函数 start_kernel() 开始。在 init/main.c 文件中,start_kernel 相当于内核的 main 函数。打开这个函数,你会发现,里面是各种各样初始化函数 XXXX_init。

内核初始化的过程_Linux

在操作系统里面,先要有个创始进程,有一行指令 set_task_stack_end_magic(&init_task)。这里面有一个参数 init_task,它的定义是 struct task_struct init_task = INIT_TASK(init_task)。它是系统创建的第一个进程,我们称为 0 号进程。这是唯一一个没有通过 fork 或者 kernel_thread 产生的进程,是进程列表的第一个。

第二个要初始化的就是办事大厅。有了办事大厅,我们就可以响应客户的需求。

这里面对应的函数是 trap_init(),里面设置了很多中断门(Interrupt Gate),用于处理各种中断。其中有一个 set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_32),这是系统调用的中断门。系统调用也是通过发送中断的方式进行的。

接下来要初始化的是咱们的会议室管理系统。对应的,mm_init() 就是用来初始化内存管理模块。

项目需要项目管理进行调度,需要执行一定的调度策略。sched_init() 就是用于初始化调度模块。

vfs_caches_init() 会用来初始化基于内存的文件系统 rootfs。在这个函数里面,会调用 mnt_init()->init_rootfs()。这里面有一行代码,register_filesystem(&rootfs_fs_type)。在 VFS 虚拟文件系统里面注册了一种类型,我们定义为 struct file_system_type rootfs_fs_type。

文件系统是我们的项目资料库,为了兼容各种各样的文件系统,我们需要将文件的相关数据结构和操作抽象出来,形成一个抽象层对上提供统一的接口,这个抽象层就是 VFS(Virtual File System),虚拟文件系统。

最后,start_kernel() 调用的是 rest_init(),用来做其他方面的初始化,这里面做了好多的工作。

rest_init 的第一大工作是,用 kernel_thread(kernel_init, NULL, CLONE_FS) 创建第二个进程,这个是 1 号进程。

1 号进程对于操作系统来讲,有“划时代”的意义。因为它将运行一个用户进程,x86 提供了分层的权限机制,把区域分成了四个 Ring,越往里权限越高,越往外权限越低。

内核初始化的过程_Linux_02

操作系统很好地利用了这个机制,将能够访问关键资源的代码放在 Ring0,我们称为内核态(Kernel Mode);将普通的程序代码放在 Ring3,我们称为用户态(User Mode)。

当一个用户态的程序运行到一半,要访问一个核心资源,例如访问网卡发一个网络包,就需要暂停当前的运行,调用系统调用,接下来就轮到内核中的代码运行了。

首先,内核将从系统调用传过来的包,在网卡上排队,轮到的时候就发送。发送完了,系统调用就结束了,返回用户态,让暂停运行的程序接着运行。

内核初始化的过程_Linux_03

这个过程就是这样的:用户态 - 系统调用 - 保存寄存器 - 内核态执行系统调用 - 恢复寄存器 - 返回用户态,然后接着运行。

内核初始化的过程_Linux_04

内存访问是不需要驱动的,这个就是 ramdisk。这个时候,ramdisk 是根文件系统。

然后,我们开始运行 ramdisk 上的 /init。等它运行完了就已经在用户态了。/init 这个程序会先根据存储系统的类型加载驱动,有了驱动就可以设置真正的根文件系统了。有了真正的根文件系统,ramdisk 上的 /init 会启动文件系统上的 init。

接下来就是各种系统的初始化。启动系统的服务,启动控制台,用户就可以登录进来了。

内核初始化的过程_Linux_05

标签:初始化,调用,kernel,文件系统,init,task,内核,过程
From: https://blog.51cto.com/key3feng/7960424

相关文章

  • Go包介绍与初始化:搞清Go程序的执行次序
    Go包介绍与初始化:搞清Go程序的执行次序目录Go包介绍与初始化:搞清Go程序的执行次序一、main.main函数:Go应用的入口函数1.1main.main函数1.2main.main函数特点二、包介绍2.1包介绍与声明2.2非main包的main函数2.3包的命名规则三、包的导入3.1包的导入介绍3.2导入多个......
  • 软件测试过程中如何有效的开展接口自动化测试
    一.简介接口自动化测试是指使用自动化测试工具和脚本对软件系统中的接口进行测试的过程。其目的是在软件开发过程中,通过对接口的自动化测试来提高测试效率和测试质量,减少人工测试的工作量和测试成本,并且能够快速发现和修复接口错误,确保软件系统的稳定性和可靠性。接口自动化测试......
  • 使用Grafana监控Nacos的简单过程
    使用Grafana监控Nacos的简单过程背景与kafka一样,想同期监控一下nacos.发现nacos跟minio等一样都有对应的metrics的暴露接口.所以这边简单使用一下.studyFromhttps://blog.csdn.net/qq_30718137/article/details/117471732https://grafana.com/grafana/dashboards/132......
  • 内核编译obj-m和obj-y的区别
    在内核编译时,主要涉及一下文件:kernel/arch/arm/configs/*.defconfigkernel/driver/*/Makefilekernel/driver/*/Kconfig如果我们想要往内核中增加新的节点,还要涉及到设备树文件,kernel/arch/arm/boot/dts/在进行模块编译时,主要有两个选项,obj-m和obj-y,而与内核密切相关的是obj-y......
  • 【Linux驱动】内核模块编译 —— make modules 的使用(单模块编译、多模块编译)
    编译驱动一般采用的是将驱动编译成模块(.ko文件),然后加载到内核,这其中就用到了makemodules命令。目录一、单模块编译1、一个c文件编译成一个ko文件2、多个文件编译成一个ko文件二、多模块编译(多文件多模块)一、单模块编译1、一个c文件编译成一个ko文件下面是最简......
  • 《Linux内核完全注释》(1)
    1概述1.1Linux发展1.1.1UnixUnix诞生于1969年,1972年用C语言进行改写,使其能够广泛推广。1.1.2Minix基于Unix,一群老师研发了minix用于教学,但是由于不开源,功能也不够,只够用于教学。这激发了Linus开发了Linux操作系统。1.1.3GNU计划在1984年,为了推广开源操作系统,让大家都......
  • 使用Grafana + jmx 监控 kafka3.5 的过程
    使用Grafana+jmx监控kafka3.5的过程摘要周五一边进行数据库监控,同时想着部署一套监控系统.能够监控一下kafka等中间件结果不想自己遇到了很多坑.下午有同事语音告诉自己一些排查问题的方式与方法.自己又多花了半个小时才将数据捞出来.感觉自己对很多工具的使用还......
  • 软件研发流程、架构规范、技术标准、需求过程等全文档
    前言:软件项目管理全文档包括以下几个方面:需求分析、项目规划、过程管理、测试和部署。全文档获取:Q+:262086839例图在文末。正文:一、需求分析是软件项目管理的第一步,也是非常关键的一步。在需求分析阶段,项目团队需要与用户进行深入沟通,了解用户的需求和期望,并对其进行详细的分......
  • Eplan API 初始化
    Eplan支持的开发方式一共有3种脚本dll文件形式exe离线程式形式虽然eplan二次开发也支持vb语言,但这里只讨论c#脚本(script)Eplan脚本支持的功能有限,有限的原因在于其支持的程序集有限c#中的System;System.XML;System.Drawing;System.Windows.FormsEpalnAPI中的Names......
  • Grafana监控OracleDB的完整过程
    背景两年前曾经写过一个进行Oracle监控的简单blog但是周天晚上尝试进行处理时发现很不完整了.很多数据获取不到.晚上又熬夜了好久进行处理.感觉还是需要总结一下,不然就忘记了获取镜像还是使用docker的方式来暴露Oracle的服务使用的镜像为:dockerpullghcr.io/iamseth/or......