Does each process has its own linear space?

In the last article we have illustrated the concept of linear address and in this blog I will try to explain some details about linear space. Linear space consist of linear addresses. Though this concept is very straightforward, some people may be confused with it when they consider multiple linear…

logical address, virtual address, linear address and physical address

In this article, I want to illustrate the relationship between the logical address, virtual address, linear address and physical address. These three concepts are very easy to confuse. Many people learn these concepts from operating system books, but these books can't explain them on a very low level. Apart from…

fdisk 的分区对齐问题

6月29号,我在制作 Bochs 磁盘镜像时遇到个不理解的地方,那就是磁盘扇区编号问题。 比如用fdisk命令给磁盘镜像分区后,第一分区是从第63号扇区开始的,按照 CHS 编号方式来看,这并不能产生分区对齐效果,因为扇区编号从1开始,那么第63扇区是本磁道最后一个扇区,这就很奇怪了,分区对齐应该是在对齐到一个磁道的开头才对,怎么对齐到末尾去了。还有用 losetup 命令挂载第一分区时,难道不是应该跳过 1-62 扇区吗,为什么正确的命令却是 losetup -o $((63*512)) /dev/loop0 hd.img,这不就跳过了63个扇区吗,跳多了。 Google 了一番之后我找到了这个问答:https://superuser.com/questions/352572/why-does-the-partition-start-on-sector-2048-instead-of-63/466186?newreg=692994d940e34813a91fdbdeb410b0ef#comment388140_352583 在它的评论里里提到了 fdisk 使用的是 LBA…

Linux 内核中的函数传参规约

一个月前的6月27号,在一个内核技术交流群里有朋友提出了一个问题,详细情况如下: 在《Linux 源代码内核情景分析》的第 372 页,有一段进程切换的汇编函数 switch_to,在这里面调用了一个C语言函数 __switch_to(374 页),这个C语言函数需要接受两个参数,奇怪的是在汇编代码里看不到这两个参数,虽然有一次压栈动作,但那是为 __switch_to 的 return 语句准备的,那这个C语言函数的两个参数到底是哪里传过来的呢。 这使我想起了在《Linux Inside》里面有一节提到的一种传参方式,名字叫 fastcall calling conventions,也就是使用 ax、dx、cx 这三个寄存器来传递第一二三个参数。如果真是这样的话,那就可以解释这个函数的参数传递了,因为这段汇编的输入数据恰好是放在 EAX 和 EDX 寄存器里的,而且数据类型和含义也与C语言函数 __switch_to…

实例示范如何向 Linux Kernel 提交 Patch

昨晚终于向内核上游提交了人生中第一个 Patch,今天早上起床迫不及待的看手机,发现维护者 Andrew Morton 在6点31分回复我了:The patch has been added to the -mm tree. 顿时感到异常兴奋。虽然这个 Patch 没什么技术含量,但是至少这是我在看代码过程中自己发现的,终于体会到了进步的感觉。下面我把 Patch 提交的步骤记录一下,也供别人参考下。 Git Email 配置 为了确保发送的 Patch 格式不会出错,我们使用 Git 自身提供的命令 git send-email。 安装 git send-email 我用的 Fedora,安装命令为 sudo dnf install git-email,其他系统请自行使用 yum 或…

如何向 Linux 内核上游提交 Patch ?

在GitHub上有本内核电子书叫《Linux Inside》,虽然完成度不高但还是很火的,它还有了自己的中文版翻译项目,我也参与了该项目的翻译工作,以下内容即为该书第 13.3 节的翻译版,主要讲解了怎么修改内核、生成 Patch 并提交给上游。 LICENSE Licensed BY-NC-SA Creative Commons. Linux 内核开发 简介 如你所知,我从去年开始写了一系列关于 x86_64 架构汇编语言程序设计的博文。除了大学期间写过一些 Hello World 这样无实用价值的程序之外,我从来没写过哪怕一行的底层代码。那些程序也是很久以前的事情了,就像我刚才说的,我几乎完全没有写过底层代码。直到不久前,我才开始对这些事情感兴趣,因为我意识到我虽然可以写出程序,但是我却不知道我的程序是怎样被组织运行的。 在写了一些汇编代码之后,我开始大致了解了程序在编译之后会变成什么样子。尽管如此,还是有很多其他的东西我不能够理解。例如:当 syscall 指令在我的汇编程序内执行时究竟发生了什么,当 printf 函数开始工作时又发生了什么,…

使用bochs和gdb联合调试Linux内核

bochs这个软件准确来说应该叫做“模拟器”,而不是虚拟机,因为VMware等虚拟机是将Guest系统所有的指令都放到真实硬件上执行,而bochs模拟器则是直接用软件模拟硬件的执行,举个例子,在bochs里你可以自定义CPU指令并在汇编里使用,这一条足以说明bochs是多么强大,实在是操作系统开发者首选的利器。 bochs安装 上一篇博文讲了DDD的安装,这一篇博文先将讲bochs的安装,之后再说联合调试。下载bochs解压后进入目录。 ./configure --enable-gdb-stub make make install 搞定,系统里面又多了一个命令bochs bochs配置 这里依然使用之前的博文制作出来的hd.img可启动内核镜像,这里面包含2.4.0内核。为了清楚起见我把bochs配置过程在这里再写一遍,这个过程与之前单纯的运行内核时有所不同,之前我们只想运行内核,现在我们要调试内核,所以多了第4步。 运行bochs命令会出现命令行菜单,选择3. Edit options开始编辑配置,进入12. Disk & Boot options,把4. First HD/CD on channel 0设为hd.img,这个过程需要输入hd.…

使用bochs运行Linux Kernel-2.4.0

上一篇博文讲了如何制作bochs硬盘镜像并且将grub装进去,这样我们可以在启动bochs后进入到grub界面。 这篇博文我们将2.4内核写入硬盘镜像,这就可以使用bochs直接启动内核了。 我的实验系统是这么部署的:CentOS 6.4 VMware虚拟机上修改代码和配置文件,用git做版本管理,同时还开着另一台虚拟机RedHat Linux 7.3,专门用来编译内核代码,毕竟2.4内核很老了,编译环境不能使用现代Linux系统,必须使用2001年左右的系统。每次在CentOS上修改完代码或配置就在RedHat上用rsync将数据同步下来,进行编译、安装、测试,这样最方便。用于开发的系统不必反复重启,用于编译的系统就是实验平台。 编译内核*(这一步在RedHat上进行)* 这一步在这里就不展开讲了,我对内核做了精简,不必要的选项全部关闭了,大大缩短了编译时间。其中, Block devices ---> RAM disk support 这个选项也被我关闭了,那内核启动的时候自然就不需要Initial RAM disk (initrd)了,所以待会儿更改grub.conf的时候不用配置下面这一行了。 initrd…

使用bochs和grub建立可引导硬盘镜像

bochs,发音同box,是我非常喜欢的虚拟机,灵活易用方便配置,功能极强,用来调试Linux内核是非常合适的。这篇博文主要讲解如何建立硬盘镜像,并且将grub安装上去,最后的结果就是bochs启动后能进入到grub引导界面。下一篇博客再讲解如何在镜像上安装Linux内核。 实验环境: CentOS 6.4 x86 硬盘基础知识 硬盘的专业术语中有:柱面,磁头,扇区,每磁道扇区数这几个概念。 每个盘片有两个磁头(Head),分别位于两面上,从0开始依次编号,一般来说硬盘有8个盘片,共计16个磁头,编号0-15。 每个盘面都有很多同心圆轨道称为磁道(Tracks),所有盘面上半径相同的磁道正好堆叠成一个圆柱面,称为柱面(Cylinders),它和磁道编号相同,都是自外向内从0开始编号。 每个磁道上划分出很多弧段,称为扇区(Sectors),每个磁道上的扇区都从1开始编号,每个扇区512字节,一个磁道一般有63个扇区,编号1-63。 磁盘定位可以使用CHS方法,即柱面、磁头、扇区。比如MBR的CHS=0/0/1,…

Kernel 2.4.0 之 head.S 为何用两次 jmp 刷新 EIP 寄存器

在arch\i386\kernel\head.S文件中,自line 100开始有这么几行: movl %cr0,%eax orl $0x80000000,%eax movl %eax,%cr0 /* ..and set paging (PG) bit */ jmp 1f /* flush the prefetch-queue */ 1: movl $1f,%eax jmp *%eax /* make sure eip is relocated */ 1: /* Set up the stack pointer */ lss stack_start,%esp 我看了很久都不明白第一次跳转到底是为了什么,情景分析那本书上说这是为了刷新指令预取队列,我把Intel手册翻了个遍也没找到关于预取队列的详细信息,…