Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第3章_3.5カーネルからピクセルを描く(osbook_day03c)が書籍通りの実行結果とならない #168

Open
Ryoya28 opened this issue Apr 29, 2024 · 8 comments

Comments

@Ryoya28
Copy link

Ryoya28 commented Apr 29, 2024

(概要)
p85 の図3-8 適当な模様をフレームバッファに描くができません #166にてtaxin39様が質問されているissueと同等の内容となりますが、自分の環境でも書籍通りの実行結果にならずフレームバッファが白で塗りつぶされるといった状況で行き詰まっております。

(実行環境)
OS:Windows
「付録A_開発環境のインストール」の手順通りにWSL、QEMU、Xサーバーの環境構築を実施

(検証内容)
下記手順をそれぞれ実行してみましたが「フレームバッファが白で塗りつぶされる」という実行結果を解消することができない。

  1. taxin39様投稿のissueに記載ある手順と全く同じコマンドで実行
  2. MikanLoaderPkgのシンボリックリンク貼り替え
      →既存のリンクrmコマンドで削除し貼り直し
  3. clang++及びld.lld実行前に既存のmain.o、kernel.elfを削除してから実行
      →古い情報が残ってしまっている可能性があると考えた為
  4. Ubuntu再インストール、環境構築からやり直して1.の手順再実施
  5. 一旦第3章を飛ばし、第4章の「ピクセルを自在に描く」を実施、osbook_day04bにcheckoutしコンパイルやリンク作成等実行しqemu実行

なお、本事象発生後、gitのタグをosbook_day02aに切り替え「EDKⅡでハローワールド」章を実行したところ、書籍通りの実行結果になる事が確認できました。

(確認事項)
本事象につきまして上記検証内容から、他検証すべき手順及び解消方法が見つかるものかご確認/ご助力をお願いしたいです。

お手数おかけしますがご確認の程よろしくお願い申し上げます。

@Ryoya28 Ryoya28 changed the title 第3章_3.5カーネルからピクセルを描く(osbook_day03c) 第3章_3.5カーネルからピクセルを描く(osbook_day03c)が書籍通りの実行結果とならない Apr 30, 2024
@Ryoya28
Copy link
Author

Ryoya28 commented May 8, 2024

2024/05/08追記
・調査進捗報告
 - 3章~4章を書籍の通りコマンド実行し出力結果確認→qemuのフレームバッファが白く塗りつぶされるまま変わらない。
 - 5章(osbook_day05a)を書籍の通りコマンド実行し出力結果確認→書籍の通り白背景に一部グリーン塗りつぶしの上"AA"と表示される事確認

@uchan-nos
Copy link
Owner

検証報告をありがとうございます。

#166 (comment) で書いた Main.c の書き換えで挙動が変化するかの確認と、kernel.elf のファイルサイズの確認をしていただけるでしょうか。

@Ryoya28
Copy link
Author

Ryoya28 commented May 11, 2024

Main.c の書き換えで挙動が変化するかの確認
Main.cの書き換えで挙動が変化する事確認できました。

Main_c書き換え前

Main_c書き換え後

kernel.elf のファイルサイズの確認
1448byteと出力が確認できました。

kernel_elfサイズ

上記より他QAをあげられている方とファイルサイズが異なるのが原因の1つと考えているのですがファイルサイズの違いは開発環境ごとに変わるものでしょうか?

@pickamirai
Copy link

私も白い塗りつぶしの画面から進みません。しましまの模様にしたいです。以下実行したもの
cd $HOME/workspace/mikanos
git checkout osbook_day03c
cd $HOMsource edksetup.sh
source edksetup.sh
build
source $HOME/osbook/devenv/buildenv.sh
cd /home/mi/workspace/mikanos/kernel
source $HOME/osbook/devenv/buildenv.sh
clang++ $CPPFLAGS -O2 --target=x86_64-elf -fno-exceptions -ffreestanding -c main.cpp
ld.lld $LDFLAGS --entry KernelMain -z norelro --image-base 0x100000 --static -o kernel.elf main.o
$HOME/osbook/devenv/run_qemu.sh /home/mi/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi /home/mi/workspace/mikanos/kernel/kernel.elf

前の状態の白く塗りつぶしするファイルが変更されていないのでしょうか?カーネルをコンパイルするときはどのように手順が変わりますか?

@drymouse
Copy link

私も同様の現象が起きております。確認してみると、osbook_day03aの時点で、KernelMain()が呼ばれていないようです。
osbook_day03aにおいて、カーネルのベースアドレスとサイズが表示されたあとにinfo registersを何度か実行してみると、RIP=0x3fb73016でずっと変わらないことが分かりました。その部分を見てみると、

0x000000003fb73016:  cmpq   $0x0,0x40(%rsp)
0x000000003fb7301c:  je     0x3fb73016

という機械語があり、RSP+0x40には0x0が格納されているため、ここで無限ループが発生している模様です。(これはkernel.elf内の無限ループとは別の部分です)
また、ブートローダを終了させる部分に所々Print()を配置すると、二回目のgBS->ExitBootServices()の前のPrintは実行されますが、その後に置いたPrintは実行されていないようです。そのため、この無限ループは二回目のExitBootServices()の中で発生していると考えています。

この問題については、osbook_day03cに切り替えても同じ部分で無限ループに入っているため、KernelMain()が実行されないために、画面に縞模様も現れないのだと考えています。

いずれにせよ、kernel.elf が実行できないままだとこの先の章の内容も試すことができなくなってしまうため、解決法に心当たりがある方は、教えていただきたいです。

お忙しいところ恐縮ではありますが、よろしくお願いいたします。

実行環境

  • Windows 11
  • WSL2 + QEMU

@tito2-lab
Copy link

tito2-lab commented Sep 21, 2024

同様の現象にあたりまして、確認できたことをご連絡いたします。解決方法はまだわかっておりません。。。ご助言いただけますと幸いです。
問題発生個所の特定にあたり、以下のようにMain.c内でPrint分で出力を行いました。

  // #@@range_begin(exit_bs)
  EFI_STATUS status;
  status = gBS->ExitBootServices(image_handle, memmap.map_key);
  if (EFI_ERROR(status)) {
    Print(L" EFI Error??: %r\n", EFI_ERROR(status));
    status = GetMemoryMap(&memmap);
    Print(L" EFI Error??: %r\n", EFI_ERROR(status));
    if (EFI_ERROR(status)) {
      Print(L"failed to get memory map: %r\n", status);
      while (1);
    }
    status = gBS->ExitBootServices(image_handle, memmap.map_key);
    Print(L" EFI Error??: %r\n", EFI_ERROR(status));

    if (EFI_ERROR(status)) {
      Print(L"Could not exit boot service: %r\n", status);
      while (1);
    }
  }
  // #@@range_end(exit_bs)

結果白画面に以下の出力がでてきました。

Kernel: 0x100000 (1432 Bytes)
 EFI Error??: Warning Unknown Glyph
 EFI Error??: Success
 EFI Error??: Warning Unkown Glyph
Could not exit boot service: Invalid Parameter

これにより以下の仮説を持っています。

  •  gBS->ExitBootServices(image_handle, memmap.map_key); によるブートサービスの停止処理がうまいくいかない (本書リスト3.4)
  • while(1) にて停止 (RIP=0x3fb73016: 0x000000003fb73016: cmpq $0x0,0x40(%rsp) ?)
  • Status Codeは "Warning Unknown Glyph"

ブートサービスの停止処理ができずKernelが立ち上がっていないと考えていますが、この Unknown Glyph の解決方法がわかりませんでした。恐れ入りますがご助言いただけますと幸いです。

実行環境

  • Windows 11
  • WSL2 + QEMU
  • Ubuntu 20.04

@ota0410
Copy link

ota0410 commented Sep 25, 2024

何らかのお役に立てられれば、と思いコメントします。

■ 背景
ここまでのコメントを参照していて、

  • ブートサービスが正常に終了できない
  • Kernelが立ち上がらない

という状況が確認できました。

ダメ元でMain.cのEFI_STATUSの値に0を代入させ、EFI_ERRORに引っかからないようにしてみる等、
試して結果を見たものの、当然カーネルを呼び出す部分である、
entry_point(gop->Mode->FrameBufferBase, gop->Mode->FrameBufferSize);
以降に進まないことを確認しました。その後も色々試してみたり、他のissuesを調べたりしていたのですが、
こちら( #134 )の状況が本件に近そうかと考えました。

■ 実施したこと
大きく分けて2点を実施しました。

1. clangおよびlldのバージョンを変更する
上記のissues内にも記載のある通り、
こちら( uchan-nos/mikanos-build#35 )を参考に、古いバージョンのclang+llvmを入れました。
(原因切り分けのため、既存のclang+llvmをremoveせずに実施)

このとき、ダウンロードしてきたclangやlldをそのまま使おうとすると、libtinfo.so.5が無いとエラーが出るかもしれません。
そのため、ダウンロードしてきたclang+llvm-7.1.0-x86_64-linux-gnu-ubuntu-14.04/libの中に、
ln -s /usr/lib/x86_64-linux-gnu/libtinfo.so.6 libtinfo.so.5
として、現時点でマシン内に入っているlibtinfo.so.6へのシンボリックリンクを作ることで、古いバージョンのclang/lldを使ってmain.cppがコンパイル/リンクができました。
コンパイル/リンク時のオプションは特に変更していません。必要に応じてlibncurses6をインストールしてください。

2. CLANGPDB利用時のABI指定追記を行う
こちらは人によっては不要かもしれません。
私はTOOL_CHAIN_TAG=CLANGPDBを利用していたので、こちらを参照しながらMain.c中の、
typedef void EntryPointType(UINT64, UINT64);
typedef void __attribute__((sysv_abi)) EntryPointType(UINT64, UINT64);に置き換えていました。

以上の2点を実施し、下記のようにコマンドを実行しました。
$HOME/osbook/devenv/run_qemu.sh $HOME/edk2/Build/MikanLoaderX64/DEBUG_CLANGPDB/X64/Loader.efi $HOME/workspace/mikanos/kernel/kernel.elf

結果、下図のように結果を出力できました。
image

私の実行環境は下記の通りです。

  • Ubuntu 24.04.1
  • QEMU

不適切な部分等あればご指摘いただけますと幸いです。

@tito2-lab
Copy link

@ota0410 情報ありがとうございました!またいろいろ調査いただきまして大変恐縮です。
おっしゃられたように古いバージョンのclang+llvmでやり直して試したところ、最終的には画面を出力することができました。

変更後、改めて osbook_day03a から仕切り直してみました。その途中、(これはまた別問題かと思いますが、)Tool Chain TagにCLANGPDBを指定していたのですが、Build エラーで止まってしまったため、GCC5に変更したところ出力ができるようになりました。
いろいろあいまいな情報共有で恐縮ですが取り急ぎのご連絡となります。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants