---
# System prepended metadata

title: 第1章 PCの仕組みとハローワールド

---

# 第1章 PCの仕組みとハローワールド

## 村松の学習記録
- `＄ mkfs.fat -n 'MIKAN OS' -s 2 -f 2 -R 32 -F 32 disk.img`
  - `mkfs`
    - ファイルシステムを構築するコマンド
  - `mkfs.fat`
    - FAT 対応なファイルシステムを構築するコマンド
    - [FAT 【File Allocation Table】 FATファイルシステム](https://e-words.jp/w/FAT.html)
  - `-s (クラスタ毎のセクタ数)`, `-R （予約セクタ数）`
    - セクタ
      - ディスク上のデータ単位、ディスクでの最小単位
    - クラスタ
      - ディスク上のデータ単位、セクタをまとめて束ねる
  - `-f (FAT テーブル数)`, `-F (FAT テーブルのタイプ)`
    - FAT(ファイルアロケーションテーブル)
      - ディスク内のファイルの位置情報などを記録するための領域
  - 参考
    -  https://zenn.dev/miwarin/articles/ecf2b11ad1628b
    -  https://atmarkit.itmedia.co.jp/ait/articles/1803/09/news034.html
    - https://en.wikipedia.org/wiki/Data_cluster
    - https://ja.wikipedia.org/wiki/File_Allocation_Table
- おすすめの進め方
  - 分からなくても進み、手を動かす
  - `git` を使って写経する
- コンピュータに USB を指したときに起こること
  - CPU が直接 USB の中身を実行するわけではない
  - 電源を入れると BIOS (Basic Input Output System) が実行
  - BIOS は実行ファイルを見つけたら、それをメインメモリに読み込む
  - CPU は BIOS の実行を中止し、メインメモリに読み込まれた実行ファイルを実行する
- リンカーとは
  - コンパイルなどでできた複数のオブジェクトファイルをつなぎ合わせて、１つの実行ファイルにまとめる
  - 参考
    - [コンパイラが作ったバイナリをつなぎ合わせるプログラム
「lld」の作者が語る、リンカの仕組み](https://logmi.jp/tech/articles/325775)


## 祖父江の学習結果

1.  [第1章の予習](#orgc089081)
    1.  [**1.1 ハローワールド**](#orgbbdb8ed)
        1.  [バイナリファイルが誤りないかのチェックは， **チェックサム** を使う](#org5d540a3)
        2.  [dmesg【コマンド】とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](#org3e5531b)
        3.  [WSLとは 「Windows SubSystem for Linux」](#org4b00dbc)
        4.  [ファイルシステム (FS)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](#org9cf34c6)
        5.  [CPUはデジタル回路 電圧の高低 **H/L ➔１/０**](#org5b7d493)
        6.  [本来の２進数では 先頭の”0”は記載しない．しかしデジタル回路の世界では扱える桁すうを明示するために，001など先頭の0を意図的に書くことがある．](#org4d00f51)
        7.  [「100」が２進数なのか，10進数どっちの100なのかわからない問題](#org912472b)
        8.  [8bit = 1byte](#org23ebff3)
        9.  [デジタル回路は1 or 0の2数だけで実現できるのが単純でメリットだが，デメリットは桁数が大きくなること](#org38bcd18)
        10. [現在主流の64Bit CPUとは 1回の計算に64桁の2進数を扱えるということ](#org8c6912b)
        11. [コンピュータで扱う数値は大きく2つある <code>[0/2]</code><code>[0%]</code>](#org5cd5e64)
        12. [**文字コード** 文字と数値（バイト列）の対応付け規則のこと](#org3a4857e)
        13. [【 umount 】コマンド――ファイルシステムのマウントを解除する：Linux基本コマンドTips（184） - ＠IT](#org10b7a5e)
        14. [BIOS [Basic Input Output System]:CPがAC/ONしてから最初に実行されるファームウェアプログラム](#orgcaa2fa0)
        15. [コンピュータを電源入れてからの処理のフロー <code>[0/7]</code><code>[0%]</code>](#org87c292f)
        16. [「UEFIアプリケーション」：今回作成したBOOTX64.EFI](#orgf97af38)
        17. [1.9 C言語でハローワールド](#orge842581)
        18. [Column 1.1](#org14da341)
    2.  [対面講義 <span class="timestamp-wrapper"><span class="timestamp">[2022-08-24 Wed 18:22] </span></span> 担当：松村](#org3a8663e)
        1.  [「lld-link」： PE形式の実行ファイルを作るためのリンカ．とはなんぞや？なんのために？やるの？](#org04c2145)


<a id="orgc089081"></a>

# Note 第1章の予習

<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 1:</span> Clock summary at <span class="timestamp-wrapper"><span class="timestamp">[2022-07-31 Sun 18:18]</span></span></caption>

<colgroup>
<col  class="org-left" />

<col  class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Headline</th>
<th scope="col" class="org-left">Time</th>
</tr>
</thead>

<tbody>
<tr>
<td class="org-left"><b>Total time</b></td>
<td class="org-left"><b>3:39</b></td>
</tr>
</tbody>
</table>


<a id="orgbbdb8ed"></a>

## **1.1 ハローワールド**


<a id="org5d540a3"></a>

### バイナリファイルが誤りないかのチェックは， **チェックサム** を使う

1.  $ sum BOOTX64.EFI

    2430     2
    
    1.  sizeが出力されるので，それで差異の確認．しかし，コード上のどこに誤りがあるかまではわからない． **コードを目視確認するしかない**


<a id="org3e5531b"></a>

### [dmesg【コマンド】とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word13787.html)


<a id="org4b00dbc"></a>

### WSLとは 「Windows SubSystem for Linux」


<a id="org9cf34c6"></a>

### [ファイルシステム (FS)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word13127.html)

1.  Linuxでは全てをファイルとして扱う

2.  WindowsではそうではなくFSの種類が

    1.  FAT ←以前使われていたFS
    
    2.  NTFS ←2022年では主流のFS


<a id="org5b7d493"></a>

### CPUはデジタル回路 電圧の高低 **H/L ➔１/０**


<a id="org4d00f51"></a>

### 本来の２進数では 先頭の”0”は記載しない．しかしデジタル回路の世界では扱える桁すうを明示するために，001など先頭の0を意図的に書くことがある．

1.  001 は3桁まで扱える回路だな！とわかる


<a id="org912472b"></a>

### 「100」が２進数なのか，10進数どっちの100なのかわからない問題

1.  解決方法：C++では2進数の「100」の場合： **0b100** と記載し区別させている


<a id="org23ebff3"></a>

### 8bit = 1byte


<a id="org38bcd18"></a>

### デジタル回路は1 or 0の2数だけで実現できるのが単純でメリットだが，デメリットは桁数が大きくなること

1.  デメリット解消策： **16進数** を使う

    1.  ０〜９ とA~Fの16種類
    
    2.  ２進数と好相性
    
        1.  ２進数の4桁 = 16進数の1桁
    
    3.  「0x」は16進数の明示


<a id="org8c6912b"></a>

### 現在主流の64Bit CPUとは 1回の計算に64桁の2進数を扱えるということ


<a id="org5cd5e64"></a>

### コンピュータで扱う数値は大きく2つある <code>[0/2]</code><code>[0%]</code>

OOTX64.EFIには下記どちらも含まれている
. [ ] CPUが実行するための命令「機械語命令」

-   文字列を画面表示する命令などが該当する

. [ ] それ以外

-   画面に表示する文字列「Hello,world!」
-   メタデータ 
    -   データ本体を説明するための付加情報のこと <code>[0/3]</code><code>[0%]</code>
        1.  [ ] ファイルフォーマット
        2.  [ ] 大きさ
        3.  [ ] どんなCPU向けの機械語が入ってるかなど


<a id="org3a4857e"></a>

### **文字コード** 文字と数値（バイト列）の対応付け規則のこと

1.  ASCII

2.  Unicode

3.  Shift-JIS

4.  多バイトの数値をどのように並べるかの方法

    1.  リトルエンディアン
    
    2.  ビッグエンディアン


<a id="org10b7a5e"></a>

### [【 umount 】コマンド――ファイルシステムのマウントを解除する：Linux基本コマンドTips（184） - ＠IT](https://atmarkit.itmedia.co.jp/ait/articles/1802/16/news025.html)


<a id="orgcaa2fa0"></a>

### BIOS [Basic Input Output System]:CPがAC/ONしてから最初に実行されるファームウェアプログラム

1.  BIOSの処理内容

    1.  OS起動前にCP内部の初期化をする
    
    2.  OS（ブートローダー）をストレージから読み出す

2.  大抵のBIOSの設定画面の表示方法は

    1.  AC/ON時に，「Deleteキー」を押しっぱなし
    
    2.  AC/ON時に，「F2キー」を押しっぱなし

3.  BIOSの種類は2種

    1.  レガシーBIOS
    
        昔のBIOS
    
    2.  UEFI BIOS
    
        UEFIという標準仕様に従って作られた BIOS
        現在の主流


<a id="org87c292f"></a>

### コンピュータを電源入れてからの処理のフロー <code>[0/7]</code><code>[0%]</code>

1.  [ ] AC/ON（電源ON）
2.  [ ] CPUはBIOSを実行開始する
    -   もともとBIOSは不揮発メモリROMに書き込まれている（電源OFFしてもBIOSは消えない，だからCPUは実行できる）
        -   メインメモリは揮発性メモリRAMなので，電源切るとクリアされる
        -   しかもCPUは，メインメモリ(RAM)に置いてあるプログラムしか実行できない．
3.  [ ] BIOS(に格納された機械語プログラム)はコンピュータを初期化する
    1.  パソコン本体，周辺機器を初期化する．
        -   CPUの動作モードを設定する
        -   PCIデバイスを検出し，設定する
4.  [ ] BIOS(に格納された機械語プログラム)は接続されているストレージを探索する
    -   HDD,SSD,USBメモリ，DVDなどを検索する
5.  [ ] BIOSはストレージの中に実行可能ファイルを見つける
    1.  [ ] そのファイルをメインメモリへ読み出す
6.  [ ] CPUはBIOSの実行を中断する
7.  [ ] CPUは読み出されたファイルを実行を開始する


<a id="orgf97af38"></a>

### 「UEFIアプリケーション」：今回作成したBOOTX64.EFI

1.  UEFIアプリケーションではUEFI BIOSの機能を使える．

    1.  例
    
        1.  画面に文字列を表示する
        
        2.  キーボードからの文字入力する
        
        3.  ストレージからファイルを読み込む


<a id="orge842581"></a>

### 1.9 C言語でハローワールド

1.  OSを作る道具

    1.  バイナリエディタは2進数で表せるものなら何でも作れる万能ツール
    
        1.  ただバイナリエディタでは決して「作りやすい」わけではない．
        
            ➔それぞれのファイルを作るための専用の道具を使った方がBetter．
            
            1.  例えば
            
                1.  バイナリエディタ： **まっさらな紙**
                    ➔プレーンすぎる
                2.  テキストエディタ： **原稿用紙** **五線譜**
                    ➔用途にあったツール
    
    2.  本書ではOSをプログラミング言語で開発する．（CとC++）
        
        1.  人間がテキストエディタで編集する．ソースコードを作成と編集する
            ➔ **.c** **.cpp** ファイルを作る
        2.  ソースコードをコンパイルする
            ➔ **.c** **.cpp** ファイルを ➔ **.o** (オブジェクトファイルに)
        3.  リンクの作成
            ➔ **.o** ➔ **.elf**
    
    3.  コンパイラ：ソースコード➔オブジェクトファイルを生成するプログラム（コンパイル）
    
    4.  オブジェクトファイル：CPUが直接実行できる機械語命令や，それが利用するデータを含んだファイル
    
        1.  1つのソースコードは1つのオブジェクトファイルになる
    
    5.  最後にリンクという作業：すべてのオブジェクトファイルをまとめて実行可能にすること

2.  「Calg」と「LLD」を使ってコンパイルとリンクする

    1.  「calg」: **Linuxようのコンパイラ**
    
            $ clang -target x86_64_-pc-win32-coff -mno-red-zone -fno-stack-protector -fshort-wchar -Wall -c hello.c
        
        通常はELF開式でファイルを出力する．が
        「-target x86<sub>64</sub><sub>-pc</sub>-win32-coff」を指定することで，Windows用COFF形式で出力することができる
        次の「lld-link」がCOFF形式を要求するので必要
        ➔コンパイルが完了するとhello.o（COFF形式）のファイルが生成されている．
    
    2.  「lld-link」： PE形式の実行ファイルを作るためのリンカ．
    
            $ lld-link /subsystem:efi_application /entry:EfiMain /out:hello.efi hello.o
        
        hello.oをリンクして，hello.efiを得ようとしている．
        
        1.  なんでこんなことすんの？Windows用のPEファイルを生成することにある．
        
            ありがたいことに，「/subsystem:efi<sub>application</sub>」オプション指定でえUEFI用のPEファイルを生成してくれる．
            ➔このオプションは，Windows用のPEファイルとUEFI用のPEファイルで若干異なる部分を考慮してファイルを生成してくれる．
            
            1.  helllo.efiファイルが作成され，これがC言語版のハローワールドアプリ．
            
            2.  helllo.efiファイルをUSBの/EFI/BOOT/BOOTX64.EFIで上書きコピーし，PCを起動させると「Hello,world!」が画面表示される


<a id="org14da341"></a>

### Column 1.1

1.  「バイナリエディタ」「コンパイラ」「リンカ」はアプリ

    1.  これらのアプリは
    
        1.  「実行可能ファイル
        2.  「設定ファイル」
            を組み合わせて構成されている．
    
    2.  「実行可能ファイル」： **パソコンに指示をするためのプログラム** と \*プログラムが動作するのに必要なデータ\*を含む
    
        1.  CPUは機械語だけを実行できる．そして実行可能ファイルにはいくつかの種類がある
        
            1.  1:スクリプト
            
                ➔典型的にはプログラミング言語で書かれるインタプリタと呼ばれるアプリがスクリプトの中身を読み取って実行する．
                
                -   例えば，シェルスクリプト
                    
                        #!/bin/bash
                        echo "hello, world"
                    
                    1.  「#!/bin/bash」は/bin/bashで指定されたインタプリタ（ここではBash）がこのスクリプトファイルを読み取って実行することを示している．
                        ➔この行は「シェバン：shebang」と呼ばれる
                    2.  2行目以降はBashが解釈できる形式でプログラムを書く．
                    3.  このスクリプトを実行するよう命令されたOS（シェル）はBashを起動し，2行目以降の内容をBashへ入力する．
            
            2.  2:機械語プログラムを中心とするもの
            
                ➔スクリプトとことなり，こちらはCPUが直接実行できる機械語をファイルの中に含んでいる．
                
                -   このファイルを実行するように命令されたOSは，その機械語をCPUが直接実行するように諸々の設定を行います．

2.  「PE形式」，「ELF形式」とOSの関係

    <table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
    
    
    <colgroup>
    <col  class="org-left" />
    
    <col  class="org-left" />
    
    <col  class="org-left" />
    
    <col  class="org-left" />
    </colgroup>
    <thead>
    <tr>
    <th scope="col" class="org-left">OS</th>
    <th scope="col" class="org-left">アプリの形式</th>
    <th scope="col" class="org-left">アプリの拡張子</th>
    <th scope="col" class="org-left">備考</th>
    </tr>
    </thead>
    
    <tbody>
    <tr>
    <td class="org-left">Windows</td>
    <td class="org-left">PE形式</td>
    <td class="org-left">.exe</td>
    <td class="org-left">&#xa0;</td>
    </tr>
    
    
    <tr>
    <td class="org-left">Linux</td>
    <td class="org-left">ELF形式</td>
    <td class="org-left">.elf</td>
    <td class="org-left">&#xa0;</td>
    </tr>
    
    
    <tr>
    <td class="org-left">&#xa0;</td>
    <td class="org-left">&#xa0;</td>
    <td class="org-left">&#xa0;</td>
    <td class="org-left">&#xa0;</td>
    </tr>
    </tbody>
    </table>

3.  COFF形式はオブジェクトファイル形式の一種．

    ➔PE形式のファイルを作る過程の中間ファイル形式としてCOFF形式をつくことが多い
    ➔hello.c ➔hello.o ➔hello.elf
    
    1.  COFF形式のオブジェクトフィルをリンク
    2.  PE形式の実行ファイルをつくる

4.  実はELF形式はオブジェクトファイル形式としても使える

    1.  PE/COFF形式は以下に分かれている
    
        1.  実行可能ファイル
        
        2.  オブジェクト
    
    2.  ELF形式はどちらも表現できる（ELF形式は「実行可能ファイル」「オブジェクトファイル」別れていない）
    
        ➔ELF ＝ ”Executable and Linkable Format”（実行可能かつリンク可能フォーマット）の略

5.  「PE」「COFF」「ELF」はいずれも機械語を格納するファイル形式である．共通点．

    ➔Word，PDF，HTMLの関係と似ている．グラフィカルに文書を扱う点は一緒だが，ファイル内部での表現方法が異なる．
    ➔メタデータの付け方やデータの配置方法などが異なる点．

6.  実行可能ファイル形式は歴史的に色々存在するが，現在は「PE」と「ELF」がほとんど

    ➔昔は a.out，COM形式，HRBなど


<a id="org3a8663e"></a>

## 対面講義 <span class="timestamp-wrapper"><span class="timestamp">[2022-08-24 Wed 18:22] </span></span> 担当：松村


<a id="org04c2145"></a>

### DONE 「lld-link」： PE形式の実行ファイルを作るためのリンカ．とはなんぞや？なんのために？やるの？

➔コンパイル後のオブジェクトファイル(バイナリ,複数)を,つなぎ合わせ実行可能形式ファイルを生成するために行う.

