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成功。

linux1.0内核代码学习(一) - 北极星 - xiebingsuccess的博客

 在编译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的时候还会遇到非常多的相同的错误,更改方法都一样。参见下面的引用进行修改:

linux1.0内核代码学习 - 北极星 - xiebingsuccess的博客

[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

猜你喜欢

转载自blog.csdn.net/xiebingsuccess/article/details/88719893