- 2025-02-15
-
发表了主题帖:
《Linux内核深度解析》- 第六章 文件系统
在Linux系统中,一切皆文件,目录、设备、套接字和管道等都是文件。
文件系统充当着类似数据管家的作用:管理磁盘上的数据。主要承担着管理数据放在磁盘的位置,提供快速找到某个文件方法,对文件操作的权限控制、日志记录、防止崩溃丢数据等。
应用程序可以直接使用内核提供的系统调用访问文件,系统调用mount用来把文件系统挂载到某个目录下。常用操作接口:
1.open:打开文件
2.close:关闭文件
3.read:读文件
4.write:写文件
5.lseek:设置文件偏移
文件系统通过“三层目录结构”管理文件:
1.超级块(Superblock)
记录整个文件系统的信息:磁盘总大小、空闲空间、文件系统类型、日志信息。
2.Inode(索引节点)
每个文件/目录对应一个唯一的 inode,相当于书的“身份证”,记录着文件权限,文件大小、创建时间及数据块地址。
3.目录项(Dentry)
目录的本质是一个“映射表”,例如:
文件名 cat.jpg → 对应的 inode 编号。
通过目录层级(如 /home/user/photos)组织文件路径。
文件系统工作流程大体有以下步骤,如果应用程序要读取 /user/data/log.txt 为例:
解析路径:从根目录 / 开始,逐级查找 user→data→log.txt 的 inode。
权限检查:内核检查当前用户是否有权访问 log.txt 的 inode。
读取数据:根据 inode 中的“数据块地址”,从磁盘读取文件内容到内存。
返回结果:将文件内容传给应用程序。
常见的文件系统类型有:fat、ext4、ubi、ntfs等。nandflash适用于fat、ubi文件系统,emmc适用于ext4文件系统。U盘根据大小及使用场景可格式化成ntfs、fat16、fat32、exfat等文件系统。由于linux对ntfs的支持不是特别友好,常用ntfs-3g来对ntfs格式的块设备进行操作。
-
发表了主题帖:
《Linux内核深度解析》- 第四章 中断、异常和系统调用
本帖最后由 大壮嘎嘎壮 于 2025-2-15 12:36 编辑
· 在arm64和MIPS等体系结构中,中断、系统调用和其他打断程序正常执行的事件被统称为异常。
一、异常
1.级别
以arm64处理器共有四个异常级别:0~3 数字越大,级别越高,权限越高。
异常级别0:用户模式。
异常级别1:内核模式。
异常级别2:基于内核的虚拟机KVM是内核的一个模块,直接在处理器上执行客户操作系统。在宿主操作系统的异常级别1和客户操作系统的异常级别1之间切换时,需要KVM陷入异常级别2。
异常级别3:arm64架构的安全扩展定义了两种安全状态:正常世界和安全世界。两个世界只能通过异常级别3的安全监控器切换。
2.分类
同步异常:系统调用、数据终止、指令终止、栈指针或指令地址未对齐、未定义指令、调试异常。
异步异常:中断、快速中断、系统错误。
3.处理
异常处理程序是内核中用于处理特定类型异常的函数。每个异常都有一个与之对应的处理程序。这些程序通常执行以下步骤:
(1)保存现场:
异常处理程序首先会保存被中断程序的执行环境,包括各种寄存器的值、堆栈指针等。这是为了确保在异常处理完成后能够恢复被中断程序的执行。
(2)确定异常类型:
根据异常向量表中的信息或异常处理程序的参数,确定异常的类型和原因。
(3)执行异常处理逻辑:
根据异常类型,执行相应的处理逻辑。这可能包括修复错误、记录日志、发送信号给进程等。
(4)恢复现场:
在异常处理完成后,恢复被中断程序的执行环境,包括恢复寄存器的值和堆栈指针。
(5)返回被中断的程序:
最后,异常处理程序会返回到被中断的程序继续执行。如果异常无法处理或导致内核崩溃,则系统可能会进入panic状态并重启。
还有一些对于特定类型的异常处理,内核可能有不同的处理策略。例如:
(1)页错误异常:
当进程访问未映射到物理地址的虚拟地址时,会触发页错误异常。内核会尝试分配新的页帧给进程,并更新页表以映射虚拟地址到物理地址。
(2)除法错误异常:
当进程执行除法运算且除数为零时,会触发除法错误异常。内核会向进程发送SIGFPE信号,通知其发生了浮点异常。
(3)系统调用异常:
当进程执行系统调用时,会触发系统调用异常。内核会根据系统调用号执行相应的系统调用服务函数。
二、中断
中断是外围设备通知处理器的一种机制。·
中断处理分为上半部和下半部,这应该是为了快速响应并减少中断屏蔽的时间。上半部处理紧急任务,然后下半部处理不那么紧急的部分。上半部是在中断上下文中执行,需要快速完成,而下半部可能用tasklet、软中断或者工作队列之类的机制延迟处理。当硬件触发中断,CPU保存现场,跳转到中断处理程序。上半部执行必要的操作,比如读取数据,然后登记下半部处理。下半部可能在稍后的时间执行,比如软中断在中断返回前处理,或者tasklet调度到软中断上下文中。工作队列则可能在内核线程中运行,可以睡眠。
三、系统调用
系统调用是内核给用户程序提供的变成接口,主要有以下特点:
权限隔离:用户程序无权直接操作硬件或内核资源,必须通过系统调用“敲门”,由内核代劳。
高效切换:通过软中断或专用指令,快速完成用户态和内核态的上下文切换。
统一接口:所有硬件操作(如读写文件、网络通信)都被抽象为系统调用,对用户程序透明。
大体流程如下:
1.用户程序发起请求
调用库函数(如 write()),库函数将参数和系统调用号(如 __NR_write)放入寄存器。
2.触发内核模式切换
通过软中断(如 int 0x80)或专用指令(如 syscall),CPU 从用户态切换到内核态。
3.内核处理请求
根据系统调用号,从内核的“系统调用表”中找到对应的处理函数(如 sys_write)。
验证参数合法性(如检查内存权限),执行实际操作(如写文件到磁盘)。
4.返回用户态
内核将结果(如成功写入的字节数或错误码)返回给用户程序,CPU 切换回用户态。
- 2025-01-20
-
加入了学习《自己动手写嵌入式操作系统》,观看 自己动手写操作系统
- 2025-01-19
-
发表了主题帖:
《Linux内核深度解析》初见 - 第一章 内核引导和初始化
本帖最后由 大壮嘎嘎壮 于 2025-1-19 17:26 编辑
.globl _start
_start:
岁聿云暮,一元复始,最近终于得空抽出时间来阅读这本《Linux内核深度解析》。
一、Boot阶段
在嵌入式系统中,BOOT(引导加载程序)扮演着至关重要的角色,它负责初始化硬件、加载操作系统内核或其他应用程序,并为系统的正常运行做好准备。
本文介绍的是嵌入式设备常用的U-Boot引导程序,U-Boot分为SPL和正常的U-Boot程序两部分。SPL(Secondary Program Loader)意为第二段程序加载器,明明作为引导程序首先出场的角色为什么要叫第二段呢,这个第二段是相对于固化在芯片内部的bootrom来说的。处理器启动时首先执行的是芯片内部固化的程序,固化程序加载SPL,SPL加载正常的U-Boot程序。由于芯片内部寸土寸金,片上内存比较小,所以才采用这种方式进行初始化内存和储存设备及一些外设,为内核的加载或者固件的更新下载做准备。Uboot最后调用boot_Jump_linux函数,跳转到linux内核。至此,uboot使命结束,CPU控制权交给内核。
二、Kernel阶段
1.初始化
内核初始化分为汇编语言和C语言部分。
汇编语言中主要执行了以下几个函数进行了一些基本的初始化流程:
(1)el2-setup:配置执行内核的异常级别。
(2)__create_page_tables:页表映射
(3)__primary_switch:开MMU
(4)__primary_switched:栈、异常向量表。数据段等初始化,调用start_kernel函数
内核初始化的C语言的入口函数是start_kernel函数,start_kernel函数的主要职责如下:
(1)设置页表和内存管理:
初始化页表,确保内核能够正确地管理内存。设置内存管理单元(MMU)的配置。
(2)初始化硬件:
初始化处理器和硬件架构相关的设置。设置中断和异常处理。
(3)内核数据结构初始化:
初始化各种内核数据结构,如调度器、进程控制块(task_struct)、内存管理等。
(4)设备驱动初始化:
初始化设备驱动框架,为内核支持的设备做好准备。
(5)文件系统初始化:
初始化虚拟文件系统(VFS)和根文件系统。
(6)启动内核线程:
启动内核守护进程和必要的内核线程,如 kswapd(内存回收守护进程)、kworker(工作线程)等。
(7)用户空间启动:
挂载根文件系统。启动第一个用户空间进程(通常是 init 进程)。
2.init进程
init进程是用户空间的第一个进程,主要有以下作用:
(1)启动系统服务:
init进程负责启动各种系统服务,如网络服务、打印服务等。这些服务通常通过运行级别(run levels)来管理,不同的运行级别对应不同的系统状态和服务组合。
(2)管理用户登录:
init进程还负责启动getty进程,用于用户登录。在系统完全启动后,init会为每个用户已退出的终端重启getty,以便下一个用户可以登录。
(3)处理孤儿进程:
当一个进程启动了一个子进程并且在子进程之前终止时,这个子进程会成为孤儿进程。init进程会接管这些孤儿进程,确保它们不会成为僵尸进程(zombie process)。
(4)系统初始化:
init进程还承担挂载文件系统、初始化属性系统和Klog、selinux的初始化等重要任务。它通过解析init.rc脚本来初始化系统daemon服务进程。
- 2024-12-11
-
回复了主题帖:
读书入围名单: 《Linux内核深度解析》
确认,可以完成阅读分享计划
- 2024-11-28
-
加入了学习《基于Arduino玩转pico RP2040》,观看 基于Arduino玩转pico RP2040