一、下载源代码
网站:http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/
注:上面的网站下载速度十分快。官网的代码下载速度很慢,不知道怎么搞的。
二、安装x86的as86和ld86
(查找as86和ld86两个工具所在的软件包)输入
apt-cache search as86 ld86
获取as86和ld86所在的安装包名称。
此时终端可能提示: “bin86 - 16-bit x86 assembler and loader”,说明bin86包含了我们所需要的两个软件。
sudo apt install bin86
在bootsect.S中,as86无法识别c语言的注释,需要在前面加上!注释。
三、
make---错误1:
cpp -nostdinc -Iinclude -traditional boot/bootsect.S -o boot/bootsect.s
as86 -0 -a -o boot/bootsect.o boot/bootsect.s
ld86 -0 -s -o boot/bootsect boot/bootsect.o
cpp -nostdinc -Iinclude -traditional boot/setup.S -o boot/setup.s
as86 -0 -a -o boot/setup.o boot/setup.s
ld86 -0 -s -o boot/setup boot/setup.o
gas -c -o boot/head.o boot/head.s
make: gas: Command not found
Makefile:35: recipe for target 'boot/head.o' failed
make: *** [boot/head.o] Error 127
将AS由 gas 改为 as , LD由 gld 改为 ld。
sed -i "s/gar/ar/g" `grep gar -rl ~/github/linux0.12/`
sed -i "s/gas/as --32/g" `grep gas -rl ~/github/linux0.12/`
sed -i "s/gld/ld -m elf_i386/g" `grep gld -rl ~/github/linux0.12/`
sed -i "s/gcc/gcc -m32/g" `grep gcc -rl ~/github/linux0.12/`
sed -i "s/.align 2/.align 4/g" `grep ".align\ 2" -rl ~/github/linux0.12/`
sed -i "s/.align 3/.align 8/g" `grep ".align\ 3" -rl ~/github/linux0.12/`
sed -i "s/-fcombine-regs//g" `grep "\-fcombine-regs" -rl ~/github/linux0.12`
sed -i "s/-mstring-insns//g" `grep "\-mstring-insns" -rl ~/github/linux0.12/`
make---错误2:
as --32 -c -o boot/head.o boot/head.s
gcc -m32 -Wall -O -fstrength-reduce -fomit-frame-pointer \
-nostdinc -Iinclude -c -o init/main.o init/main.c
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) \
^~~~
include/unistd.h:227:5: note: previous declaration of ‘fork’ was here
int fork(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);
^~~~
......
main.c line23/24/25/26把static去掉
make---错误3:
init/main.c:179:12: error: static declaration of ‘printf’ follows non-static declaration
static int printf(const char *fmt, ...)
^~~~~~
In file included from include/linux/mm.h:6:0,
from include/linux/sched.h:36,
from init/main.c:29:
include/linux/kernel.h:7:5: note: previous declaration of ‘printf’ was here
int printf(const char * fmt, ...);
main.c line179把static去掉?
make---错误4:
include/string.h:29:1: error: ‘asm’ operand has impossible constraints
__asm__("cld\n"
include/string.h:
line34::“S” (src),“D” (dest):“si”,“di”,“ax”);
line50::“S” (src),“D” (dest),“c” (count):“si”,“di”,“ax”,“cx”);
line64::“S” (src),“D” (dest),“a” (0),“c” (0xffffffff):“si”,“di”,“ax”,“cx”);
line84:“si”,“di”,“ax”,“cx”);
line103:"=a" (__res):“D” (cs),“S” (ct):“si”,“di”);
line124:"=a" (__res):“D” (cs),“S” (ct),“c” (count):“si”,“di”,“cx”);
line141:"=a" (__res):“S” (s),“0” ©:“si”);
line157:"=d" (__res):“0” (0),“S” (s),“a” ©:“ax”,“si”);
line181:“ax”,“cx”,“dx”,“di”);
line205:“ax”,“cx”,“dx”,“di”);
line232:“ax”,“cx”,“dx”,“di”);
line259:“cx”,“dx”,“di”,“si”);
line271:"=c" (__res):“D” (s),“a” (0),“0” (0xffffffff):“di”);
line332:“ax”,“cx”,“dx”,“di”);
line342:“cx”,“si”,“di”);
line353:“cx”,“si”,“di”);
line359:“cx”,“si”,“di”);
line375:“si”,“di”,“cx”);
line391:“cx”);
line401:“cx”,“di”);
main.c:
line176:asm(“int $0x80”::“a” (__NR_pause):“ax”);
sched.h:
line248:“dx”)
line260:“dx”)
memory.h:
line45:asm(“cld ; rep ; movsl”::“S” (from),“D” (to),“c” (1024):“cx”,“di”,“si”)
swap.c:
line191: :“di”,“cx”,“dx”);
buffer.c:
line288: :“cx”,“di”,“si”)
namei.c:
line82:“cx”,“di”,“si”);
bitmap.c:
line17::“a” (0),“c” (BLOCK_SIZE/4),“D” ((long) (addr)):“cx”,“di”)
line44:"=c" (__res):“c” (0),“S” (addr):“ax”,“dx”,“si”); \
floppy.c:
line159:“cx”,“di”,“si”)
hd.c:
line65:asm(“cld;rep;insw”::“d” (port),“D” (buf),“c” (nr):“cx”,“di”)
line68:asm(“cld;rep;outsw”::“d” (port),“S” (buf),“c” (nr):“cx”,“si”)
memory.h:
line12:“di”,“si”,“cx”); \
console.c:
line209:“cx”,“di”,“si”);
line220:“cx”,“di”);
line234:“cx”,“di”,“si”);
line249: :“cx”,“di”,“si”);
line270: :“ax”,“cx”,“di”,“si”);
line285 :“ax”,“cx”,“di”,“si”);
line350 :“cx”,“di”);
line381 :“cx”,“di”);
line604 :“ax”);
line1020 :“ax”);
寄存器全删掉。网上方法(待验证):
sed -i 's/\(:*.*:*\):.*);$/\1);/g' include/string.h
sed -i 's/:"dx")/)/g' include/linux/sched.h
sed -i '55s/\(:*.*:*\):.*)$/\1)/g' mm/memory.c
sed -i '81s/\(:*.*:*\):.*);$/\1);/g' mm/memory.c
sed -i '288s/\(:*.*:*\):.*)$/\1)/g' fs/buffer.c
sed -i '76s/\(:*.*:*\):.*);$/\1);/g' mm/memory.c
sed -i '17s/\(:*.*:*\):.*)$/\1)/g' fs/bitmap.c
sed -i '44s/\(:*.*:*\):.*);/\1);/g' fs/bitmap.c
sed -i '158s/\(:*.*:*\):.*)/\1)/g' kernel/blk_drv/floppy.c
sed -i '62s/\(:*.*:*\):.*)/\1)/g' kernel/blk_drv/hd.c
sed -i '65s/\(:*.*:*\):.*)/\1)/g' kernel/blk_drv/hd.c
sed -i '12s/\(:*.*:*\):.*);/\1);/g' include/asm/memory.h
sed -i 's/\(:*.*:*\):.*);$/\1);/g' kernel/chr_drv/console.c
注:asm指令
GCC中基本的内联汇编:asm____volatile(“InstructionList”);
asm(
“movl $1,%eax\r\t”
“xor %ebx,%ebx\r\t”
“int $0x80”
);
带有C/C++表达式的内联汇编:
asm volatile(“InstructionList”
:Output
:Input
:Clobber/Modify);
这4个部分都不是必须的,任何一个部分都可以为空,其规则为:
1、如果Clobber/Modify 为空,则其前面的冒号(:)必须省略。
2、如果Output,Input,Clobber/Modify都为空,Output,Input之前的冒号(:)既可以省略,也可以不省略。
3、如果Input,Clobber/Modify为空,但Output不为空,Input前的冒号(:)既可以省略,也可以不省略。
4、如果后面的部分不为空,而前面的部分为空,则前面的冒号(:)都必须保留,否则无法说明不为空的部分究竟是第几部分。
每一个Input和Output表达式都必须指定自己的操作约束Operation Constraint,这里将讨论在80386平台上所可能使用的操作约束。
当前的输入或输出需要借助一个寄存器时,需要为其指定一个寄存器约束,可以直接指定一个寄存器的名字。
常用的寄存器约束的缩写
约束 意义
r 表示使用一个通用寄存器,由 GCC 在%eax/%ax/%al,%ebx/%bx/%bl,%ecx/%cx/%cl,%edx/%dx/%dl中选取一个GCC认为合适的。
g 表示使用任意一个寄存器,由GCC在所有的可以使用的寄存器中选取一个GCC认为合适的。
q 表示使用一个通用寄存器,和约束r的意义相同。
a 表示使用%eax/%ax/%al
b 表示使用%ebx/%bx/%bl
c 表示使用%ecx/%cx/%cl
d 表示使用%edx/%dx/%dl
D 表示使用%edi/%di
S 表示使用%esi/%si
f 表示使用浮点寄存器
t 表示使用第一个浮点寄存器
u 表示使用第二个浮点寄存器
如果一个Input/Output 操作表达式的C/C++表达式表现为一个内存地址,不想借助于任何寄存器,则可以使用内存约束。比如:
asm(“lidt%0”:"=m"(__idt_addr));
asm(“lidt%0”::“m”(__idt_addr));
修饰符 输入/输出 意义
= O 表示此Output操作表达式是Write-Only的。
-
O 表示此Output操作表达式是Read-Write的。
& O 表示此Output操作表达式独占为其指定的寄存器。
% I 表示此Input 操作表达式中的C/C++表达式可以和下一 个Input操作表达式中的C/C++表达式互换
make---错误5:
ld -m elf_i386 -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
traps.o:在函数‘oom’中:
traps.c:(.text+0x49d): `oom'被多次定义
sched.o:sched.c:(.text+0x115):第一次在此定义
traps.o:在函数‘get_fs_byte’中:
traps.c:(.text+0x4c9): `get_fs_byte'被多次定义
sched.o:sched.c:(.text+0x141):第一次在此定义
traps.o:在函数‘get_fs_word’中:
traps.c:(.text+0x4d1): `get_fs_word'被多次定义
sched.o:sched.c:(.text+0x149):第一次在此定义
traps.o:在函数‘get_fs_long’中:
traps.c:(.text+0x4da): `get_fs_long'被多次定义
sched.o:sched.c:(.text+0x152):第一次在此定义
traps.o:在函数‘put_fs_byte’中:
traps.c:(.text+0x4e2): `put_fs_byte'被多次定义
sched.o:sched.c:(.text+0x15a):第一次在此定义
traps.o:在函数‘put_fs_word’中:
traps.c:(.text+0x4ee): `put_fs_word'被多次定义
sched.o:sched.c:(.text+0x166):第一次在此定义
traps.o:在函数‘put_fs_long’中:
traps.c:(.text+0x4fb): `put_fs_long'被多次定义
sched.o:sched.c:(.text+0x173):第一次在此定义
traps.o:在函数‘get_fs’中:
traps.c:(.text+0x507): `get_fs'被多次定义
sched.o:sched.c:(.text+0x17f):第一次在此定义
traps.o:在函数‘get_ds’中:
traps.c:(.text+0x50e): `get_ds'被多次定义
sched.o:sched.c:(.text+0x186):第一次在此定义
traps.o:在函数‘set_fs’中:
traps.c:(.text+0x515): `set_fs'被多次定义
sched.o:sched.c:(.text+0x18d):第一次在此定义
fork.o:在函数‘oom’中:
fork.c:(.text+0x0): `oom'被多次定义
sched.o:sched.c:(.text+0x115):第一次在此定义
fork.o:在函数‘get_fs_byte’中:
fork.c:(.text+0x2c): `get_fs_byte'被多次定义
sched.o:sched.c:(.text+0x141):第一次在此定义
fork.o:在函数‘get_fs_word’中:
fork.c:(.text+0x34): `get_fs_word'被多次定义
sched.o:sched.c:(.text+0x149):第一次在此定义
fork.o:在函数‘get_fs_long’中:
fork.c:(.text+0x3d): `get_fs_long'被多次定义
sched.o:sched.c:(.text+0x152):第一次在此定义
fork.o:在函数‘put_fs_byte’中:
fork.c:(.text+0x45): `put_fs_byte'被多次定义
sched.o:sched.c:(.text+0x15a):第一次在此定义
fork.o:在函数‘put_fs_word’中:
fork.c:(.text+0x51): `put_fs_word'被多次定义
sched.o:sched.c:(.text+0x166):第一次在此定义
fork.o:在函数‘put_fs_long’中:
fork.c:(.text+0x5e): `put_fs_long'被多次定义
sched.o:sched.c:(.text+0x173):第一次在此定义
fork.o:在函数‘get_fs’中:
fork.c:(.text+0x6a): `get_fs'被多次定义
sched.o:sched.c:(.text+0x17f):第一次在此定义
fork.o:在函数‘get_ds’中:
fork.c:(.text+0x71): `get_ds'被多次定义
sched.o:sched.c:(.text+0x186):第一次在此定义
fork.o:在函数‘set_fs’中:
fork.c:(.text+0x78): `set_fs'被多次定义
sched.o:sched.c:(.text+0x18d):第一次在此定义
panic.o:在函数‘oom’中:
panic.c:(.text+0x0): `oom'被多次定义
sched.o:sched.c:(.text+0x115):第一次在此定义
vsprintf.o:在函数‘strcpy’中:
vsprintf.c:(.text+0x265): `strcpy'被多次定义
traps.o:traps.c:(.text+0x182):第一次在此定义
vsprintf.o:在函数‘strncpy’中:
vsprintf.c:(.text+0x27b): `strncpy'被多次定义
traps.o:traps.c:(.text+0x198):第一次在此定义
vsprintf.o:在函数‘strcat’中:
vsprintf.c:(.text+0x29a): `strcat'被多次定义
traps.o:traps.c:(.text+0x1b7):第一次在此定义
vsprintf.o:在函数‘strncat’中:
vsprintf.c:(.text+0x2bd): `strncat'被多次定义
traps.o:traps.c:(.text+0x1da):第一次在此定义
vsprintf.o:在函数‘strcmp’中:
vsprintf.c:(.text+0x2ea): `strcmp'被多次定义
traps.o:traps.c:(.text+0x207):第一次在此定义
vsprintf.o:在函数‘strncmp’中:
vsprintf.c:(.text+0x30d): `strncmp'被多次定义
traps.o:traps.c:(.text+0x22a):第一次在此定义
vsprintf.o:在函数‘strchr’中:
vsprintf.c:(.text+0x337): `strchr'被多次定义
traps.o:traps.c:(.text+0x254):第一次在此定义
vsprintf.o:在函数‘strrchr’中:
vsprintf.c:(.text+0x356): `strrchr'被多次定义
traps.o:traps.c:(.text+0x273):第一次在此定义
vsprintf.o:在函数‘strspn’中:
vsprintf.c:(.text+0x377): `strspn'被多次定义
traps.o:traps.c:(.text+0x294):第一次在此定义
vsprintf.o:在函数‘strcspn’中:
vsprintf.c:(.text+0x3aa): `strcspn'被多次定义
traps.o:traps.c:(.text+0x2c7):第一次在此定义
vsprintf.o:在函数‘strpbrk’中:
vsprintf.c:(.text+0x3df): `strpbrk'被多次定义
traps.o:traps.c:(.text+0x2fc):第一次在此定义
vsprintf.o:在函数‘strstr’中:
vsprintf.c:(.text+0x412): `strstr'被多次定义
traps.o:traps.c:(.text+0x32f):第一次在此定义
vsprintf.o:在函数‘strlen’中:
vsprintf.c:(.text+0x445): `strlen'被多次定义
traps.o:traps.c:(.text+0x362):第一次在此定义
vsprintf.o:在函数‘strtok’中:
vsprintf.c:(.text+0x45e): `strtok'被多次定义
traps.o:traps.c:(.text+0x37b):第一次在此定义
vsprintf.o:在函数‘memcpy’中:
vsprintf.c:(.text+0x4e5): `memcpy'被多次定义
traps.o:traps.c:(.text+0x402):第一次在此定义
vsprintf.o:在函数‘memmove’中:
vsprintf.c:(.text+0x4fb): `memmove'被多次定义
traps.o:traps.c:(.text+0x418):第一次在此定义
vsprintf.o:在函数‘memcmp’中:
vsprintf.c:(.text+0x521): `memcmp'被多次定义
traps.o:traps.c:(.text+0x43e):第一次在此定义
vsprintf.o:在函数‘memchr’中:
vsprintf.c:(.text+0x545): `memchr'被多次定义
traps.o:traps.c:(.text+0x462):第一次在此定义
vsprintf.o:在函数‘memset’中:
vsprintf.c:(.text+0x56c): `memset'被多次定义
traps.o:traps.c:(.text+0x489):第一次在此定义
sys.o:在函数‘oom’中:
sys.c:(.text+0x0): `oom'被多次定义
sched.o:sched.c:(.text+0x115):第一次在此定义
sys.o:在函数‘get_fs_byte’中:
sys.c:(.text+0x2c): `get_fs_byte'被多次定义
sched.o:sched.c:(.text+0x141):第一次在此定义
sys.o:在函数‘get_fs_word’中:
sys.c:(.text+0x34): `get_fs_word'被多次定义
sched.o:sched.c:(.text+0x149):第一次在此定义
sys.o:在函数‘get_fs_long’中:
sys.c:(.text+0x3d): `get_fs_long'被多次定义
sched.o:sched.c:(.text+0x152):第一次在此定义
sys.o:在函数‘put_fs_byte’中:
sys.c:(.text+0x45): `put_fs_byte'被多次定义
sched.o:sched.c:(.text+0x15a):第一次在此定义
sys.o:在函数‘put_fs_word’中:
sys.c:(.text+0x51): `put_fs_word'被多次定义
sched.o:sched.c:(.text+0x166):第一次在此定义
sys.o:在函数‘put_fs_long’中:
sys.c:(.text+0x5e): `put_fs_long'被多次定义
sched.o:sched.c:(.text+0x173):第一次在此定义
sys.o:在函数‘get_fs’中:
sys.c:(.text+0x6a): `get_fs'被多次定义
sched.o:sched.c:(.text+0x17f):第一次在此定义
sys.o:在函数‘get_ds’中:
sys.c:(.text+0x71): `get_ds'被多次定义
sched.o:sched.c:(.text+0x186):第一次在此定义
sys.o:在函数‘set_fs’中:
sys.c:(.text+0x78): `set_fs'被多次定义
sched.o:sched.c:(.text+0x18d):第一次在此定义
sys.o:在函数‘strcpy’中:
sys.c:(.text+0x7f): `strcpy'被多次定义
traps.o:traps.c:(.text+0x182):第一次在此定义
sys.o:在函数‘strncpy’中:
sys.c:(.text+0x95): `strncpy'被多次定义
traps.o:traps.c:(.text+0x198):第一次在此定义
sys.o:在函数‘strcat’中:
sys.c:(.text+0xb4): `strcat'被多次定义
traps.o:traps.c:(.text+0x1b7):第一次在此定义
sys.o:在函数‘strncat’中:
sys.c:(.text+0xd7): `strncat'被多次定义
traps.o:traps.c:(.text+0x1da):第一次在此定义
sys.o:在函数‘strcmp’中:
sys.c:(.text+0x104): `strcmp'被多次定义
traps.o:traps.c:(.text+0x207):第一次在此定义
sys.o:在函数‘strncmp’中:
sys.c:(.text+0x127): `strncmp'被多次定义
traps.o:traps.c:(.text+0x22a):第一次在此定义
sys.o:在函数‘strchr’中:
sys.c:(.text+0x151): `strchr'被多次定义
traps.o:traps.c:(.text+0x254):第一次在此定义
sys.o:在函数‘strrchr’中:
sys.c:(.text+0x170): `strrchr'被多次定义
traps.o:traps.c:(.text+0x273):第一次在此定义
sys.o:在函数‘strspn’中:
sys.c:(.text+0x191): `strspn'被多次定义
traps.o:traps.c:(.text+0x294):第一次在此定义
sys.o:在函数‘strcspn’中:
sys.c:(.text+0x1c4): `strcspn'被多次定义
traps.o:traps.c:(.text+0x2c7):第一次在此定义
sys.o:在函数‘strpbrk’中:
sys.c:(.text+0x1f9): `strpbrk'被多次定义
traps.o:traps.c:(.text+0x2fc):第一次在此定义
sys.o:在函数‘strstr’中:
sys.c:(.text+0x22c): `strstr'被多次定义
traps.o:traps.c:(.text+0x32f):第一次在此定义
sys.o:在函数‘strlen’中:
sys.c:(.text+0x25f): `strlen'被多次定义
traps.o:traps.c:(.text+0x362):第一次在此定义
sys.o:在函数‘strtok’中:
sys.c:(.text+0x278): `strtok'被多次定义
traps.o:traps.c:(.text+0x37b):第一次在此定义
sys.o:在函数‘memcpy’中:
sys.c:(.text+0x2ff): `memcpy'被多次定义
traps.o:traps.c:(.text+0x402):第一次在此定义
sys.o:在函数‘memmove’中:
sys.c:(.text+0x315): `memmove'被多次定义
traps.o:traps.c:(.text+0x418):第一次在此定义
sys.o:在函数‘memcmp’中:
sys.c:(.text+0x33b): `memcmp'被多次定义
traps.o:traps.c:(.text+0x43e):第一次在此定义
sys.o:在函数‘memchr’中:
sys.c:(.text+0x35f): `memchr'被多次定义
traps.o:traps.c:(.text+0x462):第一次在此定义
sys.o:在函数‘memset’中:
sys.c:(.text+0x386): `memset'被多次定义
traps.o:traps.c:(.text+0x489):第一次在此定义
exit.o:在函数‘get_fs_byte’中:
exit.c:(.text+0x44): `get_fs_byte'被多次定义
sched.o:sched.c:(.text+0x141):第一次在此定义
exit.o:在函数‘get_fs_word’中:
exit.c:(.text+0x4c): `get_fs_word'被多次定义
sched.o:sched.c:(.text+0x149):第一次在此定义
exit.o:在函数‘get_fs_long’中:
exit.c:(.text+0x55): `get_fs_long'被多次定义
sched.o:sched.c:(.text+0x152):第一次在此定义
exit.o:在函数‘put_fs_byte’中:
exit.c:(.text+0x5d): `put_fs_byte'被多次定义
sched.o:sched.c:(.text+0x15a):第一次在此定义
exit.o:在函数‘put_fs_word’中:
exit.c:(.text+0x69): `put_fs_word'被多次定义
sched.o:sched.c:(.text+0x166):第一次在此定义
exit.o:在函数‘put_fs_long’中:
exit.c:(.text+0x76): `put_fs_long'被多次定义
sched.o:sched.c:(.text+0x173):第一次在此定义
exit.o:在函数‘get_fs’中:
exit.c:(.text+0x82): `get_fs'被多次定义
sched.o:sched.c:(.text+0x17f):第一次在此定义
exit.o:在函数‘get_ds’中:
exit.c:(.text+0x89): `get_ds'被多次定义
sched.o:sched.c:(.text+0x186):第一次在此定义
exit.o:在函数‘set_fs’中:
exit.c:(.text+0x90): `set_fs'被多次定义
sched.o:sched.c:(.text+0x18d):第一次在此定义
exit.o:在函数‘oom’中:
exit.c:(.text+0xc6d): `oom'被多次定义
sched.o:sched.c:(.text+0x115):第一次在此定义
signal.o:在函数‘oom’中:
signal.c:(.text+0x0): `oom'被多次定义
sched.o:sched.c:(.text+0x115):第一次在此定义
signal.o:在函数‘get_fs_byte’中:
signal.c:(.text+0x2c): `get_fs_byte'被多次定义
sched.o:sched.c:(.text+0x141):第一次在此定义
signal.o:在函数‘get_fs_word’中:
signal.c:(.text+0x34): `get_fs_word'被多次定义
sched.o:sched.c:(.text+0x149):第一次在此定义
signal.o:在函数‘get_fs_long’中:
signal.c:(.text+0x3d): `get_fs_long'被多次定义
sched.o:sched.c:(.text+0x152):第一次在此定义
signal.o:在函数‘put_fs_byte’中:
signal.c:(.text+0x45): `put_fs_byte'被多次定义
sched.o:sched.c:(.text+0x15a):第一次在此定义
signal.o:在函数‘put_fs_word’中:
signal.c:(.text+0x51): `put_fs_word'被多次定义
sched.o:sched.c:(.text+0x166):第一次在此定义
signal.o:在函数‘put_fs_long’中:
signal.c:(.text+0x5e): `put_fs_long'被多次定义
sched.o:sched.c:(.text+0x173):第一次在此定义
signal.o:在函数‘get_fs’中:
signal.c:(.text+0x6a): `get_fs'被多次定义
sched.o:sched.c:(.text+0x17f):第一次在此定义
signal.o:在函数‘get_ds’中:
signal.c:(.text+0x71): `get_ds'被多次定义
sched.o:sched.c:(.text+0x186):第一次在此定义
signal.o:在函数‘set_fs’中:
signal.c:(.text+0x78): `set_fs'被多次定义
sched.o:sched.c:(.text+0x18d):第一次在此定义
Makefile:32: recipe for target 'kernel.o' failed
make[1]: *** [kernel.o] Error 1
make[1]: 离开目录“/home/jackhao/github/linux0.12/kernel”
Makefile:75: recipe for target 'kernel/kernel.o' failed
make: *** [kernel/kernel.o] Error 2
segment.h中定义的函数extern inline全部改成static inline的
string.h中定义的函数extern inline全部改成static inline的
mm.h中定义的函数extern inline全部改成static inline的
make---错误6:
-c -o file_dev.o file_dev.c
file_dev.c: In function ‘file_read’:
file_dev.c:25:7: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
if (nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE)) {
^~
file_dev.c:46:1: error: unsupported size for integer register
}
上述错误需要关闭编译优化来解决,即
去掉fs的Makefile中gcc编译参数中的-O,
去掉kernel/chr_drv的Makefile中gcc编译参数中的-O,
去掉kernel/math的Makefile中gcc编译参数中的-O,
重新编译.
make---错误7:
exec.c:162:44: error: lvalue required as left operand of assignment
!(pag = (char *) page[p/PAGE_SIZE] =
exec.c line161->164
if (!(pag = (char *) page[p/PAGE_SIZE]) &&
!(pag = (char *) page[p/PAGE_SIZE] =
(unsigned long *) get_free_page()))
return 0;
更改为:
if ((!page[p/PAGE_SIZE]) &&
!(page[p/PAGE_SIZE] =
(unsigned long *) get_free_page()))
return 0;
else
pag = (char *) page[p/PAGE_SIZE];
make---错误8:
../../include/ctype.h:32:29: note: in expansion of macro ‘islower’
#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp)
^~~~~~~
tty_io.c:370:8: note: in expansion of macro ‘toupper’
c=toupper(c);
^~~~~~~
tty_io.c:381:1: error: unsupported size for integer register
}
make---错误9:
gcc -m32 -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include \
-c -o malloc.o malloc.c
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();
^
Makefile:24: recipe for target 'malloc.o' failed
malloc.c:
bdesc->page = bdesc->freeptr = (void *) cp = get_free_page();
更改为:
cp = get_free_page();
bdesc->page = bdesc->freeptr = (void *) cp;
make---错误10:
(cd lib; make)
make[1]: 进入目录“/home/jackhao/github/linux0.12/lib”
gcc -m32 -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include \
-c -o malloc.o malloc.c
malloc.c: In function ‘malloc’:
malloc.c:157:6: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
cp = get_free_page();
^
malloc.c: In function ‘free_s’:
malloc.c:215:21: warning: ‘prev’ may be used uninitialized in this function [-Wmaybe-uninitialized]
if ((prev && (prev->next != bdesc)) ||
~~~~^~~~~~
ar rcs lib.a ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o execve.o wait.o string.o malloc.o
sync
make[1]: 离开目录“/home/jackhao/github/linux0.12/lib”
ld -m elf_i386 -s -x -M boot/head.o init/main.o \
kernel/kernel.o mm/mm.o fs/fs.o \
kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \
kernel/math/math.a \
lib/lib.a \
-o tools/system > System.map
kernel/blk_drv/blk_drv.a(hd.o):在函数‘unlock_buffer’中:
hd.c:(.text+0x919): `unlock_buffer'被多次定义
kernel/blk_drv/blk_drv.a(floppy.o):floppy.c:(.text+0x7c3):第一次在此定义
kernel/blk_drv/blk_drv.a(hd.o):在函数‘end_request’中:
hd.c:(.text+0x95d): `end_request'被多次定义
kernel/blk_drv/blk_drv.a(floppy.o):floppy.c:(.text+0x807):第一次在此定义
kernel/blk_drv/blk_drv.a(ramdisk.o):在函数‘unlock_buffer’中:
ramdisk.c:(.text+0x28e): `unlock_buffer'被多次定义
kernel/blk_drv/blk_drv.a(floppy.o):floppy.c:(.text+0x7c3):第一次在此定义
kernel/blk_drv/blk_drv.a(ramdisk.o):在函数‘end_request’中:
ramdisk.c:(.text+0x2d2): `end_request'被多次定义
kernel/blk_drv/blk_drv.a(floppy.o):floppy.c:(.text+0x807):第一次在此定义
blk.h头文件
extern inline更改为static inline
kernel/blk_drv/blk_drv.a(hd.o):在函数‘unlock_buffer’中:
hd.c:(.text+0x95d): `end_request’被多次定义
在函数里加上头文件卫士
#ifndef
#define
func();
#endif
ld: 警告: 无法找到项目符号 _start; 缺省为 00000000080480b8
boot/head.o:在函数‘startup_32’中:
这是因为ld在将所有目标文件链接起来时,不知道程序的入口点在哪里。由内核的启动过程知其从head.s中开始执行,因此给head.s的 .text 段添加一句 .globl startup_32,然后给 ./Makefile 中的ld加上选项 -e startup_32 以指定入口点。
另外注意,仅指定入口点的标号还不够,后续使用tools/build构建Image仍会出错,因为此时程序入口点的地址仍是0x8048098(见上方出错信息的最后一行),而在tools/build.c中处理system模块时,认定的合法入口点地址为0x0:
因此还需添加 -Ttext 0 选项使startup_32标号对应的地址为0x0(更详细的说明见ld的手册,另有一个讨论见这里)。
boot/head.o:在函数‘startup_32’中:
(.text+0x10):对‘_stack_start’未定义的引用
(.text+0x2e):对‘_stack_start’未定义的引用
boot/head.o:在函数‘after_page_tables’中:
(.text+0x540c):对‘_main’未定义的引用
boot/head.o:在函数‘ignore_int’中:
(.text+0x5440):对‘_printk’未定义的引用
init/main.o:在函数‘init’中:
main.c:(.text+0x282):对‘puts’未定义的引用
kernel/kernel.o:在函数‘schedule’中:
(.text+0x3f3):对‘_current’未定义的引用
(.text+0x400):对‘_current’未定义的引用
(.text+0x40a):对‘_last_task_used_math’未定义的引用
(.text+0x428):对‘__stack_chk_fail_local’未定义的引用
kernel/kernel.o:在函数‘sched_init’中:
(.text+0x9d3):对‘gdt’未定义的引用
(.text+0xa98):对‘idt’未定义的引用
(.text+0xaa3):对‘timer_interrupt’未定义的引用
(.text+0xace):对‘system_call’未定义的引用
kernel/kernel.o:在函数‘reschedule’中:
sys_call.o:(.text+0xaf6):对‘_schedule’未定义的引用
kernel/kernel.o:在函数‘_system_call’中:
(.text+0xb16):对‘_NR_syscalls’未定义的引用
(.text+0xb1f):对‘_sys_call_table’未定义的引用
(.text+0xb25):对‘_current’未定义的引用
kernel/kernel.o:在函数‘ret_from_sys_call’中:
sys_call.o:(.text+0xb35):对‘_current’未定义的引用
sys_call.o:(.text+0xb3b):对‘_task’未定义的引用
sys_call.o:(.text+0xb6c):对‘_do_signal’未定义的引用
kernel/kernel.o:在函数‘_coprocessor_error’中:
(.text+0xba4):对‘_math_error’未定义的引用
kernel/kernel.o:在函数‘_device_not_available’中:
(.text+0xbd3):对‘_math_state_restore’未定义的引用
(.text+0xbdd):对‘_math_emulate’未定义的引用
kernel/kernel.o:在函数‘_timer_interrupt’中:
(.text+0xc04):对‘_jiffies’未定义的引用
(.text+0xc15):对‘_do_timer’未定义的引用
kernel/kernel.o:在函数‘_sys_execve’中:
(.text+0xc2a):对‘_do_execve’未定义的引用
kernel/kernel.o:在函数‘_sys_fork’中:
(.text+0xc35):对‘_find_empty_process’未定义的引用
(.text+0xc44):对‘_copy_process’未定义的引用
kernel/kernel.o:在函数‘_hd_interrupt’中:
(.text+0xc6f):对‘_hd_timeout’未定义的引用
(.text+0xc75):对‘_do_hd’未定义的引用
(.text+0xc7e):对‘_unexpected_hd_interrupt’未定义的引用
kernel/kernel.o:在函数‘_floppy_interrupt’中:
(.text+0xcad):对‘_do_floppy’未定义的引用
(.text+0xcb6):对‘_unexpected_floppy_interrupt’未定义的引用
kernel/kernel.o:在函数‘trap_init’中:
(.text+0x1144):对‘idt’未定义的引用
(.text+0x114f):对‘divide_error’未定义的引用
(.text+0x1161):对‘debug’未定义的引用
(.text+0x1174):对‘nmi’未定义的引用
(.text+0x1187):对‘int3’未定义的引用
(.text+0x119a):对‘overflow’未定义的引用
(.text+0x11ad):对‘bounds’未定义的引用
(.text+0x11c0):对‘invalid_op’未定义的引用
(.text+0x11d3):对‘device_not_available’未定义的引用
(.text+0x11e6):对‘double_fault’未定义的引用
(.text+0x11f9):对‘coprocessor_segment_overrun’未定义的引用
(.text+0x120c):对‘invalid_TSS’未定义的引用
(.text+0x121f):对‘segment_not_present’未定义的引用
(.text+0x1232):对‘stack_segment’未定义的引用
(.text+0x1245):对‘general_protection’未定义的引用
(.text+0x1258):对‘page_fault’未定义的引用
(.text+0x126b):对‘reserved’未定义的引用
(.text+0x127e):对‘coprocessor_error’未定义的引用
(.text+0x1297):对‘alignment_check’未定义的引用
(.text+0x12bc):对‘reserved’未定义的引用
(.text+0x12d5):对‘idt’未定义的引用
(.text+0x12e0):对‘irq13’未定义的引用
(.text+0x131f):对‘parallel_interrupt’未定义的引用
kernel/kernel.o:在函数‘_divide_error’中:
(.text+0x133c):对‘_do_divide_error’未定义的引用
kernel/kernel.o:在函数‘_debug’中:
(.text+0x1371):对‘_do_int3’未定义的引用
kernel/kernel.o:在函数‘_nmi’中:
(.text+0x1378):对‘_do_nmi’未定义的引用
kernel/kernel.o:在函数‘_int3’中:
(.text+0x137f):对‘_do_int3’未定义的引用
kernel/kernel.o:在函数‘_overflow’中:
(.text+0x1386):对‘_do_overflow’未定义的引用
kernel/kernel.o:在函数‘_bounds’中:
(.text+0x138d):对‘_do_bounds’未定义的引用
kernel/kernel.o:在函数‘_invalid_op’中:
(.text+0x1394):对‘_do_invalid_op’未定义的引用
kernel/kernel.o:在函数‘_coprocessor_segment_overrun’中:
(.text+0x139b):对‘_do_coprocessor_segment_overrun’未定义的引用
kernel/kernel.o:在函数‘_reserved’中:
(.text+0x13a2):对‘_do_reserved’未定义的引用
kernel/kernel.o:在函数‘_double_fault’中:
(.text+0x13be):对‘_do_double_fault’未定义的引用
kernel/kernel.o:在函数‘_invalid_TSS’中:
(.text+0x13f5):对‘_do_invalid_TSS’未定义的引用
kernel/kernel.o:在函数‘_segment_not_present’中:
(.text+0x13fc):对‘_do_segment_not_present’未定义的引用
kernel/kernel.o:在函数‘_stack_segment’中:
(.text+0x1403):对‘_do_stack_segment’未定义的引用
kernel/kernel.o:在函数‘_general_protection’中:
(.text+0x140a):对‘_do_general_protection’未定义的引用
kernel/kernel.o:在函数‘_alignment_check’中:
(.text+0x1411):对‘_do_alignment_check’未定义的引用
kernel/kernel.o:在函数‘copy_process’中:
(.text+0x17e2):对‘gdt’未定义的引用
kernel/kernel.o:在函数‘number’中:
vsprintf.c:(.text+0x1bf5):对‘__stack_chk_fail_local’未定义的引用
kernel/kernel.o:在函数‘sys_getrusage’中:
(.text+0x29c0):对‘__stack_chk_fail_local’未定义的引用
kernel/kernel.o:在函数‘sys_sigaction’中:
(.text+0x3b83):对‘__stack_chk_fail_local’未定义的引用
kernel/kernel.o:(.data.rel+0x3ec):对‘pg_dir’未定义的引用
kernel/kernel.o:(.data.rel+0x1028):对‘sys_fork’未定义的引用
kernel/kernel.o:(.data.rel+0x104c):对‘sys_execve’未定义的引用
mm/mm.o:在函数‘do_no_page’中:
(.text+0xa0b):对‘__stack_chk_fail_local’未定义的引用
mm/mm.o:在函数‘show_mem’中:
(.text+0xb0c):对‘pg_dir’未定义的引用
mm/mm.o:在函数‘swap_out’中:
(.text+0xda7):对‘pg_dir’未定义的引用
(.text+0xdbf):对‘pg_dir’未定义的引用
(.text+0xdf5):对‘pg_dir’未定义的引用
mm/mm.o:在函数‘_page_fault’中:
(.text+0x1231):对‘_do_no_page’未定义的引用
(.text+0x1238):对‘_do_wp_page’未定义的引用
fs/fs.o:在函数‘sys_open’中:
(.text+0x5a6):对‘__stack_chk_fail_local’未定义的引用
fs/fs.o:在函数‘bread_page’中:
(.text+0x1c87):对‘__stack_chk_fail_local’未定义的引用
fs/fs.o:在函数‘cp_stat’中:
stat.c:(.text+0x2fca):对‘__stack_chk_fail_local’未定义的引用
fs/fs.o:在函数‘do_execve’中:
(.text+0x434c):对‘__stack_chk_fail_local’未定义的引用
fs/fs.o:在函数‘sys_pipe’中:
(.text+0x494f):对‘__stack_chk_fail_local’未定义的引用
fs/fs.o:namei.c:(.text+0x536e): 跟着更多未定义的参考到 __stack_chk_fail_local
kernel/blk_drv/blk_drv.a(floppy.o):在函数‘setup_DMA’中:
floppy.c:(.text+0x24):对‘tmp_floppy_area’未定义的引用
kernel/blk_drv/blk_drv.a(floppy.o):在函数‘rw_interrupt’中:
floppy.c:(.text+0xd82):对‘tmp_floppy_area’未定义的引用
kernel/blk_drv/blk_drv.a(floppy.o):在函数‘floppy_init’中:
floppy.c:(.text+0xebe):对‘idt’未定义的引用
floppy.c:(.text+0xec4):对‘floppy_interrupt’未定义的引用
kernel/blk_drv/blk_drv.a(hd.o):在函数‘hd_init’中:
hd.c:(.text+0xea6):对‘idt’未定义的引用
hd.c:(.text+0xeac):对‘hd_interrupt’未定义的引用
kernel/chr_drv/chr_drv.a(console.o):在函数‘scrup’中:
console.c:(.text+0x41b):对‘_video_num_columns’未定义的引用
console.c:(.text+0x694):对‘_video_num_columns’未定义的引用
console.c:(.text+0x797):对‘_video_num_columns’未定义的引用
kernel/chr_drv/chr_drv.a(console.o):在函数‘scrdown’中:
console.c:(.text+0x911):对‘_video_num_columns’未定义的引用
console.c:(.text+0xa1b):对‘_video_num_columns’未定义的引用
kernel/chr_drv/chr_drv.a(console.o):在函数‘con_init’中:
console.c:(.text+0x3aea):对‘idt’未定义的引用
console.c:(.text+0x3af6):对‘idt’未定义的引用
console.c:(.text+0x3b02):对‘keyboard_interrupt’未定义的引用
kernel/chr_drv/chr_drv.a(serial.o):在函数‘rs_init’中:
serial.c:(.text+0x92):对‘idt’未定义的引用
serial.c:(.text+0x9e):对‘idt’未定义的引用
serial.c:(.text+0xaa):对‘rs1_interrupt’未定义的引用
serial.c:(.text+0xc2):对‘idt’未定义的引用
serial.c:(.text+0xce):对‘idt’未定义的引用
serial.c:(.text+0xda):对‘rs2_interrupt’未定义的引用
kernel/chr_drv/chr_drv.a(tty_ioctl.o):在函数‘get_termio’中:
tty_ioctl.c:(.text+0x35c):对‘__stack_chk_fail_local’未定义的引用
kernel/chr_drv/chr_drv.a(tty_ioctl.o):在函数‘set_termio’中:
Makefile:58: recipe for target 'tools/system' failed
make: *** [tools/system] Error 1
head.s中的_开头的变量和函数,去掉_
sys_call.s中的_开头的变量和函数,去掉_
asm.s中的_开头的变量和函数,去掉_
tty_ioctl.c:(.text+0x4c5):对‘__stack_chk_fail_local’未定义的引用
在所有Makefile文件中gcc编译选项CFLAGS后添加-fno-stack-protector
make---错误11:
init/main.o:在函数‘init’中:
main.c:(.text+0x27b):对‘puts’未定义的引用
kernel/kernel.o:在函数‘trap_init’中:
(.text+0x1163):对‘int3’未定义的引用
fs/fs.o:在函数‘check_disk_change’中:
(.text+0x20ba):对‘invalidate_buffers’未定义的引用
kernel/chr_drv/chr_drv.a(console.o):在函数‘con_init’中:
console.c:(.text+0x3b02):对‘keyboard_interrupt’未定义的引用
kernel/chr_drv/chr_drv.a(serial.o):在函数‘rs_init’中:
serial.c:(.text+0xaa):对‘rs1_interrupt’未定义的引用
serial.c:(.text+0xda):对‘rs2_interrupt’未定义的引用
Makefile:58: recipe for target 'tools/system' failed
make: *** [tools/system] Error 1
buffer.c:
line84:void inline invalidate_buffers(int dev)去掉inline,变成
void invalidate_buffers(int dev)
我不知道原因,但这么改就对了
注:让终端错误提示变英文方法
如果希望终端显示英文,可以设置系统变量
export LC_ALL=C
若希望恢复为本地语言,则
unset LC_ALL
make---错误12:
init/main.o:在函数‘init’中:
main.c:(.text+0x27b):对‘puts’未定义的引用
还没找到原因,我在main.c里定义了一个void puts(){}空函数;
make---错误13:
gcc -m32 -Wall -O -fstrength-reduce -fomit-frame-pointer -fno-stack-protector \
-o tools/build tools/build.c
In file included from tools/build.c:25:0:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
Makefile:51: recipe for target 'tools/build' failed
make: *** [tools/build] Error 1
百度搜索答案:
可以尝试输入sudoapt-get install gcc-multilib即可,其实主要是gcc安装环境没有安装完善。我在网上找了很多方式,没想到是这个,记录下。
make---错误14:
gcc -m32 -Wall -O -fstrength-reduce -fomit-frame-pointer -fno-stack-protector \
-o tools/build tools/build.c
tools/build.c: In function 'main':
tools/build.c:78:17: warning: implicit declaration of function 'MAJOR' [-Wimplicit-function-declaration]
major_root = MAJOR(sb.st_rdev);
^~~~~
tools/build.c:79:17: warning: implicit declaration of function 'MINOR'; did you mean '_IOR'? [-Wimplicit-function-declaration]
minor_root = MINOR(sb.st_rdev);
^~~~~
_IOR
/tmp/ccsWmdx0.o: In function `main':
build.c:(.text+0xed): undefined reference to `MAJOR'
build.c:(.text+0x107): undefined reference to `MINOR'
build.c:(.text+0x1a5): undefined reference to `MAJOR'
build.c:(.text+0x1bf): undefined reference to `MINOR'
collect2: error: ld returned 1 exit status
Makefile:51: recipe for target 'tools/build' failed
make: *** [tools/build] Error 1
build.c中包含的是标准库的头文件 /usr/include/linux/fs.h ,但是这个头文件里并没有实现MAJOR和MINOR宏。解决方法很简单,从include/linux/fs.h中把这两个宏复制到build.c中即可:
#define MAJOR(a) (((unsigned)(a))>>8)
#define MINOR(a) ((a)&0xff)
make---错误15:
gcc -m32 -Wall -O -fstrength-reduce -fomit-frame-pointer -fno-stack-protector \
-o tools/build tools/build.c
tools/build boot/bootsect boot/setup tools/system /dev/hd6 \
/dev/hd2 > Image
/dev/hd6: No such file or directory
Couldn't stat root device.
Makefile:43: recipe for target 'Image' failed
make: *** [Image] Error 1
这段报错的代码在build.c的line79处,可以自行阅读理解。
把
ROOT_DEV=etc/hd6
SWAP_DEV=etc/hd2
修改为
ROOT_DEV=
SWAP_DEV=
或
ROOT_DEV= FLOPPY
SWAP_DEV=
make---错误16:
gcc -m32 -Wall -O -fstrength-reduce -fomit-frame-pointer -fno-stack-protector \
-o tools/build tools/build.c
tools/build boot/bootsect boot/setup tools/system \
> Image
Root device is (3, 6)
Swap device is (0, 0)
Boot sector 512 bytes.
Setup is 1372 bytes.
Non-GCC header of 'system'
Makefile:43: recipe for target 'Image' failed
make: *** [Image] Error 1
把build.c中的
if (((long *) buf)[5] != 0)
die("Non-GCC header of 'system'");
---------------------
if (i > SYS_SIZE*16)
die("System is too big");
注释掉
以上就是全部错误,然后编译成功。但是这个系统应该是不能用的。因为最后的软盘设置等没弄明白。但是编译目标文件有了。我可以试试GBD调试了。花了两三个星期=。=真的有点累啊。
以下附上参考链接:
https://www.cnblogs.com/welhzh/p/4521196.html
https://www.cnblogs.com/hummersofdie/p/3645218.html