linux1.0内核代码学习(一)
库文件和头文件
在程序中,使用#include <stdio.h>类似的头文件stdio.h在编译器的头文件路径中,#include "abc.h"中的abc.h文件则应该在当前目录。通过对编译器指定参数-I<PATH>来指定头文件所在目录,可以用 #include <>来引用。例如:gcc -I./include hello.c,将从当前目录下的include目录下去寻找头文件。
同理,程序中调用的库函数在编译时也需要指定路径,同时指定库。使用-L<PATH>参数指定库文件的目录,-l<FILE>指定包含的库文件。例如,要使用libXXX.so库,参数为-lXXX。
一般一个库编译完成后有库文件和头文件。如果要使用这个库,可以将库文件目录和头文件目录分别用-I和-L参数指定,也可以将他们拷贝到编译器的include和lib目录下。
编译之前先到https://www.kernel.org/pub/linux/kernel/下载linux 1.0的源代码
一、编译linux1.0内核代码
虚拟机:fedora10 32位 内核版本2.6.27.41-170.2.117.fc10.i686
编译环境:gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC)
1、拷贝linux-1.0.tar.gz到我的工作目录:/mnt/mywork,解压tar zxvf linux-1.0.tar.gz,修改目录名字:mv linux linux-1.0,
进入到工作目录/mnt/mywork设置gcc编译时的默认环境变量,gcc默认的头文件目录为/usr/include,为了不破坏虚拟机本来的编译环境,因此在编译linux1.0内核的时候在控制台中设置gcc环境变量 C_INCLUDE_PATH=/mnt/mywork/linux-1.0/include/,或者在Makefile中添加gcc环境变量C_INCLUDE_PATH =/mnt/mywork/linux-1.0/include/;同时修改Makefile中变量KERNELHDRS =/usr/src/linux/include为KERNELHDRS =/mnt/mywork/linux-1.0/include/
2、配置内核
[root@localhost linux-1.0]# make config
/bin/sh Configure < config.in
*
* General setup
*
Kernel math emulation (CONFIG_MATH_EMULATION) [y]
Normal harddisk support (CONFIG_BLK_DEV_HD) [y]
XT harddisk support (CONFIG_BLK_DEV_XD) [n]
TCP/IP networking (CONFIG_INET) [y]
Limit memory to low 16MB (CONFIG_MAX_16M) [n]
System V IPC (CONFIG_SYSVIPC) [y]
Use -m486 flag for 486-specific optimizations (CONFIG_M486) [y]
*
* Program binary formats
*
Elf executables (CONFIG_BINFMT_ELF) [y]
COFF executables (CONFIG_BINFMT_COFF) [y]
*
* SCSI support
*
SCSI support? (CONFIG_SCSI) [n]
:
: Skipping SCSI configuration options...
:
*
* Network device support
*
Network device support? (CONFIG_ETHERCARDS) [y]
SLIP (serial line) support (CONFIG_SLIP) [n]
PLIP (parallel port) support (CONFIG_PLIP) [n]
NE2000/NE1000 support (CONFIG_NE2000) [n]
WD80*3 support (CONFIG_WD80x3) [y]
SMC Ultra support (CONFIG_ULTRA) [n]
3c501 support (CONFIG_EL1) [n]
3c503 support (CONFIG_EL2) [n]
3c509/3c579 support (CONFIG_EL3) [n]
HP PCLAN support (CONFIG_HPLAN) [n]
AT1500 and NE2100 (LANCE and PCnet-ISA) support (CONFIG_LANCE) [n]
AT1700 support (CONFIG_AT1700) [n]
DEPCA support (CONFIG_DEPCA) [n]
D-Link DE600 pocket adaptor support (CONFIG_DE600) [n]
AT-LAN-TEC/RealTek pocket adaptor support (CONFIG_ATP) [n] y
*
Sony CDU31A CDROM driver support (CONFIG_CDU31A) [n]
Mitsumi CDROM driver support (CONFIG_MCD) [n]
Matsushita/Panasonic CDROM driver support (CONFIG_SBPCD) [n]
*
* Filesystems
*
Standard (minix) fs support (CONFIG_MINIX_FS) [y]
Extended fs support (CONFIG_EXT_FS) [n]
Second extended fs support (CONFIG_EXT2_FS) [y]
xiafs filesystem support (CONFIG_XIA_FS) [n]
msdos fs support (CONFIG_MSDOS_FS) [y]
/proc filesystem support (CONFIG_PROC_FS) [y]
NFS filesystem support (CONFIG_NFS_FS) [y]
ISO9660 cdrom filesystem support (CONFIG_ISO9660_FS) [n]
OS/2 HPFS filesystem support (read only) (CONFIG_HPFS_FS) [n]
System V and Coherent filesystem support (CONFIG_SYSV_FS) [n]
*
* character devices
*
Parallel printer support (CONFIG_PRINTER) [n]
Logitech busmouse support (CONFIG_BUSMOUSE) [n]
PS/2 mouse (aka "auxiliary device") support (CONFIG_PSMOUSE) [y]
C&T 82C710 mouse port support (as on TI Travelmate) (CONFIG_82C710_MOUSE) [y]
Microsoft busmouse support (CONFIG_MS_BUSMOUSE) [n]
ATIXL busmouse support (CONFIG_ATIXL_BUSMOUSE) [n]
Selection (cut and paste for virtual consoles) (CONFIG_SELECTION) [n]
QIC-02 tape support (CONFIG_TAPE_QIC02) [n]
QIC-117 tape support (CONFIG_FTAPE) [n]
*
* Sound
*
Sound card support (CONFIG_SOUND) [n]
*
* Kernel hacking
*
Kernel profiling support (CONFIG_PROFILE) [n]
The linux kernel is now hopefully configured for your setup.
Check the top-level Makefile for additional configuration,
and do a 'make dep ; make clean' if you want to be sure all
the files are correctly re-made
mv .tmpconfig .config
3、编译内核前准备make dep
[root@localhost linux-1.0]# make dep
serial.c:538:8: error: macro names must be identifiers(错误:宏名必须是标识符)
make[2]: *** [dep] Error 1
make[2]: Leaving directory `/mnt/mywork/linux-1.0/drivers/char'
make[1]: *** [dep] Error 2
make[1]: Leaving directory `/mnt/mywork/linux-1.0/drivers'
make: *** [dep] Error 2
解决办法:
serial.c的第538行,修改为这样
//#ifdef 0
#if 0
[root@localhost linux-1.0]# make dep
buffer.c:108:8: error: macro names must be identifiers
make[1]: *** [dep] Error 1
make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'
make: *** [dep] Error 2
解决办法:
buffer.c的第108行,修改为这样
//#ifdef 0
#if 0
[root@localhost linux-1.0]# make dep
touch tools/version.h
for i in init/*.c;do echo -n "init/";gcc -D__KERNEL__ -E -M $i;done > .tmpdepend
for i in tools/*.c;do echo -n "tools/";gcc -D__KERNEL__ -E -M $i;done >> .tmpdepend
set -e; for i in kernel drivers mm fs net ipc ibcs lib; do make -C $i dep; done
make[1]: Entering directory `/mnt/mywork/linux-1.0/kernel'
gcc -D__KERNEL__ -E -M *.c > .depend
make[1]: Leaving directory `/mnt/mywork/linux-1.0/kernel'
make[1]: Entering directory `/mnt/mywork/linux-1.0/drivers'
set -e; for i in block char net FPU-emu; do make -C $i dep; done
make[2]: Entering directory `/mnt/mywork/linux-1.0/drivers/block'
...................................................................................................................
gcc -D__KERNEL__ -E -M *.c > .depend
make[1]: Leaving directory `/mnt/mywork/linux-1.0/lib'
rm -f tools/version.h
mv .tmpdepend .depend
可以看到现在make dep成功。
在编译bootsect.s的时候出现上面的错误,是因为as86不能找到宏定义 DEF_SYSSIZE、DEF_INITSEG等,这是由于bootsect.s中包含#include <linux/config.h>头文件,在gcc的时候应该包含到命令行中,比如makefile中CC =gcc -D__KERNEL__ -I$(TOPDIR)/include,这样as86就能识别出变量定义SYSSIZE = DEF_SYSSIZE等
4、[root@localhost linux-1.0]# make zImage
gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA boot/bootsect.S -o boot/bootsect.s
as86 -0 -a -o boot/bootsect.o boot/bootsect.s
make: as86: Command not found
make: *** [boot/bootsect.o] Error 127
在确保网络连通的情况下进行as86的安装:
[root@localhost linux-1.0]# yum install dev86*
Loaded plugins: refresh-packagekit
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package dev86.i386 0:0.16.17-10.fc10 set to be updated
--> Finished Dependency Resolution
Dependencies Resolved
=================================================================================
Package Arch Version Repository Size
=================================================================================
Installing:
dev86 i386 0.16.17-10.fc10 fedora 374 k
Transaction Summary
=================================================================================
Install 1 Package(s)
Upgrade 0 Package(s)
Total download size: 374 k
Is this ok [y/N]: y
Downloading Packages:
dev86-0.16.17-10.fc10.i386.rpm | 374 kB 00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : dev86-0.16.17-10.fc10.i386 1/1
Installed:
dev86.i386 0:0.16.17-10.fc10
Complete!
[root@localhost linux-1.0]# make zImage
as86 -0 -a -o boot/bootsect.o boot/bootsect.s
ld86 -0 -s -o boot/bootsect boot/bootsect.o
gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA 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
gcc -D__KERNEL__ -E -traditional boot/head.S -o boot/head.s
as -c -o boot/head.o boot/head.s
as: unrecognized option '-c'
make: *** [boot/head.o] Error 1
出错原因:as 语法和1991年的时候有了一些变化。
解决办法:在Makefile中将$(AS) -c -o $*.o $< 修改为 $(AS) -o $*.o $<
[root@localhost linux-1.0]# make zImage
gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA 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
gcc -D__KERNEL__ -E -traditional -DSVGA_MODE=NORMAL_VGA 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
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -m486 -c -o init/main.o init/main.c
cc1: error: unrecognized command line option "-m486"
make: *** [init/main.o] Error 1
出错原因:gcc 3.4 或者更高版本,已经去除了"-m486"和"-m386"
解决办法:在Makefile注释掉下面语句:
##ifdef CONFIG_M486
#CFLAGS := $(CFLAGS) -m486
##else
#CFLAGS := $(CFLAGS) -m386
##endif
或者修改为
ifdef CONFIG_M486
CFLAGS := $(CFLAGS) -march=i486
else
CFLAGS := $(CFLAGS) -march=i386
endif
[root@localhost linux-1.0]# make zImage
/mnt/mywork/linux-1.0/include/linux/string.h:130: error: can't find a register in class ‘SIREG’ while reloading ‘asm’
/mnt/mywork/linux-1.0/include/linux/string.h:130: error: ‘asm’ operand has impossible constraints
make: *** [init/main.o] Error 1
这两个错误都是由于C嵌入汇编用法不对造成的,后续make的时候还会遇到非常多的相同的错误,更改方法都一样。参见下面的引用进行修改:
[root@localhost linux-1.0]# make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c -o init/main.o init/main.c
init/main.c:58: warning: conflicting types for built-in function ‘_exit’
init/main.c:96:8: warning: extra tokens at end of #endif directive
init/main.c: In function ‘get_options’:
init/main.c:159: warning: array subscript has type ‘char’
init/main.c:206:8: warning: extra tokens at end of #endif directive
init/main.c:58:warning: conflicting types for built-in function ‘_exit’这是由于58处定义的int _exit(int exitcode)函数与内置的void _exit(int exitcode)函数定义不一样导致的。更改时可以重新定义一个无返回值的宏,删去原来定义_exit的宏然后用这个无返回值的宏再定义_exit函数。源码定义中修改如下:
在include\linux\unistd.h中,重新定义宏
#define _syscall_exit(type,name,atype,a) \
type name(atype a) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(a))); \
}
init/main.c:58中修改如下:
//static inline _syscall1(int,_exit,int,exitcode)
static inline _syscall_exit(void,_exit,int,exitcode)
这两个警告init/main.c:96:8: warning: extra tokens at end of #endif directive
init/main.c:206:8: warning: extra tokens at end of #endif directive是因为在#endif后面跟了一个宏,只要删掉 每一个#endif后面的宏就可以了。
警告nit/main.c: In function ‘get_options’:
init/main.c:159: warning: array subscript has type ‘char’这是由于传入参数不匹配导致,将isdigit()的参数强制转换成int即可。while (cur && isdigit((int)*cur) && i <= 10)
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-omit-frame-pointer -c sched.c
In file included from sched.c:35:
/mnt/mywork/linux-1.0/include/linux/timex.h:120: error: conflicting type qualifiers for ‘xtime’
/mnt/mywork/linux-1.0/include/linux/sched.h:308: error: previous declaration of ‘xtime’ was here
sched.c:41: error: conflicting type qualifiers for ‘xtime’
/mnt/mywork/linux-1.0/include/linux/sched.h:308: error: previous declaration of ‘xtime’ was here
make[1]: *** [sched.o] Error 1
make[1]: Leaving directory `/mnt/mywork/linux-1.0/kernel'
make: *** [linuxsubdirs] Error 2
解决办法:
修改/include/linux/sched.h第308行,修改为这样
//extern struct timeval xtime;
extern volatile struct timeval xtime;
保持和/include/linux/timex.h中的xtime声明一致
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-omit-frame-pointer -c sched.c
sched.c: Assembler messages:
sched.c:289: Warning: indirect ljmp without `*'
gcc -D__KERNEL__ -E -traditional sys_call.S -o sys_call.s
as -c -o sys_call.o sys_call.s
as: unrecognized option '-c'
make[1]: *** [sys_call.o] Error 1
make[1]: Leaving directory `/mnt/mywork/linux-1.0/kernel'
make: *** [linuxsubdirs] Error 2
解决方法,修改kernel目录下的Makefile文件如下:
.s.o:
$(AS) -o $*.o $<
#$(AS) -c -o $*.o $<
[root@localhost linux-1.0]# make clean;make zImage
fpu_entry.c:473: error: lvalue required as left operand of assignment
fpu_entry.c:474:8: warning: extra tokens at end of #endif directive
fpu_entry.c:528: warning: dereferencing type-punned pointer will break strict-aliasing rules
fpu_entry.c:529:8: warning: extra tokens at end of #endif directive
fpu_entry.c:537:8: warning: extra tokens at end of #endif directive
fpu_entry.c:548: warning: dereferencing type-punned pointer will break strict-aliasing rules
fpu_entry.c:649:8: warning: extra tokens at end of #endif directive
make[2]: *** [fpu_entry.o] Error 1
make[2]: Leaving directory `/mnt/mywork/linux-1.0/drivers/FPU-emu'
解决办法:
文件/linux/drivers/FPU-emu/fpu_system.h中
第64行,修改为这样
//#define FPU_data_address ((void *)(I387.soft.twd))
#define FPU_data_address ((I387.soft.twd))
文件/include/linux/sched.h中
第117行的,修改为这样
struct i387_soft_struct {
long cwd;
long swd;
//long twd;
void* twd;
long fip;
long fcs;
long foo;
long fos;
long top;
struct fpu_reg regs[8]; /* 8*16 bytes for each FP-reg = 128 bytes */
unsigned char lookahead;
struct info *info;
unsigned long entry_eip;
};
[root@localhost linux-1.0]# make clean;make zImage
fpu_trig.c: In function ‘rem_kernel’:
fpu_trig.c:748: error: missing terminating " character
fpu_trig.c:749: error: expected string literal before ‘movl’
fpu_trig.c:750:56: warning: missing terminating " character
fpu_trig.c:750: error: missing terminating " character
解决办法:
文件/linux/drivers/FPU-emu/fpu_trig.c中
第748行,
/* Do the required multiplication and subtraction in the one operation */
asm volatile ("movl %2,%%eax; mull %4; subl %%eax,%0; sbbl %%edx,%1;
movl %3,%%eax; mull %4; subl %%eax,%1;
movl %2,%%eax; mull %5; subl %%eax,%1;"
:"=m" (x), "=m" (((unsigned *)&x)[1])
:"m" (st1),"m" (((unsigned *)&st1)[1]),
"m" (q),"m" (((unsigned *)&q)[1])
:"%ax","%dx");
修改为这样
asm volatile ("movl %2,%%eax; mull %4; subl %%eax,%0; sbbl %%edx,%1;"
"movl %3,%%eax; mull %4; subl %%eax,%1;"
"movl %2,%%eax; mull %5; subl %%eax,%1;"
:"=m" (x), "=m" (((unsigned *)&x)[1])
:"m" (st1),"m" (((unsigned *)&st1)[1]),
"m" (q),"m" (((unsigned *)&q)[1])
:"%ax","%dx");
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c exec.c
exec.c: In function ‘copy_strings’:
exec.c:381: error: lvalue required as left operand of assignment
make[1]: *** [exec.o] Error 1
make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'
make: *** [linuxsubdirs] Error 2
解决办法:
vi /usr/src/linux/fs/exec.c
第380行,修改为这样
if (!(pag = (char *) page[p/PAGE_SIZE]) &&
!(pag = (char *) (page[p/PAGE_SIZE] = (unsigned long *) get_free_page(GFP_USER))))
//!(pag = (char *) page[p/PAGE_SIZE] = (unsigned long *) get_free_page(GFP_USER)))
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c balloc.c
balloc.c:51:10: warning: missing terminating " character
balloc.c: In function ‘find_first_zero_bit’:
balloc.c:51: error: missing terminating " character
balloc.c:52: error: expected string literal before ‘cld’
balloc.c:55:6: error: invalid suffix "f" on integer constant
balloc.c:60:7: error: invalid suffix "f" on integer constant
balloc.c:64:19: warning: missing terminating " character
balloc.c:64: error: missing terminating " character
balloc.c:81:11: warning: missing terminating " character
balloc.c: In function ‘find_next_zero_bit’:
balloc.c:81: error: missing terminating " character
balloc.c:82: error: expected string literal before ‘bsfl’
balloc.c:83:8: error: invalid suffix "f" on integer constant
balloc.c:85:6: warning: missing terminating " character
balloc.c:85: error: missing terminating " character
balloc.c:106:10: warning: missing terminating " character
balloc.c: In function ‘find_first_zero_byte’:
balloc.c:106: error: missing terminating " character
balloc.c:107: error: expected string literal before ‘cld’
balloc.c:110:7: error: invalid suffix "f" on integer constant
balloc.c:112:5: warning: missing terminating " character
balloc.c:112: error: missing terminating " character
make[2]: *** [balloc.o] Error 1
make[2]: Leaving directory `/mnt/mywork/linux-1.0/fs/ext2'
make[1]: *** [filesystems.a] Error 2
make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'
make: *** [linuxsubdirs] Error 2
解决办法:
在/linux/fs/ext2/balloc.c 中
第51行,修改为这样
__asm__("cld\n\t" \
"movl $-1,%%eax\n\t" \
"repe;\n\t" \
"scasl\n\t" \
"je 1f\n\t" \
"subl $4,%%edi\n\t" \
"movl (%%edi),%%eax\n\t" \
"notl %%eax\n\t" \
"bsfl %%eax,%%edx\n\t" \
"jmp 2f\n\t" \
"1: xorl %%edx,%%edx\n\t" \
"2: subl %%ebx,%%edi\n\t" \
"shll $3,%%edi\n\t" \
"addl %%edi,%%edx" \
:"=d" (res)
:"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
);
//:"ax", "bx", "cx", "di");
第81行,修改为这样
__asm__("bsfl %1,%0\n\t" \
"jne 1f\n\t" \
"movl $32, %0\n\t" \
"1: " \
: "=r" (set)
: "r" (~(*p >> bit)));
第106行,修改为这样
__asm__("cld\n\t" \
"mov $0,%%eax\n\t" \
"repnz; scasb\n\t" \
"jnz 1f\n\t" \
"dec %%edi\n\t" \
"1: " \
: "=D" (res)
: "0" (addr), "c" (size)
);
//: "ax");
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c ialloc.c
ialloc.c:42:10: warning: missing terminating " character
ialloc.c: In function ‘find_first_zero_bit’:
ialloc.c:42: error: missing terminating " character
ialloc.c:43: error: expected string literal before ‘cld’
ialloc.c:46:6: error: invalid suffix "f" on integer constant
ialloc.c:51:7: error: invalid suffix "f" on integer constant
ialloc.c:55:19: warning: missing terminating " character
ialloc.c:55: error: missing terminating " character
make[2]: *** [ialloc.o] Error 1
make[2]: Leaving directory `/mnt/mywork/linux-1.0/fs/ext2'
make[1]: *** [filesystems.a] Error 2
make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'
make: *** [linuxsubdirs] Error 2
解决办法:
在文件/linux/fs/ext2/ialloc.c中
第42行,修改为这样
__asm__("cld\n\t" \
"movl $-1,%%eax\n\t" \
"repe; scasl\n\t" \
"je 1f\n\t" \
"subl $4,%%edi\n\t" \
"movl (%%edi),%%eax\n\t" \
"notl %%eax\n\t" \
"bsfl %%eax,%%edx\n\t" \
"jmp 2f\n\t" \
"1: xorl %%edx,%%edx\n\t" \
"2: subl %%ebx,%%edi\n\t" \
"shll $3,%%edi\n\t" \
"addl %%edi,%%edx" \
: "=d" (res)
: "c" ((size + 31) >> 5), "D" (addr), "b" (addr)
);
//: "ax", "bx", "cx", "di");
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c inode.c
inode.c: In function ‘ext2_alloc_block’:
inode.c:110: error: can't find a register in class ‘CREG’ while reloading ‘asm’
inode.c:110: error: ‘asm’ operand has impossible constraints
make[2]: *** [inode.o] Error 1
make[2]: Leaving directory `/mnt/mywork/linux-1.0/fs/ext2'
make[1]: *** [filesystems.a] Error 2
make[1]: Leaving directory `/mnt/mywork/linux-1.0/fs'
make: *** [linuxsubdirs] Error 2
解决办法:
在/mnt/mywork/linux/fs/ext2/inode.c 文件中
第28行修改为如下所示:
#define clear_block(addr,size) \
__asm__("cld\n\t" \
"rep\n\t" \
"stosl" \
: \
:"a" (0), "c" (size / 4), "D" ((long) (addr)) \
)//:"cx", "di"
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe \
-c -o sock.o sock.c
sock.c: In function ‘unix_proto_create’:
sock.c:331: error: lvalue required as left operand of assignment
sock.c: In function ‘unix_proto_release’:
sock.c:363: error: lvalue required as left operand of assignment( 错误:赋值运算的左操作数必须是左值)
make[2]: *** [sock.o] Error 1
make[2]: Leaving directory `/mnt/mywork/linux-1.0/net/unix'
make[1]: *** [subdirs] Error 2
make[1]: Leaving directory `/mnt/mywork/linux-1.0/net'
make: *** [linuxsubdirs] Error 2
解决办法:
vi /mnt/mywork/linux/net/unix/sock.c
第331行,修改为这样
//UN_DATA(sock) = upd;
sock->data = upd;
第363行,修改为这样
//UN_DATA(sock) = NULL;
sock->data = NULL;
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -c -o arp.o arp.c
arp.c:126: error: conflicting type qualifiers for ‘arp_q’
arp.h:48: error: previous declaration of ‘arp_q’ was here
make[2]: *** [arp.o] Error 1
make[2]: Leaving directory `/mnt/mywork/linux-1.0/net/inet'
make[1]: *** [subdirs] Error 2
make[1]: Leaving directory `/mnt/mywork/linux-1.0/net'
make: *** [linuxsubdirs] Error 2
解决办法:
vi /mnt/mywork/linux/net/inet/arp.h
第48行,修改为这样
//extern struct sk_buff *arp_q;
extern struct sk_buff * volatile arp_q;
保持和arp.c中的定义一致
[root@localhost linux-1.0]# make clean;make zImage
fs/fs.o:(.text+0x6391): more undefined references to `gdt' follow
net/net.o: In function `loopback_xmit':
loopback.c:(.text+0x74a7): undefined reference to `_intr_count'
loopback.c:(.text+0x74af): undefined reference to `_bh_active'
loopback.c:(.text+0x74b5): undefined reference to `_bh_mask'
loopback.c:(.text+0x74bd): undefined reference to `_intr_count'
loopback.c:(.text+0x74c2): undefined reference to `_do_bottom_half'
loopback.c:(.text+0x74c8): undefined reference to `_intr_count'
drivers/block/block.a(floppy.o): In function `floppy_ready':
floppy.c:(.text+0xf48): undefined reference to `floppy_track_buffer'
floppy.c:(.text+0x10e2): undefined reference to `tmp_floppy_area'
floppy.c:(.text+0x113e): undefined reference to `tmp_floppy_area'
drivers/block/block.a(floppy.o): In function `redo_fd_request':
floppy.c:(.text+0x13d9): undefined reference to `floppy_track_buffer'
floppy.c:(.text+0x157a): undefined reference to `tmp_floppy_area'
floppy.c:(.text+0x1583): undefined reference to `tmp_floppy_area'
floppy.c:(.text+0x1590): undefined reference to `tmp_floppy_area'
floppy.c:(.text+0x159b): undefined reference to `tmp_floppy_area'
drivers/block/block.a(floppy.o): In function `setup_rw_floppy':
floppy.c:(.text+0x17b3): undefined reference to `floppy_track_buffer'
floppy.c:(.text+0x18d8): undefined reference to `tmp_floppy_area'
floppy.c:(.text+0x193e): undefined reference to `tmp_floppy_area'
drivers/block/block.a(floppy.o): In function `rw_interrupt':
floppy.c:(.text+0x2293): undefined reference to `floppy_track_buffer'
floppy.c:(.text+0x233d): undefined reference to `tmp_floppy_area'
drivers/char/char.a(console.o): In function `scrup':
console.c:(.text+0xb39): undefined reference to `_video_num_columns'
console.c:(.text+0xbbb): undefined reference to `_video_num_columns'
drivers/char/char.a(console.o): In function `con_write':
console.c:(.text+0x26a1): undefined reference to `_video_num_columns'
console.c:(.text+0x2c20): undefined reference to `_video_num_columns'
drivers/char/char.a(keyboard.o): In function `hard_reset_now':
keyboard.c:(.text+0x344): undefined reference to `pg0'
keyboard.c:(.text+0x368): undefined reference to `_no_idt'
make: *** [tools/zSystem] Error 1
大量类似这样的问题
解决办法:
vi boot/head.S
.globl _idt,_gdt,
.globl _swapper_pg_dir,_pg0
.globl _empty_bad_page
.globl _empty_bad_page_table
.globl _empty_zero_page
.globl _tmp_floppy_area,_floppy_track_buffer
修改为
.globl idt,gdt,
.globl swapper_pg_dir,pg0
.globl empty_bad_page
.globl empty_bad_page_table
.globl empty_zero_page
.globl tmp_floppy_area,floppy_track_buffer
并且把标志为由"_"下划线开头的去掉下划线, 这是由as汇编器进化导致的问题.
vi kernel/sys_call.S
vi kernel/ksyms.S
vi kernel/ksyms.sh
vi drivers/FPU-emu/div_small.S
vi drivers/FPU-emu/polynomial.S
vi drivers/FPU-emu/poly_div.S
vi drivers/FPU-emu/poly_mul64.S
vi drivers/FPU-emu/reg_div.S
vi drivers/FPU-emu/reg_norm.S
vi drivers/FPU-emu/reg_round.S
vi drivers/FPU-emu/reg_u_add.S
vi drivers/FPU-emu/reg_u_div.S
vi drivers/FPU-emu/reg_u_mul.S
vi drivers/FPU-emu/reg_u_sub.S
vi drivers/FPU-emu/wm_shrx.S
vi drivers/FPU-emu/wm_sqrt.S
vi net/inet/loopback.c loopback_xmit里相关__asm__的内容
vi drivers/char/keyboard.c hard_reset_now里相关__asm__的内容
vi drivers/char/console.c scrup里相关__asm__的内容; scrdown里相关__asm__的内容
vi usr/include/linux/sched.h switch_to里相关__asm__的内容_current修改为current
vi usr/src/linux/include/asm/irq.h 里相关__asm__的内容
vi drivers/FPU-emu/fpu_asm.h
#define EXCEPTION _exception
修改为
#define EXCEPTION exception
[root@localhost linux-1.0]# make clean;make zImage
kernel/kernel.o: In function `symbol_table':
(.data+0xed0): undefined reference to `verify_write'
make: *** [tools/zSystem] Error 1
解决办法:
vi /mnt/mywork/linux-1.0/include/linux/mm.h
修改
//int __verify_write(unsigned long addr, unsigned long count);
extern int verify_write(unsigned long addr, unsigned long count);
extern inline int verify_area(int type, const void * addr, unsigned long size)
{
if (TASK_SIZE <= (unsigned long) addr)
return -EFAULT;
if (size > TASK_SIZE - (unsigned long) addr)
return -EFAULT;
if (wp_works_ok || type == VERIFY_READ || !size)
return 0;
//return __verify_write((unsigned long) addr,size);
return verify_write((unsigned long) addr,size);
}
vi /mnt/mywork/linux-1.0/mm/memcpy.c
第654行,修改为这样
//int __verify_write(unsigned long start, unsigned long size)
int verify_write(unsigned long start, unsigned long size)
{
size--;
size += start & ~PAGE_MASK;
size >>= PAGE_SHIFT;
start &= PAGE_MASK;
do {
do_wp_page(1,start,current,0);
start += PAGE_SIZE;
} while (size--);
return 0;
}
[root@localhost linux-1.0]# make clean;make zImage
gcc -D__KERNEL__ -O2 -DSTDC_HEADERS -c -o misc.o misc.c
misc.c:81: error: conflicting types for ‘malloc’
misc.c:113: warning: conflicting types for built-in function ‘puts’
make[1]: *** [misc.o] Error 1
make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'
make: *** [zBoot/zSystem] Error 2
解决办法:
vi /mnt/mywork/linux-1.0/zBoot/misc.c
第81行,修改为这样
//void *malloc(int size)
void *malloc(size_t size)
[root@localhost linux-1.0]# make clean;make zImage
ld -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
misc.o: In function `fill_inbuf':
misc.c:(.text+0x42c): undefined reference to `input_len'
misc.c:(.text+0x470): undefined reference to `input_data'
misc.c:(.text+0x47c): undefined reference to `input_data'
make[1]: *** [zSystem] Error 1
make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'
make: *** [zBoot/zSystem] Error 2
解决办法:
vi /mnt/mywork/linux-1.0/zBoot/misc.c
第53行,修改为这样
//extern char input_data[];
char input_data[];
//extern int input_len;
int input_len;
[root@localhost linux-1.0]# make clean;make zImage
ld -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'
gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -o tools/build tools/build.c
tools/build boot/bootsect boot/setup zBoot/zSystem CURRENT > zImage
Root device is (-3, 0)
Boot sector 512 bytes.
Setup is 1980 bytes.
Non-GCC header of 'system'
make: *** [zImage] Error 1
解决办法:
vi /mnt/mywork/linux-1.0/tools/build.c
第191行,修改为这样
//if (N_MAGIC(*ex) != ZMAGIC)
// die("Non-GCC header of 'system'");
[root@localhost linux-1.0]# make clean;make zImage
ld -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'
gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -o tools/build tools/build.c
tools/build boot/bootsect boot/setup zBoot/zSystem CURRENT > zImage
Root device is (-3, 0)
Boot sector 512 bytes.
Setup is 1980 bytes.
System is 64 kB (64 kB code, 0 kB data and 0 kB bss)
Unexpected EOF
Can't read 'system'
make: *** [zImage] Error 1
解决办法:
vi /mnt/mywork/linux-1.0/tools/build.c
第208行,修改为这样
n=read(id, buf, l);
if (n != l) {
if( n < 0)
{
perror(argv[1]);
fprintf(stderr, "Unexpected EOF\n");
die("Can't read 'system'");
}
else if( n == 0)
break;
}
if (write(1, buf, n) != n)
die("Write failed");
sz -= n;
最后编译成功:
gcc -D__KERNEL__ -E -traditional head.S -o head.s
as -o head.o head.s
#as -c -o head.o head.s
gcc -D__KERNEL__ -O2 -DSTDC_HEADERS -c -o inflate.o inflate.c
gcc -D__KERNEL__ -O2 -DSTDC_HEADERS -c -o unzip.o unzip.c
gcc -D__KERNEL__ -O2 -DSTDC_HEADERS -c -o misc.o misc.c
misc.c:54: warning: array ‘input_data’ assumed to have one element
ld -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
make[1]: Leaving directory `/mnt/mywork/linux-1.0/zBoot'
gcc -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -o tools/build tools/build.c
tools/build boot/bootsect boot/setup zBoot/zSystem CURRENT > zImage
Root device is (-3, 0)
Boot sector 512 bytes.
Setup is 1980 bytes.
System is 64 kB (64 kB code, 0 kB data and 0 kB bss)
sync
[root@localhost linux-1.0]# ls
boot Configure fs ipc makever.sh tools
CHANGES COPYING ibcs kernel mm zBoot
config.in CREDITS include lib net zImage
config.old drivers init Makefile README zSystem.map
[root@localhost linux-1.0]#
对于ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000错误的解决方法是修改两个地方:
vi /linux-1.0/boot/head.S
在文件开始出添加:
.globl startup_32
vi /linux-1.0/Makefile第203行修改为:
tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs
$(LD) $(LDFLAGS) -e startup_32 -Ttext 100000 boot/head.o init/main.o tools/version.o
vi /linux-1.0/zboot/head.s
在文件开始出添加
.globl startup_32
vi /linux-1.0/zBoot/Makefile第22行修改为:
zSystem: piggy.o $(zOBJECTS)
$(LD) $(LDFLAGS) -o zSystem -e startup_32 -Ttext 1000 $(zOBJECTS) piggy.o
更多推荐
所有评论(0)