linux 内核0.11阅读困惑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 内核0.11阅读困惑相关的知识,希望对你有一定的参考价值。

linux内核阅读,遇到的几点困惑,参考书籍《linux内核完全解析》(赵炯著,电子版第五章内核代码)
1、在ASM中(参考的是赵博士的linux 0.11完全解析 电子版),图5-3显示, fs先入栈,ebx后入栈,(如果我没理解错的话,堆栈地址是从上往下递增的)但是在代码ASM23---31行,先pushl %ebx,再pushl %fs,不知道是不是这是 AT&T汇编的语法格式,我查到的资料 没有这种语法,还有按照书上图5--1,原SS、原ESP、EFLAG、CS和EIP应该是最后入栈的(例证是图5--1(b)出错码在EIP之下),但是图5--3如何做到,移动EIP0(即原始EIP),而原SS、原ESP、EFLAG、CS,在原位置,偏移不变呢,这不符合堆栈原理啊?
2、tarp.c中最后的trap init 205——206行,不理解 outb_p(inb_p(0x21)&oxfb,0x21);和 outb_p(inb_p(0xA1)&oxdf,0xA1)
3、trap.c中24行pushl %%fs,此处为什么有两个%,不解,求指教!

1、你说的“图5-3显示, fs先入栈,ebx后入栈”是不对的,恰好反了。
书上原话"在开始执行程序之前,堆栈指针 esp 指在中断返回地址一栏 ( 图中 esp0 处 ) 。当把将要调用的 C 函数do_divide_error()或其它 C 函数地址入栈后,指针位置是 esp1 处",这已经说明esp0的地址高于esp1的地址。同理ebx地址高于fs地址,即ebx先入栈。
2、3都是关于gnu内嵌汇编问题,需要自己看书的。
#define outb_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:"::"a" (value),"d" (port))
相当于:
mov (value),%eax
mov (port),%edx
outb %al,(%dx)
就是给某个端口port发数据value的,<<微机接口>>里很多例子,例如给中断控制器8259A初始化就是这样做的。
参考技术A 这个好像有点复杂 参考技术B 第三个是内联汇编的写法吧追问

en

追答

内联汇编规定吧,查查书应该有

第二个 outb_p(inb_p(0x21)&oxfb,0x21);估计就是先in 后out吧 ,inb_p返回值是什么?它是函数还是宏定义?

追问

就是 些端口和读端口

Linux 内核/驱动程序开发新手

【中文标题】Linux 内核/驱动程序开发新手【英文标题】:New to Linux Kernel/Driver development 【发布时间】:2011-02-10 15:19:46 【问题描述】:

最近,我开始开发运行 linux 的嵌入式设备的驱动程序。

到目前为止,我只阅读有关 linux 内部结构的信息。 由于没有驱动程序开发方面的经验,我发现迈出第一步有点困难。

我已经下载了内核源代码 (v2.6.32)。 我已阅读(略读)Linux 设备驱动程序 (3e) 我在 *** 上阅读了一些相关帖子。 我了解 linux 采用“单片机”方法。 我已构建内核(在 menuconfig 等中包含现有驱动程序) 我知道 kconfig 和 makefile 文件的基础知识,所以这应该不是问题。

有人可以描述结构(即相互链接) 内核源代码中的各个目录。

换句话说,给定一个源代码文件, 相关代码会参考哪些其他文件

(“#include”-s 提供了部分想法)

有人可以帮我想出一个更好的主意吗? 任何帮助将不胜感激

谢谢。

【问题讨论】:

这应该清除它。 youtube.com/watch?v=ENNKtfR2PYc 为内核编写一个简单的模块Hello World。然后,一旦你理解了 Hello World Kernel Module,就写下这个freesoftwaremagazine.com/articles/drivers_linux 并测试它。按照上面的链接,直到你不明白为止。并在这里阅读了我的两篇帖子mail.nl.linux.org/kernelnewbies/2010-09 我真的在论坛上努力了解它是如何工作的。所以你必须做同样的事情。不管任何人说什么,直到你不明白为止。学习的最好方法是拿起一个项目并开始工作,最后你会得到很多。例如决定修复一个 内核中无线驱动程序的错误。我知道在这个阶段这听起来很奇怪,但一直追到你做为止。在最后你将能够做到。 @realitydisplays 我知道这很长一段时间,但我的情况与 OP 相似。您共享的那 2 个链接不再有效。您能提供最新的链接吗? 【参考方案1】:

给定一个 C 文件,您必须查看它调用的函数和它使用的数据结构,而不是担心特定的文件。

开发自己的设备驱动程序有两种基本途径:

选择和你类似的驱动;去掉不适用于您设备的代码,并为您的设备填写新代码。 从设备驱动程序的最基本部分开始,然后一次添加一点,直到您的设备开始运行。

当您完成此过程时,构成您的驱动程序的文件将更有意义。请考虑每个文件中的内容,但在某种程度上,在文件之间划分驱动程序与其说是科学,不如说是一门艺术。较小的驱动程序通常只适合一两个文件。

一点设计也可能很好。考虑您的设备做什么,以及您的驱动程序需要做什么。在此基础上,您应该能够规划出设备驱动程序需要具备哪些功能。

我也相信Linux Device Drivers, Third Edition 可以帮助您走上驱动程序开发的道路。

Linux 文件本身包含的文件基于它们的功能、它们所在的层以及它们访问调用堆栈的层。大图真正告知每个文件与下一个文件的关系。

【讨论】:

感谢您的推荐。今晚会仔细阅读这本书。还有什么??任何人的实用演练??... 真正的专家需要多读几页才能浏览内核...最重要的是,内核的许多部分变化迅速,因此一旦写入就没有数据。最好的办法是阅读和理解您感兴趣的子系统。【参考方案2】:

我不得不修复内核驱动程序一次。我最大的建议(如果你使用 vim)是用 ctags 设置它,这样每次看到你不理解的函数时,你就可以用 ctrl-] 跳转内核源代码。

【讨论】:

...这样做已经有一段时间了!它确实很有帮助!

以上是关于linux 内核0.11阅读困惑的主要内容,如果未能解决你的问题,请参考以下文章

Linux 0.11源码阅读笔记-总览

Linux 0.11源码阅读笔记-文件管理

Linux内核创建一个进程的过程分析

Linux 0.11内核编译错误记录

Linux 内核Linux 内核源码结构 ( 下载 Linux 内核源码 | 使用 VSCode 阅读 Linux 内核源码 )

Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析