1.linux内核$(kallsyms.o)详解续篇 --- 内核符号表的源码生成和查找过程
2.正点原子嵌入式linux驱动开发——LED驱动开发
3.Linux里面配置多个源会怎样?
4.linux内核一般有3个主要部分是什么?
5.linux内核-2-linux内核makefile编译过程
6.linux一般有3个主要部分,分别是
linux内核$(kallsyms.o)详解续篇 --- 内核符号表的生成和查找过程
在内核中,维护着一张符号表,源码记录着内核中的源码所有符号,包括函数与全局变量的源码地址与名称。这张表嵌入在内核镜像中,源码供内核运行时随时查找符号名。源码纯html单页源码通过调用__print_symbol,源码内核代码能打印出符号名。源码 接下来,源码我们将详细解析内核符号表的源码生成与查找过程。系统映像文件与/proc/kallsyms的源码区别与联系
系统映像文件(System.map)在编译内核时生成,记录了内核中的源码所有符号及其在内存中的虚拟地址。文件由scripts/mksysmap脚本生成,源码依赖于nm命令。源码系统映像文件的源码每条记录包括地址、符号类型与符号名。符号类型包括函数、全局变量等。 而/proc/kallsyms文件是在内核启动后自动生成,位于/proc目录下,其代码实现于kernel/kallsyms.c。区别在于它包含了内核模块的符号列表,并且允许用户态访问,非内核常规操作。通常,我们只需关注_stext ~ _etext 和 _sinittext ~ _einittext之间的hashmap源码原理符号。内核符号表的生成与查找
内核在运行过程中可能需要查找地址对应的函数名,如Oops或调试信息输出。但内核并未依赖System.map或/proc/kallsyms文件,而是通过vmlinux中的符号表(.tmp_vmlinux2.o)实现快速查找。内核符号表结构
内嵌符号表通过scripts/kallsyms工具生成,源码位于kallsyms.c。该表包含6个全局变量:kallsyms_addresses、kallsyms_num_syms、kallsyms_names、kallsyms_token_table、kallsyms_token_index与kallsyms_markers。其中,kallsyms_addresses记录所有符号地址,kallsyms_num_syms统计符号数量,kallsyms_names存放符号名,kallsyms_token_table与kallsyms_token_index用于压缩存储高频率字符串。压缩算法与优化
内核使用压缩算法减少存储开销,将高频率字符串表示为token,并通过kallsyms_token_table与kallsyms_token_index实现压缩与解压。kallsyms_markers将符号每个分组,加速查找过程。查找过程实例与源码分析
举例说明查找地址0xc对应的符号名。首先在System.map中定位到该地址位于__create_page_tables与__enable_mmu之间。在.tmp_kallsyms2.S文件中,利用二分查找定位符号地址,算命源码系统然后通过kallsyms_names与kallsyms_markers加速查找过程。最后解析压缩的符号名,得到结果为__enable_mmu。内核模块符号查找
内核模块在启动时动态加载,其符号表存储在struct module结构中,所有已加载模块的struct module结构构成全局链表。查找内核模块中的符号时,调用kallsyms_lookup()函数,模块符号查找由get_ksymbol()函数完成。正点原子嵌入式linux驱动开发——LED驱动开发
在之前的笔记中,我们详细介绍了字符设备驱动的开发流程,并通过虚拟chrdevbase设备实践了首个驱动。接下来,我们将转向正点原子STMMP开发板上的LED灯驱动编写。
在Linux环境下,驱动开发的核心是配置硬件寄存器。LED灯驱动也不例外,它涉及对STMMP的IO口进行设置。特别地,LED0连接到PI0引脚,因此我们的焦点在于构建Linux下针对该引脚的控制驱动。
首先,理解MMU,即内存管理单元,它在Linux下负责虚拟空间到物理空间的弹头捕鱼 源码映射。在Linux内核中,尽管早期要求处理器具备MMU,但现在支持无MMU设备。MMU的作用在于,即使开发板内存只有1GB DDR3,通过内存映射,虚拟地址空间可以扩展到4GB。当CPU访问数据时,实际上是通过虚拟地址间接访问物理地址,这就需要借助ioremap和iounmap函数进行内存映射和解除映射。
ioremap函数接收物理地址和内存大小,返回映射后的虚拟地址空间。卸载驱动时,使用iounmap撤销映射。这些函数确保了在Linux系统内的正确内存访问。
在LED驱动中,使用ioremap将GPIOI_MODER寄存器映射到虚拟地址,以便通过指针进行读写操作。Linux内核推荐使用readb, readw, readl等函数进行I/O操作,以及writeb, writew, writel进行写入操作。
回到硬件层面,STMMP开发板上的LED0连接到PI0引脚,通过改变PI0的输出状态控制LED的点亮和熄灭。驱动程序编写包括定义设备宏、寄存器操作函数、商城不给源码设备操作函数如led_switch和led_unmap,以及设备注册、文件操作等步骤。
最后,通过编写测试应用程序,进行设备打开、关闭、读写操作,验证驱动的正确性。编译驱动模块,将模块加载到开发板,并创建设备节点进行测试,成功后可以卸载驱动,整个过程涉及地址映射、字符设备操作以及硬件配置的实践。
总之,本篇主要讲解了如何通过Linux的地址映射技术,结合字符设备操作,实现对STMMP开发板上LED灯的驱动开发,包括寄存器配置和硬件连接的理解。实践中,手册查阅和理解硬件手册是非常重要的环节。
Linux里面配置多个源会怎样?
可以。
添加思路:cpu core初始化,内存管理子系统(mmu),硬件时钟系统,早期调试打印机制,异常中断子系统,时间子系统(timer),串口驱动。
具体方式:
1 cpu core初始化
cpu core的初始化主要指cpu的工作模式,通用寄存器初始化,cache初始化,异常入口初始化,mmu初始化等。也就是cpu core内部各个单元模块的初始化。
2 内存管理子系统
kernel是运行在动态存储器(DRAM DDR),首先保证动态存储器的稳定运行,动态存储器的初始化一般是放在bootloader中,或者在我们的调试工具脚本中去配置DDR参数,实现DDR的稳定读写运行。
3 硬件时钟系统
最小的soc片上系统应该有CPU,时钟,复位电路和一块存储器构成,缺一不可。
4 早期调试打印机制
在dram和寄存器读写正常后,接下来首要任务是实现kernel早期的调试打印,这是调试kernel所必须的。
5 异常 中断子系统
timer和uart要正常工作,异常(ppc核内有timer,作为一种单独的异常来处理) 中断是必须要正常工作起来。
6 时间子系统
kernel下时间子系统实现计时和定时功能,主要是根据一个外部timer或者核内timer(PPC提供核内timer)来实现。
7 串口驱动
最后实现串口驱动就完成了移植kernel的最后一步了。串口驱动实现这里不细说了。
linux内核一般有3个主要部分是什么?
进程调度器:这个内核子系统负责在系统上同时运行的所有进程之间公平地分配CPU时间。
内存管理单元:这个内核子单元负责在系统上运行的各种进程之间合理分配内存资源。MMU不仅仅为每个进程提供单独的虚拟地址空间。
虚拟文件系统:这个子系统负责提供一个统一的接口来跨不同的文件系统和物理存储介质访问存储的数据。
linux内核-2-linux内核makefile编译过程
Linux内核编译过程主要涉及zImage的编译和vmlinux的生成,这些目标通过顶层Makefile中的规则进行管理。_all是默认目标,当执行make或make all时,会首先编译vmlinux。vmlinux的编译依赖于scripts/link-vmlinux.sh,它会链接$(vmlinux-deps),这些依赖包括head-y、init-y/drivers-y、net-y、libs-y和core-y等组成部分。
head-y是不依赖MMU的架构编译目标,而init-y/drivers-y和net-y是顶层Makefile中的模块。libs-y包含了arch/arm/lib目录下的库文件,而core-y则根据配置项可能包含VFP相关的模块。最终,这些模块被链接成vmlinux,使用link-vmlinux.sh脚本进行链接,并调用if_changed函数进行条件判断和链接操作。
在编译zImage时,make zImage会构建vmlinux并进一步生成zImage,zImage是vmlinux经过gzip压缩后的版本。Image和zImage的区别在于Image不压缩,而zImage压缩后更小。uImage是旧版uboot的专用镜像,现已很少使用,而zImage在新版本uboot中广泛支持。
整个过程中,scripts/Makefile.build文件起到了关键作用,它定义了编译规则,如编译内置目标和模块,以及如何生成zImage。编译过程包括编译内置目标(如built-in.o)和链接生成最终的可执行文件vmlinux,然后根据配置生成zImage。
linux一般有3个主要部分,分别是
1. 进程调度器:负责在系统中所有运行的进程之间公平地分配CPU时间,确保高效的多任务处理。
2. 内存管理单元(MMU):负责合理分配内存资源给系统中的各个进程,并为每个进程提供独立的虚拟地址空间,同时管理虚拟与物理内存的映射。
3. 虚拟文件系统(VFS):提供统一的接口,以便跨越不同的文件系统和物理存储介质访问存储的数据,为用户空间的应用程序提供一致的文件操作体验。
《Linux Kernel IOMMU》翻译
本文是一篇关于Linux内核中输入输出内存管理单元(IOMMU)的深入介绍,主要针对IT技术专家和Linux内核开发者。IOMMU是PCIe的一部分,负责将设备虚拟地址翻译成物理地址,提升虚拟化环境中的系统性能。文章将从IOMMU的基础概念、硬件功能、Linux内核中的IOMMU子系统,以及DMA转换模式和直通模式的详细解释入手,逐步深入。
文章首先阐述了IOMMU的核心概念和与内存管理单元(MMU)的区别,强调了IOMMU在硬件层面进行地址转换的优势。接下来,文章解释了如何在Linux内核中传递I/O请求,并通过I/O页表和相关数据结构的构建,使得IOMMU硬件能够正确地进行地址转换。文章还提到,操作系统需要获取IOMMU的硬件信息,这通常通过主机系统固件的ACPI表提供。
在介绍Linux内核的IOMMU子系统时,文章详细描述了子系统的三个层次以及如何处理DMA请求。它解释了DMA子系统与IOMMU子系统之间的交互,以及在DMA映射请求被直接映射或需要IOMMU硬件参与映射时的具体流程。文章还讨论了IOMMU支持的两级地址翻译机制,并给出了示例说明如何利用不同层级的页表实现地址转换。
文章进一步讨论了在ACPI表中描述IOMMU功能和配置的细节,以及如何在Linux IOMMU子系统中初始化IOMMU硬件。它特别提到了两种类型的IVDBs和AMD IOMMU的硬件描述。
文章随后介绍了Linux内核中的IOMMU DMA转换模式与直通模式的区别。DMA转换模式下,主机操作系统应用基于IOMMU的操作,实现DMA转换;而直通模式下,DMA地址等于系统物理地址,DMA访问不需要经过虚拟机管理程序,直接通过IOMMU硬件进行地址映射。文章还解释了在BIOS设置中开启IOMMU直通模式与禁用IOMMU选项之间的区别。
文章最后讨论了虚拟化环境中的直接设备访问用例,并通过crash工具程序深入分析了IOMMU状态更改的示例。文章提供了虚拟化环境配置、实验环境服务器配置、在KVM引导进入有直接设备访问的虚拟机操作系统前后的IOMMU信息对比,以及使用crash工具观察AMD的IOMMU结构的详细步骤和结果。
本文旨在为想要深入了解Linux内核中IOMMU技术的IT专家和开发者提供全面、深入的指导,从基础概念到实际应用,覆盖了IOMMU在虚拟化环境中的关键功能和操作流程。