Linux内核
文章平均质量分 72
小黑屋关门了
这个作者很懒,什么都没留下…
展开
-
kmem_cache(slab机制)
同时,kmem_cache 中的 c_lastp 以及 c_firstp 指针将以 c_offset 属性地址为基准,使其成 kmem_cache 中所有 slabs 的双向链表头。当申请 地址空间时,内核首先匹配较为接近的 kmem_cache,随后在 kmem_cache 中已有的 slab 中获取相应的地址空间(即。上述结构中 kmem_cache 结构中嵌套了 kmem_slab 结构,用作 kmem_cache 中 slab 结构的链表头。嵌套的位置为 kmem_cache->c_offset。原创 2022-09-08 18:11:56 · 1050 阅读 · 0 评论 -
free_area 空闲区域
申请地址空间时,内核将根据 free_area 和 mem_map 数组来决定,内核提供了宏 RMQUEUE_TYPE 作为内存分配的最终执行者。关于上述中的 free_are_init 接口则是在 paging_init 接口中被调用,不同的架构实现的页初始化不同,以 i386 为例。通过 free_area_init 接口来初始空闲区域。为了理解 Linux 内存管理,选取低版本向上学习,此次分析的为 2.2.26 版本。综上,便是 free_area 的入口调用分析。原创 2022-09-05 17:13:06 · 433 阅读 · 0 评论 -
内存管理_memblock
void __init page_address_init(void){ int i; for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) { INIT_LIST_HEAD(&page_address_htable[i].lh); spin_lock_init(&page_address_htable[i].lock) }}static struct page_address_slot { struct原创 2022-08-23 15:00:04 · 207 阅读 · 0 评论 -
ftrace
//以kpatch中的ftrace使用为例,进行分析static struct ftrace_ops kpatch_ftrace_ops __read_mostly = { .func = kpatch_ftrace_handler, .flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY,};ftrace_set_filter_ip(&kpatch_ftrace_ops, ip, 0, 0);re原创 2020-11-26 14:22:42 · 262 阅读 · 0 评论 -
ftrace_init
//ftrace在kernel启动初始过程中会被初始化,即在init/main.c:start_kernel()函数中。//以mips结构为例,分析ftrace的初始化过程:void __init ftrace_init(void){ extern unsigned long __start_mcount_loc[]; extern unsigned long __stop_mcount_loc[]; //这两个变量由内核编译的过程中进行赋值 unsigned long count, f原创 2020-11-26 10:47:44 · 318 阅读 · 1 评论 -
sock文件系统
//sock文件系统定义如下:static struct file_system_type sock_fs_type = { .name = "sockfs", .init_fs_context = sockfs_init_fs_context, .kill_sb = kill_anon_super,};//sock文件系统在内核初始过程中通过init_calls方式来执行core_initcall(sock_init);//sock文件系统入口——sock_init()接口,原型如下:原创 2020-10-19 21:04:02 · 555 阅读 · 0 评论 -
网络子系统
网络子系统在内核中可划分为两部分,分别是网络协议栈和网络设备。将从网络编程的接口入手,了解网络子系统,主要以TCP socket编程为例来进行分析。socket系统调用原型:int socket(int family, int type, int protocol);SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol){ return __sys_socket(family, type, protocol);}原创 2020-10-19 21:01:47 · 861 阅读 · 0 评论 -
中断域
IRQ Domain用于将硬件的中断号,转换成Linux系统中的中断号(virtual irq, virq)。例如:硬件中断号 映射关系 Linux中断号 (irq_domain)INT ID#20 ----------------> irq=4每个中断控制器都对应一个IRQ Domain;中断控制器驱动通过irq_domain_add_*()接口来创建IRQ Domain;IRQ Domain支持三种映射方式:linear map(线性映射),tree map(树映射原创 2020-07-16 17:27:37 · 858 阅读 · 0 评论 -
CPU Temp hardware monitor
在内核中,为了对硬件设备进行监视,内核提供了hwmon(hardware monitor)方法,来方便对硬件设备的监视。以社区5.6版本为例,分析与龙芯相关的cpu_hwmon.c文件,该文件以module_init()的形式注入内核,从而在内核初始化阶段通过do_initcalls被调用,从而得到执行。该文件的入口函数为:static int __init loongson_hwmon_init(void){ int ret; pr_info("Loongson Hwmon Enter...\n原创 2020-07-06 18:02:54 · 1008 阅读 · 0 评论 -
总线注册(platform,PCI)
在内核中可能存在不同种类的总线,为了对总线进行管理,内核将其抽象为设备来进行管理。这里,分别以platform总线和pci总线为例来进行说明。platform总线是一种虚拟总线,当某一设备与处理器直接连接时,可以利用该虚拟总线来模拟出设备通过总线连接到处理器这一结构。内核中,关于platform总线的注册位于drivers/base/platform.c文件中。int __init platform_bus_init(void){ int error; early_platform_clean原创 2020-07-06 16:30:05 · 843 阅读 · 0 评论 -
device_tree分析
在内核中,经常会听到“设备树”这一概念,根据名字,大致可以理解为内核将计算机系统中的设备按照树型结构进行了组织。首先,了解一下内核将会使用的设备树二进制文件DTB。DTB(Devicetree Blob)是DTS的二进制文件格式,Kernel使用DTC工具将DTS源文件编译成DTB,bootloader再将DTB文件传递给Kernel解析。DTB的文件结构|-----------------------|| struct fdt_header ||--------------------原创 2020-06-30 11:01:51 · 2487 阅读 · 0 评论 -
setup_early_printk()函数分析
关于该函数,主要用来注册用于早期显示的终端。内核中声明了一个全局变量early_console,并将另一全局变量early_console_prom赋值给它,同时,注册early_console_prom所抽象的终端。原型如下:struct console *early_console;static void early_console_write(struct console *con, const char *s, unsigned n){ while (n-- && *s)原创 2020-06-15 19:41:28 · 257 阅读 · 0 评论 -
printk()函数分析
在内核模块中,常用的输出函数为printk(),为了理解该函数的工作原理以及执行流程,接下来对该函数进行分析。printk()函数原型如下://以“printk("num is: %d!\n", num)”语句为例,开始分析。//在分析之前,先来了解两个宏定义,分别是:#define va_start(v, l) __builtin_va_start(v, l) //参数v将指向(addr + sizeof(l)),addr为参数的首地址#define va_end(v) __builtin_va原创 2020-06-15 14:43:11 · 2935 阅读 · 0 评论 -
PCI总线设备遍历
在梳理内核驱动程序时,发现一个问题,当注入内核驱动程序时,内核会根据驱动结构体(比如:struct pci_driver)中的总线属性(pci_driver->bus)来找到与驱动程序在同一总线上相对应的驱动设备。因此,本文主要对pci设备在内核中的注入时间,以及注入过程来进行分析。查阅资料,得知关于不同CPU架构下的PCI设备的注入是以arch/cpu_type/pci/目录下的文件为入口来开始执行的。通过对其中的文件进行分析,最后执行的关键入口函数为pci_bus_add_devices()函数原创 2020-05-21 10:18:13 · 1915 阅读 · 0 评论 -
Linux_rtl8169
以Realtek_8168网卡为例,来说明Linux内核中网卡设备驱动的注册与运行。因为r8168与r8169使用的相同的驱动程序,因此在内核版本中,会发现r8169_main.c文件。在5.6版本的内核中,内核定义了struct pci_driver rtl8169_pci_driver对象来描述网卡驱动,并调用module_pci_driver()函数来注册该驱动模块。如下:static ...原创 2020-05-16 17:03:10 · 647 阅读 · 0 评论 -
硬件中断信号处理
我们知道关于中断被分成了两种,一种是软中断(比如:系统调用,系统报错等);另一种是硬件中断。这里我们来了解一下内核是如何识别并处理这些中断的。以5.6版本的内核为例,在内核启动阶段的代码中可以看到这么一个函数init_IRQ(),顾名思义,该函数主要的任务是初始化中断。因为每个CPU的架构不同,所以其硬件中断存在一定的差异性,因此该函数由各个CPU的架构自己来实现。这里以mips架构为例,其实现...原创 2020-05-15 17:56:00 · 1022 阅读 · 0 评论 -
从硬件了解寻址
学习Linux内核,内存管理是必学的,但是和自己以前设计译码电路的寻址完全不同,所以对抽象后地址映射不能很好地理解,虽然很多书都有介绍,但是领悟的还是有缺陷。所以这次以Intel微处理器为例子去了解硬件是怎么寻址的,然后在转到Linux系统怎么抽象的。80x86常见的工作模式有,实模式和保护模式。先来看实模式,它的操作空间<=1MB。所以这个时候段寄存器里面存放的是16位的段地址。然后段地址会原创 2017-01-15 22:02:58 · 744 阅读 · 0 评论 -
Linux内核——进程管理(二)
进程上下文 可执行程序代码是进程的重要组成部分。这些代码从一个可执行文件载入到进程的地址空间执行。一般程序在用户空间执行。当一个程序执行系统调用或者触发了某个异常,它就陷入了内核空间。此时,我们称内核“代表进程执行”并处于进程上下文中。在此上下文中current宏是有效的。除非在此间隙有更高优先级的进程需要执行并由调度器做出了相应的调整,否则在内核退出的时候,程序恢复在用户空间会继续执行。 系统原创 2017-07-02 11:54:55 · 249 阅读 · 0 评论 -
进程管理(一)
进程 进程就是处于执行期的程序(目标码存放在某种存储介质上)。但进程并不仅仅局限于可执行程序代码(Unix称其为代码段,text section)。通常进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程(thread of execution),当然还包括用来存放全局变量的数据段等。实际上,进程就是正在执行的程序的实时结原创 2017-06-30 22:53:25 · 260 阅读 · 0 评论 -
linux 内核—进程的地址空间(1)
系统中所运行的程序,被叫做进程。每个进程在执行的过程中都会有自己独立的地址空间,而系统是如何确定哪块地址空间是该进程的?所以创建了有关进程的地址空间的数据结构体,通过这些结构体来创建、查找、删除与进程对应的地址空间。什么是地址空间?由进程的所有线性地址构成的空间叫做地址空间。但是地址空间又是由n(n>=0)个线性区构成的,也就是说,地址空间中的线性地址并不是连续的。而线性区的线性地址却是连续的。所以原创 2017-07-09 15:13:40 · 286 阅读 · 0 评论