编译运行linux0.12,linux0.12 编译过程
感謝這篇文章的作者:??? http://www.cnblogs.com/strugglesometimes/p/4231359.html
編譯是個很蛋疼的事情,本想把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 是個簡單的shell 函數(shù),具體定義見下面的傳送門。
問題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’
把這兩個刪掉即可,現(xiàn)在GCC已經(jīng)不支持了
具體解決方法
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: indefinition 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: indefinition of macro ‘_syscall0’
type name(void) ^include/unistd.h:241:5: note: previous declaration of ‘pause’ was here
intpause(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: indefinition 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 中通過宏又定義了這三個函數(shù),但定義時多了static 限定,與聲明不同,所以出錯。所以直接把unistd.h中的聲明去掉。
問題7:
init/main.c:179:12: error: static declaration of ‘printf’ follows non-static declaration
static int printf(const char *fmt, ...)
這個問題困擾了好久,網(wǎng)上的解決方案都是把static去掉,但是這樣做,后面在鏈接的時候會出現(xiàn)另一個錯誤undefined reference to ‘_put‘. 新的問題是由于GCC會對printf進行優(yōu)化,把無參的printf優(yōu)化成put,而linux0.12的libc中又沒有實現(xiàn)put才會導致新的問題。那么現(xiàn)在回到這個問題上,猜測應該也是由于GCC本身對printf這個函數(shù)名有特別的關照所致,所以把printf稍微改下名,printf -> printw。發(fā)現(xiàn)果然就編譯通過了。
具體解決方案:
sed -i ‘s/ printf/ printw/g‘ init/main.c
問題8:
init/main.c: In function‘main’:
init/main.c:176:3: error: ‘a(chǎn)sm’ operand has impossible constraints
__asm__("int $0x80"::"a" (__NR_pause):"ax");
類似的問題在后面編譯中出現(xiàn)好多,C內嵌匯編的格式__asm__(匯編語句:輸入寄存器:輸出寄存器:可能被修改的寄存器),最新的GCC規(guī)定輸入或輸出寄存器不能出現(xiàn)在可能被修改的寄存器中,目前看到網(wǎng)上的方法是把所有類似問題的可能被修改的寄存器全部刪掉。
具體解決方法
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相關的東西,根據(jù)網(wǎng)上的方法,把=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;
elsepag = (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;
原文:http://www.cnblogs.com/welhzh/p/4521196.html
總結
以上是生活随笔為你收集整理的编译运行linux0.12,linux0.12 编译过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: promise的状态以及api介绍_20
- 下一篇: mysql标识列从一开始_mysql中标