나는 Linux 커널을 다시 컴파일하는 과정을 접하면서 이 주제에 어느 정도 관심을 가지게 되었습니다. 그래서 출력을 더 깊이 관찰하기 위해 github에서 Linux 커널 0.01을 다운로드했습니다(https://github.com/liudonghua123/linux-0.01). 실행할 때 make
(추가 매개변수 없음) 오류가 발생했습니다.
$ cd 'linux_kernel(0.01)-source_code'
$ make
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -fno-stack-protector \
-nostdinc -Iinclude -c -o init/main.o init/main.c
In file included from include/sys/stat.h:5,
from include/unistd.h:53,
from init/main.c:2:
include/stdint.h:153: warning: "__INT64_C" redefined
153 | # define __INT64_C(c) c ## LL
|
<built-in>: note: this is the location of the previous definition
In file included from include/sys/stat.h:5,
from include/unistd.h:53,
from init/main.c:2:
include/stdint.h:154: warning: "__UINT64_C" redefined
154 | # define __UINT64_C(c) c ## ULL
|
<built-in>: note: this is the location of the previous definition
In file included from init/main.c:3:
include/time.h:39:8: warning: conflicting types for built-in function ‘strftime’; expected ‘long unsigned int(char *, long unsigned int, const char *, const void *)’ [-Wbuiltin-declaration-mismatch]
39 | size_t strftime(char * s, size_t smax, const char * fmt, const struct tm * tp);
| ^~~~~~~~
include/time.h:1:1: note: ‘strftime’ is declared in header ‘<time.h>’
+++ |+#include <time.h>
1 | #ifndef _TIME_H
init/main.c: In function ‘printf’:
init/main.c:114:45: warning: passing argument 3 of ‘vsprintf’ from incompatible pointer type [-Wincompatible-pointer-types]
114 | write(1,printbuf,i=vsprintf(printbuf, fmt, args));
| ^~~~
| |
| va_list {aka char *}
init/main.c:38:12: note: expected ‘__va_list_tag *’ but argument is of type ‘va_list’ {aka ‘char *’}
38 | extern int vsprintf();
| ^~~~~~~~
init/main.c: Assembler messages:
init/main.c:93: Error: invalid instruction suffix for `push'
init/main.c:94: Error: invalid instruction suffix for `push'
init/main.c:95: Error: invalid instruction suffix for `pushf'
init/main.c:96: Error: invalid instruction suffix for `push'
init/main.c:97: Error: invalid instruction suffix for `push'
make: *** [Makefile:27: init/main.o] Error 1
$
(쉘에서 정확한 단어를 복사했습니다)
어떻게 고치나요?
답변1
0.01 커널은 64비트 x86용으로 빌드할 수 없습니다. x86에서는 32비트를 대상으로 해야 합니다. 게다가 최근 링커 변경으로 인해 코드가 링크되지 않습니다. 여러 정의를 허용하여 이 문제를 해결할 수 있습니다.
내보내기 를 위해 편집하여 해결할 수 있는 몇 가지 남은 문제가 있습니다 kernel/console.c
.columns
attr
static unsigned long lines=LINES;
unsigned long columns=COLUMNS;
static unsigned long state=0;
static unsigned long npar,par[NPAR];
static unsigned long ques=0;
unsigned char attr=0x07;
그러다가, 즉시,
make CC="gcc -m32" AS="as --32" LD="ld -melf_i386 --allow-multiple-definition" clean Image
적어도 GCC 10을 사용하여 성공적으로 완료됩니다(적절한 GCC 및 binutils가 있고 Bruce Evans가 있다고 가정 as86
) . ld86
나는 아직 그것을 시도하지 않았습니다시작하다생성된 커널. ELF 커널이 제대로 작동할지 잘 모르겠습니다.
답변2
Ubuntu 18.04 64 및 32비트 버전에서 컴파일할 수 있도록 변경된 사항을 보려면 이 저장소를 확인하세요. 또한 qemu에서 실행되는 make 명령도 있습니다. https://github.com/mariuz/linux-0.01