- 博客(153)
- 收藏
- 关注
原创 Linux之arm64 的ASID的管理
当系统发生进程切换,从进程A切换到进程B,从而导致地址空间也从A切换到B,这时候,我们可以认为在A进程执行过程中,所有TLB和Cache的数据都是for A进程的,一旦切换到B,整个地址空间都不一样了,因此需要全部flush掉(注意:我这里使用了linux内核的术语,flush就是意味着将TLB或者cache中的条目设置为无效,对于一个ARM平台上的嵌入式工程师,一般我们会更习惯使用invalidate这个术语,不管怎样,在本文中,flush等于invalidate)。
2025-11-28 16:08:39
903
原创 linux之ARM64的启动过程-多核启动(2)
1)cpu启动的含义:cpu可以从内存中取指、译码、执行,当然内存可以是soc片内的sram,也可以是ddr。2)我们要知道,程序为何可以在多个cpu上并发执行:他们有各自独立的一套寄存器,如:程序计数器pc,栈指针寄存器sp,通用寄存器等,可以独自 取指、译码、执行,当然内存和外设资源是共享的,多核环境下当访问临界区 资源一般 自旋锁来防止竞态发生。
2025-11-27 16:12:00
789
原创 linux之ARM64的启动过程-汇编阶段stext (1)
Linux kernel 的arm64 启动汇编阶段, 是主核启动kernel 的第一条指令所在。这里提到主核,就会有从核,下一篇文章介绍主核从核启动的顺序和区别。
2025-11-26 17:11:09
853
原创 Linux之网络子系统-硬件MAC和 phy 的基本组成原理
首先我们来说说以太网卡的MAC芯片的功能。以太网数据链路层其实包含MAC(介质访问控制)子层和LLC(逻辑链路控制)子层。一块以太网卡MAC芯片不但要实现MAC子层和LLC子层的功能,还要提供符合规范的PCI界面以实现和主机的数据交换。MAC从PCI总线(或者是AXI总线)收到IP数据包(或者其他网络层协议的数据包)后,将之拆分并重新打包成最大1518Byte,最小64Byte的帧。
2025-11-24 15:29:52
839
1
原创 linux之内存管理(8)-内存映射 mmap触发的缺页异常Page Fault(二)
综上所述,在调用mmap函数进行内存映射时,如果在flags参数中设置了或者MAP_LOCKED标志位,则表示需要马上为这块进程地址空间vma分配物理页并建立映射关系。此时,Linux内核依次扫描这段vma中的每一个虚拟页,并对每一个虚拟页触发缺页异常,从而为其立即分配物理内存,并建立虚拟页与物理页之间的映射关系,补齐进程的页表体系。本文分析的mmap内存映射所引起的缺页中断只是Linux内核缺页中断的一个分支,关于Linux内核详细的缺页中断流程,有机会再继续分析。
2025-11-18 11:34:31
566
原创 linux之内存管理(7)-内存映射 mmap的实现与分析(一)
的全称是,中文意思是或,是操作系统中的一种,其作用是将一个文件或者其它对象映射到进程的虚拟地址空间,实现磁盘地址和进程虚拟地址空间一段虚拟地址的一一对应关系。通过系统调用我们可以让进程之间通过映射到同一个普通文件实现共享内存,普通文件被映射到进程虚拟地址空间当中后,进程可以像访问普通内存一样对文件进行一系列操作,而不需要通过系统调用来读取或写入。标注红色flags 是常用的。
2025-11-18 11:01:57
979
原创 Linux之中断子系统-工作队列workqueue分析(7)
工作队列(workqueue)是除了软中断softirq和小任务tasklet以外最常用的一种中断下半部分机制,由内核统一管理。工作队列把推迟执行的任务交给内核线程来执行,其运行在进程上下文,允许重新调度、睡眠。工作队列解决了软中断和tasklet执行时间过长导致系统实时性下降的问题,同时避免了驱动模块自身创建线程导致内核线程过多的问题。
2025-11-13 11:16:14
623
原创 Linux之中断子系统-软中断softirq 和小任务 tasklet 分析(6)
硬件的中断处理函数处于中断上半部分,在CPU关中断的状态下执行,中断线程、软中断(softirq)及小任务(tasklet)属于中断的下半部分(bottom half),在CPU开中断的状态下执行。小任务基于软中断实现,实质是对软中断的进一步封装, 在实际使用中应尽量使用小任务。软中断及小任务的执行时机通常是中断上半部分返回(中断服务函数还未完全退出)的时候,其执行的上下文环境也处于(软)中断当中,因此其调用的处理函数不允许睡眠。
2025-11-12 18:13:14
829
原创 Linux之中断子系统-中断控制器的中断函数gic_handle_irq分析(5)
在前面文章中,已经分析汇编函数, 最终调用的是handle_arch_irq或arch_irq_handler_default函数。以zynq7k为例,其采用的是GIC pl390中断控制器,gic初始化的时候调用set_handle_irq函数,将handle_arch_irq函数指针指向了。因此这里以zynq7为例,介绍Linux内核对uart0的中断处理过程。
2025-11-12 17:51:12
572
原创 Linux之中断子系统-内核中断注册源码分析(4)
外设产生中断后,Linux内核会执行一个具体的函数来响应中断,此函数被称为中断服务函数。中断服务函数运行在中断上下文中,若中断线程化后,则中断事件在进程上下文中处理。不同的外设中断源,其对应的中断服务函数一般也不同。因此在使用具体的外设中断之前,需要注册对应的中断服务函数,并指明软件中断号、中断标志、中断名称及传递给中断服务函数的参数等。linux之 硬中断线程化 深度分析_linux软中断和硬中断-CSDN博客。
2025-11-12 17:28:28
713
原创 Linux之中断子系统-中断控制器介绍以及初始化源码分析(2)
zynq7020有两个Cortex-A9内核,采用GIC pl390(属于GIC V1版本)中断控制器。zynq7020中断控制器有16个SGI中断,硬件中断号范围0-15,5个PPI中断,硬件中断号范围16-31,其中16-26保留,没有使用,60个SPI中断,硬件中断号范围32-95,93-95保留,没有使用。SPI中断可通过读取spi_status_0和spi_status_1寄存器,获取发生中断的硬件中断号。每一个外设的中断都对应一个中断描述符,Linux内核使用irq_desc结构体描述中断。
2025-11-12 17:03:30
747
原创 Linux之vmlinux文件段布局和arm64 的链接脚本vmlinux.lds.S分析
作为一个内核工程师, 会经常见到vmlinux ELF文件,如果没有对这个ELF文件熟悉,不能称之为合格的内核工程师。在分析中断向量表的定义和内存布局时,发现自己没有写过一个和内核vmlinux ELF布局的文章。下面开始详细介绍vmlinux ELF是如何生成的以及段布局。
2025-11-11 18:33:49
1039
原创 linux之中断子系统介绍(1)
中 断是指CPU在正常执行指令过程中,出现了突发且紧急的事件,CPU必须暂时停止执行当前的程序,跳转到处理突发事件的指令处执行,处理完毕后返回到原来的指令处继续执行。根据中断的来源,中断可分为内部中断和外部中断,内部中断来源于CPU内部,如软件中断指令、除法错误、溢出等,外部中断来自于CPU外部,由外设产生,如串口收到数据产生中断、定时器到期产生中断。根据中断入口跳转方法可分为向量中断和非向量中断。
2025-11-05 19:25:23
800
1
原创 Linux之内核内存属性代码分析(x86,ARM64,RISC-V)
不同的处理器架构有不同的内存属性(memory type)及不同的行为。为了便于理解和使用,Linux内核在处理器架构的基础上抽象了一套软件接口,定义了noncached、writecombine、writethrough、device等通用的内存属性接口。内核开发者直接使用即可,不需要关注具体处理器架构的内存属性。
2025-11-04 16:07:53
558
原创 Linux之armv8 MMU页表格式及地址转换过程分析
CPU发出的虚拟地址经过MMU转换后得到物理地址,然后使用物理地址访问真实的硬件。虚拟地址和物理地址的映射关系保存在页表中,MMU需要遍历页表,才能将虚拟地址转换成物理地址。ARM64现在有两种大小的页表描述符,分别是ARMv8的64-bit描述符(一个页表描述符8字节),ARMv9的128-bit描述符(一个页表描述符16字节)。本文只介绍ARMv8的64-bit描述符。
2025-11-04 15:28:32
889
原创 Linux之arm SMMUv3命令和事件队列分析(13)
SMMUv3新增了命令和事件队列(),可选的PRI队列,用于和软件进行交互。软件将要执行的命令提交到命令队列,比如预取配置、Invalidate STE命令等,SMMU从命令队列取出命令并执行。当命令不正确或配置出错等错误发生时,SMMU将会将这些事件写入到事件队列,软件从事件队列取出事件进行处理。PRI队列用于接收。
2025-11-04 14:48:52
975
原创 linux之arm SMMUv3 中断处理过程分析(12)
SMMUv3驱动初始化的时候,会注册事件队列中断处理函数、错误中断处理函数和PRIQ中断处理函数。下面分析这些中断处理函数。
2025-11-04 11:20:30
279
原创 Linux之arm SMMUv3 驱动重要宏和函数解析(11)
宏用于计算根页表大小,通常情况下,根页表和其他页表大小相等。由于根页表访问频率较高,有些系统中会进行优化,根页表大小可能会大于其他页表。,l为2,即第2级页表,其对应IOVA bit[20:12]位,则。数据结构,该数据结构中保存了IO页表信息和映射IO页表的回调函数。函数首先从当前页表中解析出下一级页表的物理地址,然后使用。初始化页表项,主要是设置属性、映射的物理地址级页表类型。分配和初始化arm_lpae_io_pgtable。宏用于计算页表(除了根页表大小)大小。用于计算每个页表包含的页表项数量。
2025-11-04 11:12:59
895
原创 Linux之IOMMU 涉及DMA-API(map 和unmap) 调用流程分析(10)
当使用IOMMU且使能DMA-IOMMU中间层时,使用DMA API接口alloc、free、map、unmap内存时,底层都会调用到IOMMU API,最终调用到SMMUv3驱动,完成内存的map和unmap。调用流程如下图所示。
2025-11-04 10:29:58
928
原创 Linux之IOMMU 涉及DMA-API(alloc 和free) 调用流程分析(9)
当使用IOMMU且使能DMA-IOMMU中间层时,使用DMA API接口alloc、free、map、unmap内存时,底层都会调用到IOMMU API,最终调用到SMMUv3驱动,完成内存的map和unmap。调用流程如下图所示。
2025-11-03 16:43:27
855
原创 linux之arm SMMUv3 client 设备DMA配置过程分析(8)
设备总系类型数据结构bus_type中定义了dma_configure和dma_cleanup两个回调函数,前者用于建立该总线上设备的DMA配置,后者用于清理该总线上设备的DMA配置。下面以PCIe设备为例,介绍PCIe设备初始化的时候,DMA配置流程。属性,然后将设备的BDF转换成StreamID。定义PCIe设备使用的Stream ID。设备树定义如下所示。PCIe设备的BDF转换成对应的StreamID。SMMU将PCIe设备的IOVA转换成物理地址。函数,则会调用该回调函数建立设备的。
2025-11-03 15:10:39
301
原创 Linux之arm SMMUv3 控制器注册过程分析(7)
Linux之arm SMMUv3控制器初始化及设备树分析(6)-CSDN博客中描述了IOMMU控制器初始化过程。SMMU驱动最后调用iommu_device_register将其注册到内核中,下面分析一下SMMU控制器注册过程中都做了那些工作。遍历内核中所有总线,初始化使用SMMU的设备,主要是创建设备的Stream Table,给设备分配或者创建iommu_group。遍历所有使用SMMU的设备,创建iommu_domian,并和设备关联起来。主要是初始化设备使用的STE和CD表。
2025-11-03 14:57:15
640
原创 Linux之arm SMMUv3控制器初始化及设备树分析(6)
下面是两个SMMU master设备的设备树。第一个PCI Host设备通过iommus属性引用smmu,StreamID为0x1,外部可能只会接一个PCIe设备,因此只需要一个StreamID。第二个设备为PCIe RC,外部可能会接很多设备,iommus属性无法描述这种情况,因此需要使用iommu-map和iommu-map-mask属性。回调函数集合,该函数集合实现了SMMU所以功能,具体意义如下。下面是RK3588定义的SMMUv3的设备树。SMMUv3驱动的入口函数如下代码所示。
2025-11-03 11:08:40
1068
原创 Linux之IOMMU软件架构分析(5)
Linux系统IOMMU的架构分为7层,分别为IOMMU用户空间接口(IOMMUFD)、DMA接口、DMA和IOMMU中间层、IOMMU接口、IOMMU核心层、IOMMU驱动和IOMMU硬件。IOMMU用户空间接口:控制IOMMU子系统的用户API,使用文件描述符在用户空间管理IO页表。DMA接口:DMA Mapping接口,内核驱动使用这些接口进行内存分配、映射以及缓存同步。
2025-11-03 10:58:51
696
原创 linux之arm SMMUv3 故障和错误(4)
提交给SMMU命令在某些情况下不正确时,命令队列有机制报告这些错误。事件队列中记录了一些错误和故障。包括了来自设备流量(traffic)引起的错误和故障,比如配置错误或者设备地址引起的缺页异常。一种基于全局寄存器的SMMU_GERROR机制用于上报以下情况引发的事件:当无法将记录写入事件队列或PRI队列时,以及其他无法写入内存的灾难性事件。这种情况可能发生在事件队列指针错误的指向不存在的内存,或发生队列溢出的情况下。
2025-10-31 16:32:12
779
原创 linux之arm SMMUv3 STE表和CD表数据格式分析(3)
SMMUv3的Stream Table由STE(Stream Table Entry)表和CD(Context Descriptor)表组成。STE表如果是一级表,则全部由STE组成,每个STE占用64字节,如果是二级表,则第一级表由L1STD组成,每个L1STD占用8字节,L1STD保存了STE表的基地址,第二级表由STE组成。CD表如果是一级表,则表全部由CD组成,每个CD占用64字节,如果是二级表,则第一级表由L1CD组成,每个L1CD占用8字节,保存了CD表的基地址,第二级表由CD组成。
2025-10-31 15:53:03
740
1
原创 linux之arm SMMUv3 stream table 分析(2)
Stream Table中记录了SMMU转换设备地址所需的信息,比如TLB页表基地址、ASID、VMID、配置信息、内存属性等。SMMU使用StreamID和SubstreamID索引Stream Table。Stream Table由STE表和CD表组成,STE表用于第一阶段和第二阶段地址转换,CD表用于第一阶段地址转换。
2025-10-31 11:11:42
486
原创 Linux之PCIE 的port driver的分析
本文介绍PCI Express Port Bus driver基础知识,如何使能注册和反注册PCI Express Port Bus Driver. PCIe Port bus driver 所处PCIe软件架构位置如下图红色。
2025-10-29 18:28:52
294
原创 linux之PCIE 设备枚举流程分析
当系统启动时或者有新的PCIe设备接入时,PCIe主机会扫描PCIe总线上的PCIe设备,读取设备配置空间信息,建立设备的拓扑关系,然后为设备分配资源(如内存空间、I/O空间、中断、总线编号等),最后根据设备的类型匹配驱动。下面以Linux内核为例,介绍PCIe主机枚举PCIe设备的流程。
2025-10-29 18:06:17
927
原创 linux之PCIE 的RC驱动加载和初始化
RK3588 PCIe RC和EP使用同一个平台驱动,其主要的作用是解析设备树中的资源、初始化中断、使能电源、初始化PHY、使能时钟和释放复位,然后根据compatible属性初始化RC或者EP驱动。
2025-10-29 17:09:34
997
原创 linux之内核pcie 软件框架分析
Linux内核PCIe软件框架如下图所示,按照PCIe的模式,可分为RC和EP软件框架。RC的软件框架分为五层,第一层为RC Controller Driver,和RC Controller硬件直接交互,不同的RC Controller,其驱动实现也不相同;第二层为Core层,该层将Controller进行了抽象,提供了统一的接口和数据结构,将所有的Controller管理起来,同时提供通用PCIe设备驱动注册和匹配接口,完成驱动和设备的绑定,管理所有PCIe设备;
2025-10-29 16:44:04
946
原创 linux之PCIE 的控制器硬件结构与dbi
RK3588 PCIe子系统如下图所示。总共拥有5个PCIe控制器。PCIe30X4(4L)支持RC和EP模式,其他4个仅支持RC模式。ITS port 1连接PCIe30X4(4L)和PCIe30X2(2L)控制器,PCIe30X4(4L)和PCIe30X2(2L)控制器使用PCIe3.0 PIPE PHY。
2025-10-20 14:47:14
1081
原创 linux之 remoteproc 内核实现源码分析
远程处理器 (RPROC) 框架允许不同的平台/架构控制(开机、加载固件、关机)远程处理器,同时抽象硬件差异。此外,它还提供监控和调试远程协处理器的服务。1.1 框架通信图右侧是Linux 的kernel ,左侧是控制的远程处理器。1.2 加载固件 的格式remoteproc 框架支持 2 种独占格式:看到网友讲到:此外,该框架还为支持该通信类型的远程处理器添加了rpmsg virtio设备,从而使得特定于平台的远程处理器驱动程序只需提供一些低级处理器,而所有rpmsg驱动程序就可以正常工作。目前还没有明
2025-10-10 10:59:48
1032
原创 Linux之virtio实现原理--virtblk设备初始化
传统磁盘因其工作原理随机访问比顺序访问性能低很多,内核块设备IO系统设计之初针对这种情况的主要优化手段是缓存用户态IO请求并尽可能合并,保证IO请求顺序访问磁盘。在实现时设计单队列存储用户态对块设备的IO请求,一把锁保护该队列上的IO请求数据结构。传统磁盘IO性能瓶颈在于硬件,跨分区访问,随机访问的速度远远没法和磁盘软件栈的处理速度匹配。
2025-09-15 14:53:12
699
原创 linux之和块设备相关的% iowait
IOwait 是指CPU空闲时,且当前有task在等待IO的时间。因IO阻塞而调度主要出现在 1.等待数据返回;2.并发IO时竞争资源影响该时间的因素很多,不只有IO负载,CPU负载也会严重影响该参数,不可一味根据IOwait判断系统的IO压力,还需要结合iostat等数据综合判断。
2025-09-05 14:04:56
828
原创 Linux之块设备的多队列的实现机制
在分析5.*版本的内核源码submit_bio() 函数, 发现 多队列机制是block layer的默认机制;之前老版本的 blk_queue_bio() 函数 也被移除了; IO调度也被融合在 多队列的制作需求的函数里(如果没有指定make_request 函数)。总之, 内核block layer软件框架目前是走多队列的架构。下面展示一下源码:submit_bio():-》generic_make_request()-》q->make_request_fn(q, bio);这个函数是在什么
2025-09-05 11:31:44
673
原创 linux之IO存储子系统全流程分析
首先做一个简单科普,如图所示,内存是以page (4k)为单位的kernel在2020年12月的patch中提出了folio的概念,我们可以把folio简单理解为一段连续内存,一个或多个page的集合,他和page的关系如图:
2025-09-03 15:23:32
997
1
原创 Linux之块设备驱动框架
块设备是针对存储设备的,比如 SD 卡、EMMC、NAND Flash、Nor Flash、SPI Flash、机械硬盘、固态硬盘等。因此块设备驱动其实就是这些存储设备驱动,块设备驱动相比字符设备块设备只能以块为单位进行读写访问,块是 linux VFS基本的数据传输单位;字符设备是以字节为单位进行数据传输的,不需要缓冲块设备在结构上是可以进行随机访问的,对于这些设备的读写都是按块进行的,块设备使用缓冲区来暂时存放数据,等到条件成熟以后在一次性将缓冲区中的数据写入块设备中。
2025-08-29 18:09:09
861
原创 linux 之内核rpmsg 的框架和具体的实现
RPMsg是利用通道进行数据通信,先用 /dev/rpmsg_ctrl0 设备通过ioctrl生成端点,然后使用生成的端点进行通讯名称服务,VIRTIO_RPMSG_F_NS 宏,不开启就不使用名称服务,使用就需要m核心先发送信息才可以注册设备驱动中定义的核心:m核A核RPMsg内核驱动框架涉及到RPMsg框架、virtio框架、remoteproc子系统和mailbox子系统mailbox,驱动开发者可自我注册client生成设备提供APP层直接进行核间通信分析物理层,创建。
2025-08-25 10:53:55
1228
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅