Understanding the `extern` keyword in C language

Introduction Almost every programmer knowns C language since it's usually the first programming language they learned. However, C is very hard to gain a deeper understanding because of its low-level property. In this article, we will focus on the extern keyword and find out its essence. Before we explain extern…

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…

C 语言中的元素指针与一维数组指针

在我上大三的时候,有段时间发现自己对指针的理解不够深入,所以就看了《Pointers On C》这本书的指针章节,当时印象很深刻的是接触到了一维数组指针这个概念,5月19号我在看内核代码时又遇到了这个问题,结果一时间竟然没看懂,搜了资料才想起来这么个概念。 举个例子: #include<stdio.h> void main() { int boot_gdt[] = {1,2,3}; int *a = boot_gdt; int *b = &boot_gdt; printf("%x\n",a); printf("%x\n",b); } 两个输出语句会输出同样的结果,一开始我大为不解,然后 Google…

博客迁移说明

今天正式从 CSDN 博客迁移到自建博客了,CSDN 虽然博主众多,气氛也还算不错,但是独立博客的自由度是公共博客平台所无法企及的。早在一年前我就用 Ghost Blog 自建了一个写随笔的博客,那时候只是写着玩,也没想过把技术博客也迁移到 Ghost 上来,但是前一阵子我购入了 haolee.io 这个新域名之后,我就下决心维护两个独立博客,一个写随笔用,记录生活中一些乱七八糟的事情,一个写技术文章,记录自己的成长历程。独立博客还有一个好处就是会让自己更加用心的维护,毕竟这就相当于个人的简历一样。 CSDN 的博客我这一两年没写几篇文章,主要是动力不足,很多都写成笔记存在了电脑里,没有整理出来,现在开了独立博客之后我要更加勤快的写博文,一方面是为自己留个笔记,另一方面这会加深我对一些知识的理解,也说不定能对别人起到一定的帮助作用。 CSDN 上有 54 篇历史博文,我没有都迁移过来而是挑选了 15 篇,因为当年写的很多博文实在是太浅显了,实在不好意思都搬过来。…

实例示范如何向 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.…