首页 > 系统相关 >linux启动流程

linux启动流程

时间:2024-09-06 09:24:36浏览次数:7  
标签:do populate 启动 kernel bus 流程 init linux device

  1. KASLR kernel address space layout randomization 内核地址空间布局随机化
    本质是将链接的地址做了随机偏移,这样System.map中的地址也不一样了,需要用 cat /proc/kallsyms才能查看到实际的地址。主要还是为了安全,这样地址布局随机化,来增加安全,被攻击的难度会增加。
  • 防止利用内核漏洞。由于struct等数据结构会产生内核漏洞,通过随机化的方式将这些地址随机,这样攻击者就难以定位。
  • 提高安全性。每次引导得到的内核和内存地址都不用,即使得到上一次的内存布局,下一次就不再有效。
  • 减少信息泄露的影响

通过 CONFIG_RANDOMIZE_BASE 开启

启动流程

设备树加载与解析

设备树最开始在Image末尾,由uboot加载到.init.data中,存在的地址相当于物理地址。

start_kernel-> 
	setup_arch-> (对架构进行解析、包括设备树)
		setup_machine_fdt 
			(本函数得到在.init.data中地址(物理地址)转换后的虚拟地址)
		unflatten_device_tree->
			__unflatten_device_tree->
				unflatten_gt_nodes
					(执行两次,第一次得到转换成struct device_node所需要的空间后,分配内存。第二次真正开始解析设备树节点。)

unflatten_dt_nodes
从根节点开始:

  1. fdt_next_node 找下一个节点
  2. populate_node 为当前节点申请空间,并对node进行初始化,并且根据内容进行填充
  3. 会对深度进行设置从而得到父子关系

各个子系统初始化

子系统初始化和设备的初始化,都在最后一步rest_init中的do_initcalls中

rest_init->
	user_mode_thread(kernel_init, NULL, CLONE_FS)-> (开启0号进程)
		kernel_init->
			kernel_init_freeable->
				do_basic_setup->
					do_initcalls

顺便说一下,kernel_init中,会执行1号进程,首先判断是不是ramdisk(/init),其次会检查传入的命令中指定的1号进程,最后会依次判断 "/sbin/init" "/etc/init" "/bin/init" "/bin/sh"

do_initcalls中会从level0依次执行各种初始化函数。

其中 宏定义__define_initcall(fn, id)会将函数指针fn放在section段 .initcall##id.init,通过段名设置优先级(各个段依次执行)。

这样就可以回答下面几个问题

  1. 设备什么时候开始注册
    注册函数 of_platform_default_populate_init被放到了 .init.text中,被定义到 .initcall3s中(arch_initcall_sync(of_platform_default_populate_init))

所以在执行 do_initcalls 就会执行到of_platform_default_populate_init进行设备的注册

of_platform_default_populate_init->
	of_platform_default_populate->
		of_platform_populate->
			(从根节点开始遍历所有节点)
			of_platform_bus_create->
				of_device_alloc
				dev->dev.bus = &platform_bus_type
				of_device_add->
					device_add
  1. 各个子系统的注册
    会通过 __define_initcall(fn,id) 注册到段中,依次注册

  2. Bus的初始化流程

同样注册也是在 rest_init中执行

rest_init->
	kernel_init->
		kernel_init_freeable->
			do_basic_setup->
				driver_init->
					devices_init->
						devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
						(在/sys/下创建device)
						dev_kobj = kobject_create_and_add("dev", NULL)
						(在sys/下创建dev)
					buses_init->
						bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL)
						(在sys/下创建bus kset)
					classes_init->
						class_kset = kset_create_and_add("class", NULL, NULL);
						(在sys/下创建class kset)
					platform_bus_init->
						device_register
						bus_register 
						(注册总线)
				do_initcalls

device和driver匹配流程


总的来说,总线将设备树中的设备描述(device)与驱动文件(driver)统一管理,并且总线提供了match函数,用来将device与driver匹配上,然后调用driver的probe进行初始化

  1. 设备和驱动在注册到bus管理的链表中的时候都会去遍历匹配对应的驱动或者设备。
  2. 几种匹配
    1. pdev中dirver_override和drv的name匹配
    2. of_driver_match_device(设备树匹配)
    3. acpi_driver_match_device(acpi匹配)
    4. id_table匹配
    5. pdev和drv中name匹配

文件系统挂载

start_kernel
	>vfs_caches_init(fs/dcache.c)
	初始化根目录/
	>mnt_init((fs/namespace.c))
		>sysfs_init(fs/sysfs/mount.c)注册sysfs文件系统(创建根目录,注册到全局链表file_system中)
		>fs_kobj = kobject_create_and_add("fs", NULL);在sys/下创建fs kobject
		>shmem_init(mm/shmem.c)注册tmpfs文件系统
		>init_rootfs(init/do_mounts.c)
		>init_mount_tree(fs/namespace.c)
	>proc_root_init(fs/proc/root.c)注册proc文件系统
	>rest_init
		>kernel_init
			>kernel_init_freeable(init/main.c)
				>do_basic_setup
					>do_initcalls
						>core_initcall(debugfs_init)注册debugfs文件系统
						解压根文件系统
						>rootfs_initcall(populate_rootfs)(init/initramfs.c)
							>populate_rootfs(init/initramfs.c)
								>do_populate_rootfs(init/initramfs.c)解压cpio包
				>prepare_namespace(/init不存在等情况,initramfs不涉及)
			>run_init_process(ramdisk_execute_command)执行ramdisk_execute_command指定参数,即init=的值,默认为/init。调用进程会替换当前进程,执行成功不再返回

标签:do,populate,启动,kernel,bus,流程,init,linux,device
From: https://www.cnblogs.com/alanli07/p/18399618

相关文章

  • Linux在驱动里做定时循环
    1.使用内核定时器实现思路是,在驱动里使用一个内核定时器,定时一个时间后,执行回调函数,再在回调函数里重新设置一次定时时间,以此往复,在回调函数里里执行自己的业务Linux4.4内核/*一些变量*/#definePOLL_PERIOD(HZ/1)/*(HZ/100):Pollingperiod.01seconds(10ms)*......
  • 首发 最新AWVS/Acunetix Premium V24.8高级版漏洞扫描器(最新版)Windows/Linux下载
    前言AcunetixPremium是一种Web应用程序安全解决方案,用于管理多个网站、Web应用程序和API的安全。集成功能允许您自动化DevOps和问题管理基础架构。AcunetixPremium:全面的Web应用程序安全解决方案Web应用程序对于企业和组织与客户、合作伙伴和员工的联系至关重要。......
  • linux curl命令介绍以及使用
    文章目录`curl`简介`curl`的安装基本用法发送GET请求将响应内容保存到文件显示请求的头部信息发送POST请求上传文件携带请求头处理重定向通过代理发送请求下载文件指定请求的超时时间高级用法模拟浏览器行为保持会话(Cookie)验证HTTPS请求总结在Linux中,curl是一个......
  • Docker - 在Rockly Linux 9.4 上安装Docker-CE
    安装Docker-CE修改repo源修改为国内阿里源以提高安装速度sed-e's|^mirrorlist=|#mirrorlist=|g'\-e's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g'\-i.bak\/etc/yum.repos.d/rocky*.repo......
  • C++入门项目:Linux下C++轻量级Web服务器 跑通|运行|测试(小白进)
    TinyWebServer是一个开源的项目,适合小白入门C++网络编程,注意该项目是在linux系统下。Linux下C++轻量级Web服务器,助力初学者快速实践网络编程,搭建属于自己的服务器.使用线程池+非阻塞socket+epoll(ET和LT均实现)+事件处理(Reactor和Proactor均实现)的并发模型使用状......
  • Linux 系统的操作命令
    Author:ACatSmilingSince:2024-09-05文件与目录结构Linux系统中,一切皆文件。Linux目录结构:[zeloud@localhost~]$cd/[zeloud@localhost/]$lsbinbootdevetchomeliblib64mediamntoptprocrootrunsbinsrvsystmpusrvar/bin:存......
  • 三、搭建网站服务器超详细步骤——FinalShell下载安装使用流程(免费国产的SSH工具)+宝塔
    前言本篇博客是搭建网站服务器模块下的第3部分  FinalShell下载安装使用流程  在分享这篇博客之前,首先讲一下,FinalShell软件是干什么用的,用大白话进行说明一下:这个软件是一款远程控制和管理服务器的软件,通过SSH协议与远程服务器进行连接,去操控一系列的命令信息。就像......
  • Linux-目录结构和Vim编辑器
    目录Linux目录结构基本介绍​编辑具体的目录结构Vim编辑器vi和vim的基本介绍vi和vim常用的三种模式正常模式插入模式命令行模式各种模式的相互切换vim快捷键盘图粘贴与删除拷贝当前行并粘贴拷贝多行并粘贴删除当前行删除多行Vim的退出保存命令普通退出保存......
  • 《 Kali Linux 安装的具体步骤》
    以下是KaliLinux安装的具体步骤: 准备工作: 1. 下载KaliLinux镜像:从官方网站(https://www.kali.org/downloads/)下载适合您的版本(如64位)的ISO镜像文件。2. 准备安装介质:您可以选择将镜像写入U盘(使用Rufus等工具)或者刻录到DVD光盘。3. 备份重要数据:安装......
  • 【操作系统存储篇】Linux文件基本操作
    目录一、Linux目录二、Linux文件的常用操作三、Linux文件类型一、Linux目录Linux有很多目录,Linux一切皆是文件,包括进程、设备等。相对路径:相对于当前的操作目录,文件位于哪个目录。绝对路径:从根目录开始的路径。二、Linux文件的常用操作touch:创建文件; vim:创建或......