参考:
http://www.oldlinux.org (对老版本 Linux 的研究,站长的 <Linux 内核完全注释> 一书很有帮助)
http://www.kernel.org ( Linux 内核源代码各个版本和一些工具、文档下载的官网)
http://www.gnu.org (下面用到的 GNU 的工具系列的手册,可以在这找到的)
http://ftp.gnu.org/gnu ( GNU 的工具下载 URL)
http://bochs.sourceforge.net (一种虚拟机用他来运行编出来的 Linux)
http://www.google.com (TMD 再不行就问他了)
http://www.kernel.org ( Linux 内核源代码各个版本和一些工具、文档下载的官网)
http://www.gnu.org (下面用到的 GNU 的工具系列的手册,可以在这找到的)
http://ftp.gnu.org/gnu ( GNU 的工具下载 URL)
http://bochs.sourceforge.net (一种虚拟机用他来运行编出来的 Linux)
http://www.google.com (TMD 再不行就问他了)
以下为 Linux 0.11 版本的源代码下载 URL:
编译环境的准备:
首先需要建立编译环境,会用到的主要工具基本有:
1. as86 (Assembler for 8086..80386 processors, 8086 汇编编译器)
2. ld86 (Linker for as86, as86 的连接器)
3. as (portable GNU assembler, GNU 汇编编译器,区别于上面的 as86,这个要用 AT&T 汇编语法)
4. ld (the GNU linker, GNU 连接器)
5. gcc (GNU project C and C++ compiler, GNU 的 C/C++ 编译器)
6. cpp (The C Preprocessor, C 语言的预编译器)
7. ar (create, modify, and extract from archives, 归档工具)
8. make (Makefile 文件的解释工具)
9. dd (convert and copy a file, 文件复制的一种工具)
10. tar (功能很多这里应该只用到了他文件打包,解包的功能)
2. ld86 (Linker for as86, as86 的连接器)
3. as (portable GNU assembler, GNU 汇编编译器,区别于上面的 as86,这个要用 AT&T 汇编语法)
4. ld (the GNU linker, GNU 连接器)
5. gcc (GNU project C and C++ compiler, GNU 的 C/C++ 编译器)
6. cpp (The C Preprocessor, C 语言的预编译器)
7. ar (create, modify, and extract from archives, 归档工具)
8. make (Makefile 文件的解释工具)
9. dd (convert and copy a file, 文件复制的一种工具)
10. tar (功能很多这里应该只用到了他文件打包,解包的功能)
源代码的修改和编译:
由于历史悠久, Linux 0.11 代码在不做修改的情况下,很难在现在的环境下这接编译通过(除非你能的到 10 几年前 Linus 用的那个版本的 gcc 什么的)。所以要对代码作少量修改(说说是少量花了好几小时的,主要是一上来不熟 gcc 的内嵌汇编)。
我修改后可以顺利编译的源代码 http://lexx.51.net/oldlinux/mod-linux-0.11.tar.gz
(出错不负任何责任,编译环境 gcc-3.2 as-2.13 as86-0.16 ld-2.13 ld86-0.16 ar-2.13)
改动主要有这几个方面:
1. Makefile 的修改, 把所有 Makefile 里的 gas 换成 as, gld 换成 ld.(as 和 ld 这两个兄弟以前叫 gas 和 gld 的)
2. Makefile 的修改, 把所有 Makefile 里 CFLAGS 里面的 -fcombine-regs 和 -mstring-insns (-fcombine-regs 据说是老版 gcc 特有的,至于 -mstring-insns 更牛 Linus 为某种目的为 gcc 加出来的,实在是佩服的五体投地)
3. Makefile 的修改, 把所有 Makefile 里 "$(AS) -c -o $*.o $<" 这句中的 -c 去掉 (现代版的 as 已经不要 -c 这个选项了)
4. 8086 汇编代码修改, 把所有用 as86 编译的 .s 文件中的 C 语言注释,换成 ! (感叹号)方式的,汇编注释方式. (因为现在的 as86 不兼容 C 风格注释了)
5. 汇编代码修改, 把所有 .align 语句后面的数字变成以他为幂的 2 的次方.比如原来 .align 3 就应该变为 .align 8 (因为语法变了,以前写的是 2 的次方,现在直接写几了)
6. 汇编代码修改, 把所有在汇编中调用 C 函数或者变量的前导下划线去掉.同时把汇编中输出给 C 函数使用的变量和函数的前导下划线去掉.(举例说以前 C 里面有一个函数叫 strcpy 如果在以前汇编里面要调用就要写成 call _strcpy,但现在则可以写成 call strcpy 了)
7. 内嵌汇编代码修改,主要是要去掉人工 cpu 寄存器的修改.这部分工作量比较大.这个很难说明,举两个例子
1) register int __res __asm__("ax"); /* 原来的内嵌需要人工制定用那个寄存器 */
register int __res; /* 现在的编译器不用了所以就去掉 */
1) register int __res __asm__("ax"); /* 原来的内嵌需要人工制定用那个寄存器 */
register int __res; /* 现在的编译器不用了所以就去掉 */
2) __asm__("cld\n\t" /* 原来的最后有对修改寄存器的说明 */
"rep\n\t"
"stosb"
::"a" (c),"D" (s),"c" (count)
:"cx","di");
"rep\n\t"
"stosb"
::"a" (c),"D" (s),"c" (count)
:"cx","di");
__asm__("cld\n\t" /* 现在的编译器不用了所以就去掉 */
"rep\n\t"
"stosb"
::"a" (c),"D" (s),"c" (count));
"rep\n\t"
"stosb"
::"a" (c),"D" (s),"c" (count));
一些疑惑的地方修改(为了编译同过我改了,不过不知道为什么):
1. panic 函数的声明. panic 函数在两处有声明分别是 include/linux/sched.h 里声明为 extern void panic(const char * str);. 另一处 include/linux/kernel.h 里声明为 volatile void panic(const char * str);. kernel.h 里多了 volatile 描述符,所以我的编译器提醒我类型冲突.后来在 sched.h 里同样添加 volatile 描述符才通过.
1. panic 函数的声明. panic 函数在两处有声明分别是 include/linux/sched.h 里声明为 extern void panic(const char * str);. 另一处 include/linux/kernel.h 里声明为 volatile void panic(const char * str);. kernel.h 里多了 volatile 描述符,所以我的编译器提醒我类型冲突.后来在 sched.h 里同样添加 volatile 描述符才通过.
2. kernel/chr_drv/keyboard.S 的 47 行,为:
xorl %al,%al /* %eax is scan code */
xorl %al,%al /* %eax is scan code */
可是按照语法来说明显是 xorb %al,%al. (会有这么明显得错误吗?一直搞不懂)
3. include/string.h 里面的 memcpy 函数无论如何修改 (去掉修改寄存器的说明,去掉 inline 描述符等)在调用出都会编译错误,后来把 memcpy 的实现直接放到了调用出(总共 4 个地方)才得以通过,不过心有余悸好像会错的.
4. tools/build.c 的修改,在最后的 build 工具中有一段对 system 文件的验证,就是指 build.c 的第 158 行,在我这永远通不过,我想可能是因为 gcc 版本变了的原因,暂时把它去掉了,不过心有余悸好像会错的.
5. build 参数的修改,build 参数的最后一个指定一个根设备,我把它改成了空使 build 工具使用默认的设备号,不过心有余悸好像会错的.
如果一切都顺利修改完后再 make 一遍就应该得到 Image 文件了
节外生枝的问题:
1号问题: AT&T 汇编语法,由于以前学校教的是 Intel 汇编所以 AT&T 和 GCC 内嵌的 AT&T 看得真是头晕
2号问题: 就是我之前描述的一些心有余悸的修改
最大问题: 把我现在的 Image 再虚拟机(决定是 Bochs)上运行出来
2号问题: 就是我之前描述的一些心有余悸的修改
最大问题: 把我现在的 Image 再虚拟机(决定是 Bochs)上运行出来