
嵌入式之路,LDD3,驱动程序
三眼桥墩
这个作者很懒,什么都没留下…
展开
-
LDD3 D01 2018.01.01 星一
21:50-22:38 50分钟 #前言内容的组织两大部分:第一部分(第一到第十一章)如何编写内核磨课,编写功能完备的字符设备驱动程序所涉及的各个编程主题。第二部分(第十二到第十八章)讲述块设备驱动程序和网络接口 #第一章设备驱动程序简介用户的操作通过一组标准化的调用执行,而这些调用独立于特定的驱动程序。将这些调用映射到作用于实际硬件的设备特有操作上,则是设原创 2018-01-01 23:14:15 · 204 阅读 · 0 评论 -
LDD3 D15 01.15 星一
21:15-22:05-p228内核定时器的实现这个级联表的工作方式如下: 如果定时器在下一个 0 到 255 jiffies 中到期, 它被添加到专供短时定时器 256列表中的一个上, 使用 expires 成员的最低8位. 如果它在将来更久时间到时( 但是在 16,384 jiffies 之前 ),它被添加到基于 expires 成员的 9 - 14 位的 64 个列表中一个。原创 2018-01-15 22:07:49 · 173 阅读 · 0 评论 -
LDD3 D05 补
10:01-11:30 p75-p99第四章 调试技术内核中的调试支持通常在内核配置的 kernel hacking 菜单中。 通过打印调试 printk消息有优先级。类似 KERN_ALERT 的宏会被展开成尖括号中的整数。 定义了8种这样的宏。数字越小严重程度越高。 klogd, syslogdecho 8 > /proc/sys/kernel/原创 2018-01-06 22:32:54 · 186 阅读 · 0 评论 -
LDD3 D16 01.16 星二
22:30-23:15 -p248per-CPU 变量当你创建一个per-CPU变量, 系统中每个处理器获得这个变量的副本。因而访问它不需要锁定。 对 get_cpu_var 的调用返回一个 lvalue 。因为是 lvalue,所以 它可被赋值给或者直接操作. 例如, 一个网络代码中的计数器时使用这 2 个语句来递增的:get_cpu_var(sockets_in_use)+原创 2018-01-16 23:43:36 · 178 阅读 · 0 评论 -
LDD3 D08 01.08 星一
20:50-21:55 p99-p120通常, 当你面对一个 oops, 第一件事是查看发生问题的位置, 常常与调用堆栈分开列出. 在上面展示的第一个 oops, 相关的行是: EIP is at faulty_write+0x4/0x10 [faulty] 这里我们看到, 我们曾在函数 faulty_write, 它位于 faulty 模块( 在方括号中列出的 ). 16原创 2018-01-08 23:15:03 · 177 阅读 · 0 评论 -
D24 补
50m 20p 类【没读懂】 一个类是一个设备的高级视图, 它抽象出底层的实现细节. 驱动可以见到一个SCSI 磁盘或者一个 ATA 磁盘, 在类的级别, 它们都是磁盘. 类成员常常由上层的代码处理, 而不需要驱动的明确的支持。【Q什么意思?】 class_simple接口第一步是创建类自身. 使用一个对 class_simple_creat原创 2018-01-25 22:35:22 · 216 阅读 · 0 评论 -
D25 01.25 星四
21:15-22:3019p第十五章 内存映射和DMA 地址类型虚拟内存引入了一个中间层, 有了虚拟内存,系统运行的程序可以分配远多于物理上可用的内存。 User virtual addresses 这是被用户程序见到的常规地址. 用户地址在长度上是 32 位或者 64 位,依赖底层的硬件结构, 并且每个进程有它自己的虚拟地址空间.Physica原创 2018-01-25 22:45:53 · 230 阅读 · 0 评论 -
LDD3 D09 01.09 星二
21:24-22:15 -p136 自旋锁函数如果你有自旋锁,他可以在被运行在(硬件或软件)中断上下文获得, 则必须使用一种禁止中断的形式获得. 因为使用其他锁函数,迟早会导致死锁。【为什么?】 读取者和写入者自旋锁允许多个进程读,但只有一个进程可以写。 锁陷阱不明确的规则锁定模式,策略,必须一开始就规定好。无论是信号量还是自旋锁,不允许第二次获得锁原创 2018-01-09 22:43:29 · 152 阅读 · 0 评论 -
D17 补
20:54-22:01 20p 使用I/O 内存用来和设备通讯的主要机制是通过内存映射的寄存器和设备内存 I/O 内存是简单的一个象 RAM 的区域不管是否需要 ioremap 来存取 I/O 内存, 不鼓励直接使用 I/O 内存的指针。 而应该用封装过的函数或宏。这是为了安全和可移植性的考虑。 I/O 内存分配和映射I/O 内存区必须在使用前分配.分配内存区的接口是( 在 定义):stru原创 2018-01-18 22:26:33 · 153 阅读 · 0 评论 -
D26 缺
如题原创 2018-01-26 21:51:01 · 167 阅读 · 0 评论 -
Sprint 2 Done
做得好:坚持写博客 做得不好没有动手写代码,只读书,几乎不能理解书上内容。第十四章 Linux设备模型。没读懂第十五章内存映射和DMA没读懂 节后见了。2018.1.26原创 2018-01-26 21:55:21 · 179 阅读 · 0 评论 -
D18 D19 缺
如题。缺。原创 2018-01-20 23:17:52 · 178 阅读 · 0 评论 -
LDD3 D23 01.23 星二
21:20-22:05 20p【没读明白,设备模型的用途。以及怎样实现自己驱动程序的设备模型】 第十四章 Linux 设备模型 设备模型使得操作系统能按照一个正确顺序遍历硬件。通过sysfs,设备模型用用户空间提供系统信息。通过设备模型支持热插拔设备模型包括一个机制来给设备分配类别, 它在一个更高的功能性的级别上描述了这些设备, 并且允许它们对用户空间可见.设备原创 2018-01-23 22:43:44 · 260 阅读 · 0 评论 -
D22 补
30m 10p注册一个PCI驱动为了被正确注册到内核, 所有的 PCI驱动必须创建的主结构是 struct pci_driver 结构. 使能PCI 设备在 PCI 驱动的探测函数中, 在驱动可存取PCI 设备的任何设备资源(I/O 区或者中断)之前, 驱动必须调用 pci_enable_device 函数: intpci_enable_device(struct p原创 2018-01-22 22:19:27 · 164 阅读 · 0 评论 -
LDD3 D10 补
10:32-11:40 20p第6章 高级字符驱动操作ioctl 接口在用户空间, ioctl 系统调用有下面的原型: int ioctl(int fd, unsigned long cmd, ...); 原型中的点并不表示可变参数, 而是一个单个可选的参数, 传统上标识为 char *argp. 这些点在那里只是为了阻止在编译时的类型检查.第三个参数的类型,取决于第二原创 2018-01-11 11:30:54 · 177 阅读 · 0 评论 -
D11 补
09:24- 10:26 20p poll 和select使用非阻塞 I/O的应用程序常常使用 poll, select, 和 epoll 系统调用. poll, select 和 epoll 本质上有相同的功能:每个允许一个进程来决定它是否可读或者写一个或多个文件而不阻塞. 驱动程序函数原型:unsigned int(*poll) (struct file *filp原创 2018-01-12 10:24:31 · 185 阅读 · 0 评论 -
D12 补
09:26-10:4020p处理器特定的寄存器损失可移植性,提高时间精度 获知当前时间内核一般通过jiffies值来获取当前时间。 驱动程序一般不需要知道墙鈡时间,即年月日时分秒。 有一个内核函数转变一个墙上时钟时间到一个jiffies 值, 是:#include unsigned long mktime(unsigned int year, unsig原创 2018-01-13 12:19:12 · 178 阅读 · 0 评论 -
Sprint 1 done
200p完成。做得好:坚持写博客。提醒自己完成进度。做的不好:有很多补,说明当天没能按时完成进度每天1-1.5小时,只够读书。书上代码,例子没有时间练习。原创 2018-01-13 12:22:09 · 181 阅读 · 0 评论 -
LDD3 D02 2018.01.02 星二
21:21-22:14 60m p21-p42第二章构造和运行模块设置测试系统读者首先要准备好一个内核源代码树。【Q:怎样准备?】 Helloworld模块内核需要自己单独的打印输出函数,这是因为它在运行时不能依赖C库。【Q:为什么?】 核心模块和应用程序相比模块只是预先注册自己以便服务于将来的某个请求。模块的退出函数必须仔细撤销初始化函原创 2018-01-02 23:44:48 · 152 阅读 · 0 评论 -
LDD3 D03 补
15:02-16:47 90m 18p 第3章 字符驱动模块化的字符驱动什么是模块化? scull的设计编写驱动的第一步是定义驱动将要提供给用户程序的能力(机制)。全局意味着如果设备被多次打开,设备中含有的数据由所有打开他的文件描述符共享。永久意味着如果设备关闭又重新打开,数据不会丢失。 主次编号支付设备通过文件系统的名字来存取。这些名字被称为文件系原创 2018-01-04 16:49:03 · 188 阅读 · 0 评论 -
LDD3 D04 2018.01.04 星四
22:05-22:40 35m p64-p75 Scull 的内存使用 为了彻底理解代码,我们需要知道“如何分配”,而“为何分配”则表明驱动程序编写所需做出的选择。 两个核心函数 kmalloc()和 kfree()将NULL 指针传给 kfree 是合法的。 scull 设备的布局, 每个内存区被称为一个量子,是多大?怎样理解 ? 使用宏和整数值同时原创 2018-01-04 23:16:04 · 170 阅读 · 0 评论 -
D21 补
50m 20p第11 章 内核中的数据类型标准C 类型的使用尽量避免使用 int之类标准类型,因为它是平台相关的。即不同平台占用的字节数可能不同。 ## 安排一个明确大小给数据项内核提供了下列数据类型来使用。所有的数据声明在 , 它又被 包含.u8; /* unsigned byte (8bits) */u16; /* unsigned word(16 bits)原创 2018-01-22 22:18:56 · 192 阅读 · 0 评论 -
D20 补
22:05-22:55 20p实现中断处理例程中断处理例程也是一个c程序唯一的特别之处是一个它在中断时运行, 因此, 它能做的事情遭受一些限制. 这些限制与我们在内核定时器上看到的相同. 一个中断处理例程不能传递数据到或者从用户空间拷贝数据, 因为它不在进程上下文执行. 它也不能做任何可能睡眠的事情, 例如调用 wait_event, 使用除 GFP_ATOMIC 之外任何东西原创 2018-01-20 23:18:22 · 211 阅读 · 0 评论