私は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