- 博客(16)
- 收藏
- 关注
原创 LDD3--字符设备驱动
次设备号由驱动程序内部用于区分同一驱动管理下的不同设备实例,驱动通过次设备号来定位具体的物理或逻辑设备。VFS 最终通过函数指针 file->f_op->open(inode, filp),将找到的 inode 和刚创建的 file(filp)作为参数,将控制权正式移交给驱动开发者编写的 open 函数,完成整个调用闭环。校验通过后,内核分配并创建 file 结构体,将原始的 flags(含 O_NONBLOCK)存入 file->f_flags,将 f_mode 存入 file->f_mode。
2026-08-13 08:47:24
161
原创 LDD3--构造和运行模块
本文介绍了Linux内核模块开发的基本流程和关键概念。首先展示了一个简单的"Hello World"内核模块代码,解析了__init、__exit等宏的作用。接着说明了编译环境配置和Makefile的工作原理,重点解释了模块编译时的目录切换和参数传递机制。然后详细分析了insmod、modprobe等工具加载和卸载模块的内部机制。最后探讨了内核模块的版本依赖问题,解释了vermagic校验机制,并提供了针对不同硬件架构的交叉编译配置方法。全文系统地讲解了从模块编写到编译、加载的完整流程,强调了版本匹配和架构
2026-07-24 16:40:06
197
原创 LDD3--设备驱动程序简介
设备驱动程序本质上是操作系统和硬件设备之间的桥梁,它屏蔽了硬件设备的物理差异,向上层提供标准的操作接口。// 假设这里是操作系统的 demo, 操作系统定义了 init exit print 三个抽象接口,当用户点击打印按钮之后,操作系统就会按序执行接口内容,接口实现在驱动程序中,具体逻辑要在驱动加载 probe 之后才能知道;= 0) {printf("[OS] 错误:驱动加载失败!\n");return -1;printf("用户点击打印按钮\n");return 0;
2026-07-24 14:36:33
240
原创 宏定义使用
如果定义的 stuff 非常长,可以将其分成几行,除最后一行外,每行末尾都添加一个反斜杠 如果反斜杠添加在宏 中,第二行前面的空白字符会被忽略,如果是字符串,第二行的空白字符还是会存在,对于多参数的调用,还是在参数逗号后面进行换行。#undef 如果一个现存的名字需要重新定义,那么他的旧定义必须使用 #undef 移除。每对定义的每条语句是等价的,但 #if 形式功能更强,因为可以每条判断有多个条件。根据上面的逻辑,宏定义也是完全可以进行嵌套的,但是宏里面不能出现递归。
2024-12-16 16:50:12
776
原创 “C 和指针” 指针的概念
从这一点看,指针变量和其他变量没有什么区别,如果变量是静态的,他会被初始化为 0,但是如果变量是自动的,他将根本不会初始化,声明一个指向整型的指针并不会创建一个存储整型值的内存空间。计算机的内存由很多很多 bit 组成,每个bit可以容纳值 0 或 1,每 8 个位可以组成一个字节,每个字节通过地址来标识,一些机器通过字来存储整数,一个字一般由 2 - 4个字节组成,尽管一个字包含了四个字节,但是他仍然只有一个地址,至于他的地址是最左边字节还是最右边字节的位置,不同机器有不同的规定。
2024-12-13 09:47:58
326
原创 c 和指针 动态内存分配
realloc 用于修改已经存在的内存块的大小;如果原先内存块无法改变大小,realloc 会重新申请一块内存,然后把原有内容复制过来,所以在使用 realloc 之后,原有的内存指针就不能使用了,应使用 realloc 返回的新指针;如果内存池是空的或者可用内存无法满足要求,malloc 会返回一个 NUL 指针,因此每个从 malloc 返回的指针都需要检查,确保非 NUL。malloc 参数 需要分配的字节数,然后返回一个指向被分配的内存块起始位置的指针,malloc 分配的是一块连续的内存;
2024-12-12 20:41:39
850
原创 c 和指针 学习笔记 结构体联合体
这个实际上就是声明了一个结构体数组,和一个结构体指针;这两个声明会被编译器当作完全不同的两个数据类型,即使他们的成员列表完全相同,所以下面这条语句实际上是非法的。如上代码实际上就声明了一个 TAG ,为特定的成员列表提供一个结构名;这个声明实际上类似于制造一个甜饼切割器,可以决定最后的切割形状,但其本身并不是甜饼;声明结构时,必须列出它包含的所有成员,列表包含每个成员的类型和名字。声明了一个结构变量 x,这个结构变量包含 a b c 三个成员;结构的每个成员主要是通过成员名字来进行访问;
2024-12-11 21:04:09
255
原创 c和指针 学习笔记 字符串
dst 需要在内存上修改内容,所以不能使用字符串常量,同时 strcpy 会将 NUL 字节同步进行 cpy,如果 dst 原始字符串长于 src 字符串,那么多出来的部分在经过 cpy 后将丢失。if (strlen(a)>strlen(b)) 与 if(strlen(a)-strlen(b)>0) 实际上是不相等的。将 src 字符串复制到 dst 参数,如果 src 和 dst 内存上存在重叠,那么结果是未定义的;将src拷贝添加到 dst 字符串的结尾,必须要考虑 目标字符串空间必须是足够的。
2024-12-09 20:52:41
233
原创 c和指针--函数
返回值类型 函数名 形参类型 函数体 是函数组成的四个基本要素开发一段程序是一个周密执行的过程,对于一些和必须要执行的函数/过程,可以先用存根占位置// NULL 空函数体, 只起到一个存根作用 }K&R C定义一个函数 显然比现在复杂得多intadd(a, b)int a;int b;函数默认返回值是 int,所以对于没有返回值的函数应该使用 void 声明其返回类型;从表达式内部调用一个过程类型的函数是一个非常严重的错误,这会使用一个不可预测的值;(编译器会识别到这个错误)
2024-11-21 21:06:41
285
原创 “C和指针” 学习笔记 --章节五
强制类型转换具有相当高的优先级,如果说把强制类型转换放在一个表达式前面他只会改变表达式第一个项目的类型,如果要对整个表达式进行类型转换,必须要把整个表达式用括号括起来。操作数既可以是表达式也可以是两边加上括号的类型名,当然在表达式操作数两边都加上括号也是合理的 比如;赋值操作符把右操作数的值存储于左操作数的指定位置;使用规则很好记,在操作数之间的操作符在变量值被使用之前增加他的值,在操作数之后的操作符在变量值被使用之后才增加他的值。赋值是表达式的一种,所以只要允许出现表达式的地方都允许赋值,;
2024-11-01 20:57:41
763
原创 “c和指针”学习笔记 --章节四
C 最简单的语句,本身只包含一个 分号。适用的场合就是语法要求出现一条完整地语句,但不需要它执行任何操作;,赋值对于 C 来说是一种操作,就像加法和减法一样,赋值在表达式内进行。
2024-10-31 20:10:50
177
原创 “c和指针” 学习笔记 --章节三
非缺省状态下,我们可以通过在字符末端添加 L 或 l,使整数被解释为 long,字符 U 或 u 使数值被解释为 unsigned ,如果添加 ul 那么就会被解释为 unsigned long;signed 和 unsigned 改变整型的表示范围,当可移植问题比较重要时,最佳妥协方案就是把存储 char 型变量的值限制在 signed char 和 unsigned char 的交集中;整型包括字符、短整型、整型、长整型,听上去长整型一定比短整型要大,但这个假设实际上不一定正确。
2024-10-30 17:09:31
224
原创 “c和指针“ 学习笔记 --章节二
c 是一种自由形式的语言,没有规定一行中可以出现多少条语句(预处理指令以行为单位),应该出现多少空白等,唯一规则就是相邻标记之间必须要有至少一个空白字符(制表符、空格、换行符),否则会被解释为单个标记;一个源文件可以包含多个函数,但每个函数最好完整出现在同一个源文件中,虽然标准没有规定,但这才是比较合理的形式,这样使抽象数据类型成为可能;每个可执行代码都有运行时堆栈,用于保存变量和返回地址,程序同时也会使用静态内存,存储在静态内存中的变量在程序整个执行过程中一直保留它们的值;c 的多行注释由 /* …
2024-10-30 15:02:02
380
原创 数组指针、指针数组、数组、数组首元素code笔记
/ a &a &a[0] 看起来地址是完全一致的,但是实际上有完全不同的含义。// 同理可见 对于 指针数组 int *ints[10];// a是数组名,保存数组地址的地址需要&a。// ints 类型是 int *[10]// 指针数组,每个元素都保存了一个指针。// &ints 类型是 int。
2024-10-28 14:58:34
174
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅