linux0.12 编译过程

编译是个很蛋疼的事情,本想把linux0.12在bochs上跑起来然后就可以各模块的学习,没想各种问题。

问题1:

1 gas -c -o boot/head.o boot/head.s
2 make: gas: Command not found

gas已过时,将所有Makfile里gas -> as

具体解决方法

msed gas as

msed 是个简单的shell 函数,具体定义见下面的传送门。

传送门:http://www.cnblogs.com/strugglesometimes/p/4231348.html

问题2:

 1 boot/head.s:43: Error: unsupported instruction `mov 2 boot/head.s:47: Error: unsupported instruction `mov 3 boot/head.s:59: Error: unsupported instruction `mov 4 boot/head.s:61: Error: unsupported instruction `mov 5 boot/head.s:136: Error: invalid instruction suffix for `push 6 boot/head.s:137: Error: invalid instruction suffix for `push 7 boot/head.s:138: Error: invalid instruction suffix for `push 8 boot/head.s:139: Error: invalid instruction suffix for `push 9 boot/head.s:140: Error: invalid instruction suffix for `push10 boot/head.s:151: Error: invalid instruction suffix for `push11 boot/head.s:152: Error: invalid instruction suffix for `push12 boot/head.s:153: Error: invalid instruction suffix for `push13 boot/head.s:154: Error: operand type mismatch for `push14 boot/head.s:155: Error: operand type mismatch for `push15 boot/head.s:161: Error: invalid instruction suffix for `push16 boot/head.s:163: Error: invalid instruction suffix for `pop17 boot/head.s:165: Error: operand type mismatch for `pop18 boot/head.s:166: Error: operand type mismatch for `pop19 boot/head.s:167: Error: invalid instruction suffix for `pop20 boot/head.s:168: Error: invalid instruction suffix for `pop21 boot/head.s:169: Error: invalid instruction suffix for `pop22 boot/head.s:214: Error: unsupported instruction `mov23 boot/head.s:215: Error: unsupported instruction `mov24 boot/head.s:217: Error: unsupported instruction `mov

这是由于在64位机器上编译的原因,需要告诉编译器,我们要编译32位的code,在所有Makefile的AS后面添加 --32,CFLAGS中加-m32

具体解决方法

msed as$ as\ --32
msed -O -O\ -m32

问题3:

boot/head.s: Assembler messages:
boot/head.s:231: Error: alignment not a power of 2
make: *** [boot/head.o] Error 1

 把align n -> align 2^n

具体解决方法

sed -i s/align 2/align 4/g boot/head.s
sed -i s/align 3/align 8/g boot/head.s

问题4:

gcc: error: unrecognized command line option ‘-fcombine-regs’
gcc: error: unrecognized command line option ‘-mstring-insns’

把这两个删掉即可,现在GCC已经不支持了

具体解决方法

msed -fcombine-regs \ 
msed -mstring-insns \ 

问题5:

额。。。。为了更快的找到Error的地方,我把所有的warning 都关掉了即在CFLAGS 中加-w

具体解决方法

msed -Wall -w

问题6:

In file included from init/main.c:8:0:
init/main.c:23:29: error: static declaration of ‘fork’ follows non-static declaration
 static inline _syscall0(int,fork)
                             ^
include/unistd.h:151:6: note: in definition of macro ‘_syscall0’
 type name(void)       ^
init/main.c:24:29: error: static declaration of ‘pause’ follows non-static declaration
 static inline _syscall0(int,pause)
                             ^
include/unistd.h:151:6: note: in definition of macro ‘_syscall0’
 type name(void)       ^
include/unistd.h:241:5: note: previous declaration of ‘pause’ was here
 int pause(void);
     ^
init/main.c:26:29: error: static declaration of ‘sync’ follows non-static declaration
 static inline _syscall0(int,sync)
                             ^
include/unistd.h:151:6: note: in definition of macro ‘_syscall0’
 type name(void)       ^
include/unistd.h:252:5: note: previous declaration of ‘sync’ was here
 int sync(void);

这里是由于include/unistd.h 中声明了一次pause() sync() fork(), 而在main.c 中通过宏又定义了这三个函数,但定义时多了static 限定,与声明不同,所以出错。所以直接把unistd.h中的声明去掉。

问题7:

init/main.c:179:12: error: static declaration of ‘printf’ follows non-static declaration
 static int printf(const char *fmt, ...)

这个问题困扰了好久,网上的解决方案都是把static去掉,但是这样做,后面在链接的时候会出现另一个错误undefined reference to ‘_put‘. 新的问题是由于GCC会对printf进行优化,把无参的printf优化成put,而linux0.12的libc中又没有实现put才会导致新的问题。那么现在回到这个问题上,猜测应该也是由于GCC本身对printf这个函数名有特别的关照所致,所以把printf稍微改下名,printf -> printw。发现果然就编译通过了。

具体解决方案:

sed -i s/ printf/ printw/g init/main.c

问题8:

init/main.c: In function ‘main’:
init/main.c:176:3: error: ‘asm’ operand has impossible constraints
   __asm__("int $0x80"::"a" (__NR_pause):"ax");

类似的问题在后面编译中出现好多,C内嵌汇编的格式__asm__(汇编语句:输入寄存器:输出寄存器:可能被修改的寄存器),最新的GCC规定输入输出寄存器不能出现在可能被修改的寄存器中,目前看到网上的方法是把所有类似问题的可能被修改的寄存器全部删掉。

具体解决方法

find -type f -exec sed -i s/:\"\w\{2\}\"\(,\"\w\{2\}\"\)*)/:) /g {} \;

问题9:

make[1]: gld: Command not found

同gas, 把gld -> ld

具体解决方法

msed gld ld

问题10:

ld -r -o kernel.o sched.o sys_call.o traps.o asm.o fork.o panic.o printk.o vsprintf.o sys.o exit.o signal.o mktime.o
ld: Relocatable linking with relocations from format elf32-i386 (sched.o) to format elf64-x86-64 (kernel.o) is not supported

 同问题2,告诉ld以32位链接,在ld命令后面加 -m elf_i386

具体解决方法

msed ld$ ld\ -m\ elf_i386

问题11:

../include/asm/segment.h: Assembler messages:
../include/asm/segment.h:27: Error: bad register name `%sil

去segment.h 的第27行找,没找到sil相关的东西,根据网上的方法,把=r或r 改成=q或q,果然就好了,这里应该是编译器造成的,r表示任意寄存器,在编译的时候就用了sil这个寄存器,可为什么无效还会被用到呢。q表示使用eax,ebx,ecx,edx中任意一个。

具体解决方法

sed -i s/r"/q"/g include/asm/segment.h

问题12:

exec.c: In function ‘copy_strings’:
exec.c:162:44: error: lvalue required as left operand of assignment
         !(pag = (char *) page[p/PAGE_SIZE] =
if (!(pag = (char *) page[p/PAGE_SIZE]) &&
    !(pag = (char *) page[p/PAGE_SIZE] =
      (unsigned long *) get_free_page())) 
    return 0;

以上是原始code,以下是OK的code

if ((!page[p/PAGE_SIZE]) &&                                                                                                      
    !(page[p/PAGE_SIZE] =
      (unsigned long *) get_free_page()))                                                                                       
    return 0;                                                                                                                   
else                                                                                                                            
    pag = (char *) page[p/PAGE_SIZE];

问题13:

In file included from floppy.c:42:0:
blk.h:90:6: error: #elif with no expression
 #elif

这里把第90行的#elif -> #else

问题14:

make[1]: gar: Command not found

老问题了,gar -> ar

msed gar ar

问题15:

malloc.c: In function ‘malloc’:
malloc.c:156:46: error: lvalue required as left operand of assignment
   bdesc->page = bdesc->freeptr = (void *) cp = get_free_page();

和问题12一样

bdesc->page = bdesc->freeptr = (void *) cp = get_free_page();

上面是原始的,下面是OK的,把代码拆分下就好

cp = get_free_page();
bdesc->page = bdesc->freeptr = (void *) cp;

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。