Linux 0.01をどのようにコンパイルしますか?

Linux 0.01をどのようにコンパイルしますか?

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

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

関連情報