编译是个很蛋疼的事情,本想把linux0.0.1在Ubuntu上跑起来然后就可以各模块的学习,没想各种问题。
问题1:
1 gas -c -o boot/head.o boot/head.s 2 make: gas: Command not found
gas已过时,将所有Makfile里gas -> as
具体解决方法
1
|
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 `push' 10 boot/head.s:151: Error: invalid instruction suffix for `push' 11 boot/head.s:152: Error: invalid instruction suffix for `push' 12 boot/head.s:153: Error: invalid instruction suffix for `push' 13 boot/head.s:154: Error: operand type mismatch for `push' 14 boot/head.s:155: Error: operand type mismatch for `push' 15 boot/head.s:161: Error: invalid instruction suffix for `push' 16 boot/head.s:163: Error: invalid instruction suffix for `pop' 17 boot/head.s:165: Error: operand type mismatch for `pop' 18 boot/head.s:166: Error: operand type mismatch for `pop' 19 boot/head.s:167: Error: invalid instruction suffix for `pop' 20 boot/head.s:168: Error: invalid instruction suffix for `pop' 21 boot/head.s:169: Error: invalid instruction suffix for `pop' 22 boot/head.s:214: Error: unsupported instruction `mov' 23 boot/head.s:215: Error: unsupported instruction `mov' 24 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;