Mercurial > hg > Papers > 2021 > okud-thesis
changeset 18:e8a0f9380734
paper fix
author | okud |
---|---|
date | Mon, 15 Feb 2021 21:10:15 +0900 |
parents | 7aa7bb77556c |
children | 0dd66a59256b |
files | paper/chapter/chapter2.tex paper/chapter/chapter3.tex paper/chapter/chapter4.tex paper/chapter/chapter5.tex paper/chapter/chapter6.tex paper/chapter/introduction.tex paper/file/bootloader.c paper/final_thesis.pdf paper/final_thesis.tex prepaper/file prepaper/pre.pdf slide/slide.md slide/slide.pdf |
diffstat | 13 files changed, 281 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/paper/chapter/chapter2.tex Mon Feb 15 05:00:58 2021 +0900 +++ b/paper/chapter/chapter2.tex Mon Feb 15 21:10:15 2021 +0900 @@ -16,7 +16,7 @@ \end{figure} CbCには、GCC\cite{gcc}上に実装されたものとLLVM/Clang\cite{llvm}上に実装されたものがある。 -GCCとLLVM/Clangで実装されたCbCをARMでCompileするにはCross Compileを行う必要がある。 +GCCとLLVM/Clangで実装されたCbCをx86上でARMのコードを実行するにはCross Compileを行う必要がある。 GCCとLLVMではCbCを動かすのにGCCの方が安定しているのでCbCのGCCのCrossCompile環境を作成する。 このCross Compile環境はSingularityで作成した。 @@ -49,7 +49,6 @@ \section{CbC on GCC CrossCompile } Singularityで環境を作成するためにソースコード\ref{src:cbc_gcc_cross}を作成する。 -\renewcommand{\lstlistingname}{ソースコード} \lstinputlisting[language=Bash, numbers=left, breaklines=true, basicstyle=\ttfamily\footnotesize, frame=single, caption=CbC\_gcc\_cross.def, label=src:cbc_gcc_cross]{file/cbc_gcc_cross.def} defファイルが作成できたらsingularity buildを下記のように行う。 \begin{lstlisting}[frame=lrbt,label=sif build,caption={singularity build}]
--- a/paper/chapter/chapter3.tex Mon Feb 15 05:00:58 2021 +0900 +++ b/paper/chapter/chapter3.tex Mon Feb 15 21:10:15 2021 +0900 @@ -49,7 +49,7 @@ \label{raspi} \end{figure} -\renewcommand{\lstlistingname}{コマンド} + \begin{lstlisting}[frame=lrbt,label=screen,caption={screenコマンド}] $ screen /dev/tty.usbserial-143130 1152000 \end{lstlisting} \ No newline at end of file
--- a/paper/chapter/chapter4.tex Mon Feb 15 05:00:58 2021 +0900 +++ b/paper/chapter/chapter4.tex Mon Feb 15 21:10:15 2021 +0900 @@ -45,6 +45,8 @@ 第一セクタの512バイトがメモリにコピーされ、そこにジャンプする。 そして、そのBootLoaderが起動する。BootLoaderがカーネルとディスクイメージをメモリにロードし、 カーネルが初期化処理をする。その後OSが起動される。 + + UEFIは、UEFIファームウェアがロードされ、起動に必要なハードウェアを初期化する。 次にファームウェアがBootマネージャのデータを読み込みどのUEFI Applicationをどこから起動するか決定する。 ファームウェアのブートマネージャのブートエントリに定義されているように UEFI Application をファームウェアが起動する。 @@ -82,7 +84,9 @@ Tianocoreは、独自のビルドシステムをもつ大規模で複雑な環境で、 CrossCompilerとしてGCC、MinGW、Microsoft Visual C++などが使用できる。 UEFI Application のコンパイルだけでなくBIOS ROMにフラッシュするUEFIファームウェアのコンパイルにも利用できる。 - Gnu-efiは、システムのネイティブGCCでUEFIアプリケーションをコンパイルするためのライブラリとヘッダのセットである。 + + +Gnu-efiは、システムのネイティブGCCでUEFIアプリケーションをコンパイルするためのライブラリとヘッダのセットである。 UEFI ファームウェアのコンパイルには使用できない。UEFI Applicationをリンクするためのライブラリがいくつかあり、 UEFI Applicationの開発に特化している。
--- a/paper/chapter/chapter5.tex Mon Feb 15 05:00:58 2021 +0900 +++ b/paper/chapter/chapter5.tex Mon Feb 15 21:10:15 2021 +0900 @@ -3,18 +3,18 @@ \section{Boot Loader} Boot Loaderは、OSをLoadしてBootさせる役割をもつプログラムである。 -図\ref{bootloader}は、UEFIとPlatformの関係を表したもので、赤い円の部分がBootLoaderである。 -図\ref{bootloader}のようにBootLoaderはBootManagerから起動され、OSをLoadし、Bootさせる。 +図\ref{loader}は、UEFIとPlatformの関係を表したもので、赤い円の部分がBootLoaderである。 +図\ref{loader}のようにBootLoaderはBootManagerから起動され、OSをLoadし、Bootさせる。 \begin{figure}[H] \begin{center} \includegraphics[width=150mm]{fig/bootloader.png} \end{center} \caption{bootloader} - \label{bootloader} + \label{loader} \end{figure} -BootLoaderでOSをbootさせる仕組みを\ref{bootos}に示す。 +BootLoaderでOSをbootさせる仕組みを図\ref{bootos}に示す。 初めに、ハードウェアに電源が繋がり、UEFIが起動する。 UEFIのBoot ManagerがBoot Loaderを起動する。 その後Boot LoaderがOSのKernelをメモリにLoadさせる。 @@ -30,8 +30,30 @@ \label{bootos} \end{figure} -\section{xv6 bootloader} -実装中 +\section{bootloaderの実装} +UEFI Applicationとしてgnu-efiでBootLoaderを実装した。 +ソースコード\ref{src:bootloader}がBootLoaderである。 +18行目で efi\_mainの引数であった EFI\_IMAGE\_HANDLE型の ImageHandleを使って、 +EFI\_LOADED\_IMAGE\_PROTOCOLを構造体 LoadedImageParentに入れている。 +この IMAGEは実行メモリイメージで ImageHandleが実行している自身のハンドルになる。 +LOADED\_ IMAGE\_ PROTOCOLは既にメモリ上に Load済みのImageに対して情報を得る事ができる。 + + +24行目でハンドルのDevicePathを使って OSのファイルへのファイルパスを EFI\_DEVICE\_PATH型の変数に代入している。 +BootLoaderはEFIシステムパーテーションに置かれ、このパーテーションは HDDの先頭の FAT32になる。 +なので、DevicePathはこのシステムパーテーションのDeviceそのものを指すことになる。 +つまり、このシステムパーテーションの root directoryにある OSについての DevicePathを Pathという変数に格納した。 +この DevicePath は BootLoaderが Kernel を Loadする際に使用する。 + + +30行目の BS-\verb|>| LoadImage()で OS を呼び出し、その Kernelをメモリに展開している。 +そして46行目の BS->StartImage()でLoadされた Imageを起動し、Kernelを起動する。 + + +これにより、BootLoaderがOSをBootすることができる様になる。 + +\lstinputlisting[language=Bash, numbers=left, breaklines=true, basicstyle=\ttfamily\footnotesize, frame=single, caption=bootloader.c, label=src:bootloader]{file/bootloader.c} +
--- a/paper/chapter/chapter6.tex Mon Feb 15 05:00:58 2021 +0900 +++ b/paper/chapter/chapter6.tex Mon Feb 15 21:10:15 2021 +0900 @@ -1,5 +1,24 @@ \chapter{今後の課題} -\section{今後の課題} -aaaa \ No newline at end of file + +今後の課題として以下の5つを挙げる。 +\begin{itemize} + \item Singularity上のqemu-system-armにgdbを接続する + \item そのgdbでKernel Loaderをでバックする + \item xv6 KernelをUEFIからBootするコードを入れる + \item xv6を書き換えたGearsOSを実装する + \item USB Driverを実装し、キーボードやマウスを使える様にする +\end{itemize} +Singularity上のqemu-system-armにgdbを接続することができれば、 +UEFI上で起きた不具合やプログラムの流れを可視化できる様になる。 +これにより、UEFIのApplicationの開発や組み込み実装がスムーズに行える様になる。 +そして、そのgdbでKernel Loaderをでバックすることをすれば、 +BootLoaderやKernel Loadの動きを見ることができ、個人でBootLoaderを作ることができる。 +ほぼ全てのOSをUEFIからBootできる様になる。 +つまり、xv6 KernelをUEFIからBootするコードを入れることができ、 +xv6を書き換えたGearsOSをUEFIから実装することができる。 +xv6をUEFIからBootすることができれば、 +UEFIはI/Oのデバイスパスを持っているので、 +USB DriverをUEFI Applicationで実装できる。 +USB Driverが存在すれば、GearsOSにキーボードやマウスが使える様になる。
--- a/paper/chapter/introduction.tex Mon Feb 15 05:00:58 2021 +0900 +++ b/paper/chapter/introduction.tex Mon Feb 15 21:10:15 2021 +0900 @@ -1,6 +1,6 @@ -\chapter{初めに} +\chapter{UEFIへの移行} \pagenumbering{arabic} %ページ番号の表記方法 -\section{要旨} +\section{研究目的} 2017年、Intel社は2020年までにLegacy BIOSとUEFIへの互換を非推奨とし、互換モジュールのCSMを削除すると発表した。\cite{IntelNews} Legacy BIOSは長年に渡り16bitパソコンの時代からの資産を引き継いできたため、16bitモードでしか動作しない。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/file/bootloader.c Mon Feb 15 21:10:15 2021 +0900 @@ -0,0 +1,55 @@ +#include<efi.h> +#include<efilib.h> + + +EFI_STATUS +efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_DEVICE_PATH *Path; + EFI_LOADED_IMAGE *LoadedImageParent; + EFI_LOADED_IMAGE *LoadedImage; + EFI_HANDLE Image; + CHAR16 *Options = L"root=/dev/sda2 rootfstype=btrfs rw quiet splash"; + EFI_STATUS Status=EFI_SUCCESS; + + InitializeLib(ImageHandle, SystemTable); + Print(L"Hello, EFI!\n"); + + Status = uefi_call_wrapper(BS->OpenProtocol, 6, ImageHandle, &LoadedImageProtocol,(void**)&LoadedImageParent, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + return Status; + } + Print(L"Hello,2!\n"); + Path = FileDevicePath(LoadedImageParent->DeviceHandle, L"\\OS"); + if (Path == NULL) { + Print(L"Could not get device path."); + return EFI_INVALID_PARAMETER; + } + Print(L"Hello,3!\n"); + Status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, ImageHandle, Path, NULL, 0, &Image); + if (EFI_ERROR(Status)) { + Print(L"Could not load %r", Status); + FreePool(Path); + return Status; + } + Print(L"Hello,4!\n"); + Status = uefi_call_wrapper(BS->OpenProtocol, 6, Image, &LoadedImageProtocol, (void**)&LoadedImage, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + return Status; + } + Print(L"Hello,5!\n"); + LoadedImage->LoadOptions = Options; + LoadedImage->LoadOptionsSize = (StrLen(LoadedImage->LoadOptions)+1) * sizeof(CHAR16); + + Print(L"Hello,6!\n"); + Status = uefi_call_wrapper(BS->StartImage, 3, Image, NULL, NULL); + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + Print(L"Hello,7!\n"); + + return EFI_SUCCESS; +}
--- a/paper/final_thesis.tex Mon Feb 15 05:00:58 2021 +0900 +++ b/paper/final_thesis.tex Mon Feb 15 21:10:15 2021 +0900 @@ -29,7 +29,7 @@ numbersep=1zw, lineskip=-0.5ex } - +\def\lstlistingname{ソースコード} \def\lstlistlistingname{リスト目次} \setlength{\itemsep}{-1zh}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prepaper/file Mon Feb 15 21:10:15 2021 +0900 @@ -0,0 +1,55 @@ +#include<efi.h> +#include<efilib.h> + + +EFI_STATUS +efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_DEVICE_PATH *Path; + EFI_LOADED_IMAGE *LoadedImageParent; + EFI_LOADED_IMAGE *LoadedImage; + EFI_HANDLE Image; + CHAR16 *Options = L"root=/dev/sda2 rootfstype=btrfs rw quiet splash"; + EFI_STATUS Status=EFI_SUCCESS; + + InitializeLib(ImageHandle, SystemTable); + Print(L"Hello, EFI!\n"); + + Status = uefi_call_wrapper(BS->OpenProtocol, 6, ImageHandle, &LoadedImageProtocol,(void**)&LoadedImageParent, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + return Status; + } + Print(L"Hello,2!\n"); + Path = FileDevicePath(LoadedImageParent->DeviceHandle, L"\\xv6.img"); + if (Path == NULL) { + Print(L"Could not get device path."); + return EFI_INVALID_PARAMETER; + } + Print(L"Hello,3!\n"); + Status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, ImageHandle, Path, NULL, 0, &Image); + if (EFI_ERROR(Status)) { + Print(L"Could not load %r", Status); + FreePool(Path); + return Status; + } + Print(L"Hello,4!\n"); + Status = uefi_call_wrapper(BS->OpenProtocol, 6, Image, &LoadedImageProtocol, (void**)&LoadedImage, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + return Status; + } + Print(L"Hello,5!\n"); + LoadedImage->LoadOptions = Options; + LoadedImage->LoadOptionsSize = (StrLen(LoadedImage->LoadOptions)+1) * sizeof(CHAR16); + + Print(L"Hello,6!\n"); + Status = uefi_call_wrapper(BS->StartImage, 3, Image, NULL, NULL); + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + Print(L"Hello,7!\n"); + + return EFI_SUCCESS; +}
--- a/slide/slide.md Mon Feb 15 05:00:58 2021 +0900 +++ b/slide/slide.md Mon Feb 15 21:10:15 2021 +0900 @@ -8,7 +8,7 @@ style: | section { background-color: #FFFFFF; - font-size: 28px; + font-size: 40px; color: #4b4b4b; font-family: "Arial", "Hiragino Maru Gothic ProN"; } @@ -58,14 +58,6 @@ --- <!-- class: slide --> - -![CbCの遷移](images/CbC.png) - - - - ---- -<!-- class: slide --> # GearsOS - 並列信頼研究で開発されているOS - 信頼性と拡張性がテーマ @@ -99,15 +91,10 @@ --- <!-- class: slide --> # UEFI 開発環境 -- EDK2 +- edk2 - gnu-efi - ---- -<!-- class: slide --> -# EDK2 -- 独自のビルドシステムをもつ大規模で複雑な環境 -- CrossCompilerとしてGCC、MinGW、Microsoft Visual C++などが使用できる -- UEFI Application のコンパイルだけでなくBIOS ROMにフラッシュするUEFIファームウェアのコンパイルにも利用できる +- qemu +- singularity --- <!-- class: slide --> @@ -115,12 +102,118 @@ - システムのネイティブGCCでUEFIアプリケーションをコンパイルできる - UEFI Applicationをリンクするためのライブラリがある - UEFI Applicationの開発に特化している +- EDK2のファームウェアがベース + +--- +# UEFI Applicationの例 +Hello.c +``` +#include <efi.h> +#include <efilib.h> + +EFI_STATUS +EFIAPI +efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + InitializeLib(ImageHandle, SystemTable); + Print(L"Hello, world!\n"); + return EFI_SUCCESS; +} +``` +--- +BootLoader.c +``` +#include<efi.h> +#include<efilib.h> + +EFI_STATUS +efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_DEVICE_PATH *Path; + EFI_LOADED_IMAGE *LoadedImageParent; + EFI_LOADED_IMAGE *LoadedImage; + EFI_HANDLE Image; + CHAR16 *Options = L"root=/dev/sda2 rootfstype=btrfs rw quiet splash"; + EFI_STATUS Status=EFI_SUCCESS; + + InitializeLib(ImageHandle, SystemTable); + Print(L"Hello, EFI!\n"); + + Status = uefi_call_wrapper(BS->OpenProtocol, 6, ImageHandle, &LoadedImageProtocol,(void**)&LoadedImageParent, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + return Status; + } + Path = FileDevicePath(LoadedImageParent->DeviceHandle, L"\\xv6.img"); + if (Path == NULL) { + Print(L"Could not get device path."); + return EFI_INVALID_PARAMETER; + } + Status = uefi_call_wrapper(BS->LoadImage, 6, FALSE, ImageHandle, Path, NULL, 0, &Image); + if (EFI_ERROR(Status)) { + Print(L"Could not load %r", Status); + FreePool(Path); + return Status; + } + Status = uefi_call_wrapper(BS->OpenProtocol, 6, Image, &LoadedImageProtocol, (void**)&LoadedImage, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Print(L"Could not get LoadedImageProtocol handler %r\n", Status); + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + return Status; + } + LoadedImage->LoadOptions = Options; + LoadedImage->LoadOptionsSize = (StrLen(LoadedImage->LoadOptions)+1) * sizeof(CHAR16); + + Print(L"Hello,6!\n"); + Status = uefi_call_wrapper(BS->StartImage, 3, Image, NULL, NULL); + uefi_call_wrapper(BS->UnloadImage, 1, Image); + FreePool(Path); + + return EFI_SUCCESS; +} +``` --- <!-- class: slide --> -# UEFIによるGearsOSのBoot +# qemu +- 異なるアーキテクチャのプログラムを動かすエミュレータ +- 本開発ではX86上でARMを動かした +- gnu-efiで実装したUEFIを動かした + + +--- +<!-- class: slide --> +# singularity +- ユーザーが自身の計算環境を完全再現し、保持できる様にしたLinuxコンテナ +- 学科の新システムで利用できる +- CbC GCC ARM CrossCompile環境を作った +- UEFIの開発環境を作った --- <!-- class: slide --> -# まとめ(デモ???) +# 研究の成果 +- uefiの開発環境をSingularityで作成した +- GNU-efiで作成したUEFI ApplicationをQEMU-ARMで動かすことができた +- RaspberryPiにUEFIをファームウェアとして設定し、実行することができた +- ミニマムなKernel Loaderを調査しARM xv6用に書き直した + + +--- +<!-- class: slide --> +# 今後の課題 +- Singularity上のqemu-system-armにgdbを接続する +- そのgdbでKernel Loaderをでバックする +- xv6 KernelにUEFIからBootするコードを入れる +- xv6を書き換えたGearsOSを実装する +- USB Driverを実装し、キーボードやマウスを使える様にする + +--- +<!-- class: slide --> +# 大変だったこと +- EDK2は汎用的だがARMのConfigなどの書き換えが困難 +- UEFI開発の情報が少なく、偏りがあった +- UEFI独特のプログラムの書き方があった +- 低レベルの開発に慣れていなかった +