Booting ARM Linuxを再読する

# Bootring ARM Linuxを再読する

ARM Linuxの起動プロセスってどうなっているのか、というのをもう一度認識を改めるためにも、今回は、Bootring ARM Linuxを再読していく。

（追記）もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる（認識）。

> https://www.kernel.org/doc/html/latest/index.html
> 
> Licensing documentation
> 
> The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
> 
> https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

では読んでいきます。

https://www.kernel.org/doc/html/latest/arm/booting.html#

> In order to boot ARM Linux, you require a boot loader, which is a small program that runs before the main kernel. The boot loader is expected to initialise various devices, and eventually call the Linux kernel, passing information to the kernel.

ARM Linuxを起動するにため、boot loaderが必要となる。boot loaderはmain kernelを起動する前に動作する小さいプログラムである。boot loaderは様々なデバイスの初期化をしたり、最終的にはLinux kernelを呼び出すために、Kernelに情報を伝達したりするだろう。

> Essentially, the boot loader should provide (as a minimum) the following:
1.Setup and initialise the RAM.
2.Initialise one serial port.
3.Detect the machine type.
4.Setup the kernel tagged list.
5.Load initramfs.
6.Call the kernel image.

本質的には、boot loderは下記を（ミニマム構成として）実行する。
1. RAMのセットアップと初期化
2. １つシリアルポートの初期化。
3. machine typeの特定
4. kernel tagged listのセットアップ
5. initramfsの呼び込み
6. kernel imageの呼び出し。

## 1. Setup and initialise RAM

>Existing boot loaders:
　MANDATORY （必須）
New boot loaders:
　MANDATORY　（必須）

> The boot loader is expected to find and initialise all RAM that the kernel will use for volatile data storage in the system. It performs this in a machine dependent manner. (It may use internal algorithms to automatically locate and size all RAM, or it may use knowledge of the RAM in the machine, or any other method the boot loader designer sees fit.)

boot loaderはkernelがシステムにおいて一時的なデータストレージとして用いるすべてのRAMを検出し初期化するだろう。これは、machineに依存したやり方となる。（おそらく、自動的にすべてのRAMの位置や容量、machineにおけるRAMに関する知識、あるいは、その他boot loaderの設計者のフィットする、内部アルゴリズムが使われるだろう）。

## 2. Initialise one serial port

>Existing boot loaders:
　OPTIONAL, RECOMMENDED（オプションであり、推奨される）
New boot loaders:
　OPTIONAL, RECOMMENDED（オプションであり、推奨される）

>The boot loader should initialise and enable one serial port on the target. This allows the kernel serial driver to automatically detect which serial port it should use for the kernel console (generally used for debugging purposes, or communication with the target.)

boot loaderは、target上の1つのシリアルポートを初期化し、有効にするべきである。これは、kernel serial driverが自動的にkernel consoleに利用されているシリアルポートを検知するのに用いられる（一般的には、デバッグ目的、あるいは、targetとの通信のために用いられる）。

>As an alternative, the boot loader can pass the relevant ‘console=’ option to the kernel via the tagged lists specifying the port, and serial format options as described in

別の手段としては、boot loaderはkernelに対して関連する"console=" optionをportに関するtagged listを介して通知してもよい。serial format optionの詳細は以下にある。

Documentation/admin-guide/kernel-parameters.rst.

## 3. Detect the machine type

>Existing boot loaders:
　OPTIONAL（オプション）
New boot loaders:
　MANDATORY except for DT-only platforms（DT-only platfromではおそらく必須）



> The boot loader should detect the machine type its running on by some method. Whether this is a hard coded value or some algorithm that looks at the connected hardware is beyond the scope of this document. The boot loader must ultimately be able to provide a MACH_TYPE_xxx value to the kernel. (see linux/arch/arm/tools/mach-types). This should be passed to the kernel in register r1.

boot loaderは、何らかの手段に基づいて動作しているmachine typeを検知するべきである。ハードコードされた値を用いる、あるいは、接続されたハードウェアを読みだして何らかのアルゴリズムを用いるなどになるが、このドキュメントのスコープ外となる。boot loaderは最終的にはkernelに対してMACH_TYPE_xxx値を通知することができなければならない（linux/arch/arm/tools/mach-typesを参照）。これは、register r1を介して、kernelに通知される。

> For DT-only platforms, the machine type will be determined by device tree. set the machine type to all ones (~0). This is not strictly necessary, but assures that it will not match any existing types.

DT-only plaftormでは、machine typeはdevice treeを判別するために用いられる。machine typeは全１にセットされる（~0)。これは厳密には必要のないことではあるが、既存のタイプと一致しないことを保証します。

## 4. Setup boot data
Existing boot loaders:
　OPTIONAL, HIGHLY RECOMMENDED（オプションだが、強く推奨）
New boot loaders:
　MANDATORY（必須）

>The boot loader must provide either a tagged list or a dtb image for passing configuration data to the kernel. The physical address of the boot data is passed to the kernel in register r2.

boot loaderはtagged listもしくはdtb imageのいずれかを、kernelに対する設定データとして提供しなければならない。boot dataの物理アドレスは、register r2を介してkernelに通知される。

### 4a. Setup the kernel tagged list

> The boot loader must create and initialise the kernel tagged list. A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE. The ATAG_CORE tag may or may not be empty. An empty ATAG_CORE tag has the size field set to ‘2’ (0x00000002). The ATAG_NONE must set the size field to zero.

boot loaderは、kernel tagged listを生成し初期化しなければならない。有効なtagged listは、ATAG_COREから介し、ATAG_NONEで終了する。ATAG_CORE tagは～であってもなくてもよい。空のATAG_CORE tagはsize fieldが'2'(0x00000002)としてセットされる。ATAG_NONEはsize filedが0でなければならない。

> Any number of tags can be placed in the list. It is undefined whether a repeated tag appends to the information carried by the previous tag, or whether it replaces the information in its entirety; some tags behave as the former, others the latter.

tagsのいくつかの数値はlistに保持することができる。タグが繰り返された場合、前のタグによって通視された情報に追加されるのか、それとも情報全体を置き換えるのかは定義されていない。前者として動作するタグもあれば、後者として動作するタグもある。

>The boot loader must pass at a minimum the size and location of the system memory, and root filesystem location. Therefore, the minimum tagged list should look:

boot loaderは、system memoryのサイズや位置の情報、root filesystemの位置の情報を最低でも伝えれねばならない。最小のtagged listは以下のようになる。

```
              +-----------+
base ->       | ATAG_CORE |  |
              +-----------+  |
              | ATAG_MEM  |  | increasing address
              +-----------+  |
              | ATAG_NONE |  |
              +-----------+  v
```

> The tagged list should be stored in system RAM.
tagged listはsystem RAMに保持される。

> The tagged list must be placed in a region of memory where neither the kernel decompressor nor initrd ‘bootp’ program will overwrite it. The recommended placement is in the first 16KiB of RAM.

tagged listは、kernel decompressorあるいはinitrdの"bootp" prgoramも上書きしないメモリ領域上に設置しなければならない。推奨される位置は、メモリの先頭16KiBである。

### 4b. Setup the device tree

> The boot loader must load a device tree image (dtb) into system ram at a 64bit aligned address and initialize it with the boot data. The dtb format is documented in Documentation/devicetree/booting-without-of.txt. The kernel will look for the dtb magic value of 0xd00dfeed at the dtb physical address to determine if a dtb has been passed instead of a tagged list.

boot loaderは、device tree image (dtb)を system RAM上の64bit alignment addressにロードし、boot dataを初期化しなければならない。drb formatについては、Documentation/devicetree/booting-without-of.txt に文書化されている。kernelは、drb 物理アドレスからdtb magic value 0xd00dfeedを見つける事で、tagged listの代わりにdtbを用いる。

>The boot loader must pass at a minimum the size and location of the system memory, and the root filesystem location. The dtb must be placed in a region of memory where the kernel decompressor will not overwrite it, while remaining within the region which will be covered by the kernel’s low-memory mapping.

boot loaderは、system memoryのサイズと位置、そして、root filesystem の位置といった最小限の情報を伝達する。dtbは、kernel decompressorで上書きされないメモリ領域上に置かれねばならない。そして、kernelのlow memory mappinguでカバーできる領域内にあるべきだ。


>A safe location is just above the 128MiB boundary from start of RAM.

RAMの先頭128Mibバウンダリまでの領域が安全な位置となる。

## 5. Load initramfs.

>Existing boot loaders:
　OPTIONAL（オプション）
New boot loaders:
　OPTIONAL（オプション）

>If an initramfs is in use then, as with the dtb, it must be placed in a region of memory where the kernel decompressor will not overwrite it while also with the region which will be covered by the kernel’s low-memory mapping.

initramfsをdtbと共に用いる場合には、kernel decompressorが上書きしないメモリ領域上に設置しなければならない。そして、kernelのlow memory mappinguでカバーできる領域内にあるべきだ。

>A safe location is just above the device tree blob which itself will be loaded just above the 128MiB boundary from the start of RAM as recommended above.

安全な場所は、device treeのすぐ上となる。device tree blobは上記で推奨されている通り、RAMの先頭から128MiB領域のすぐ上にLoadされる。


## 6. Calling the kernel image

Existing boot loaders:
　MANDATORY（必須）
New boot loaders:
　MANDATORY（必須）

>There are two options for calling the kernel zImage. If the zImage is stored in flash, and is linked correctly to be run from flash, then it is legal for the boot loader to call the zImage in flash directly.

kernel zImageを呼び出すには２つの方法があります。もし、zImageがFlashに保持され、それはflashから動作するように正しくlinkされているならば、boot loaderはflash内から直接zImageを呼び出すことができます。


>The zImage may also be placed in system RAM and called there. The kernel should be placed in the first 128MiB of RAM. It is recommended that it is loaded above 32MiB in order to avoid the need to relocate prior to decompression, which will make the boot process slightly faster.

zImageはあるいはsystem RAM上に配置され、そこから呼び出す事も出来ます。kernelはRAMの先頭128MiBに配置されるべきです。そして、展開後に再配置する必要が無いように、32MiBを越えた位置にロードすることを推奨します。これにより、boot processがわずかに早くなります。

>When booting a raw (non-zImage) kernel the constraints are tighter. In this case the kernel must be loaded at an offset into system equal to TEXT_OFFSET - PAGE_OFFSET.

ram(non-zImage) kernelを起動するときには、制約は更に厳しくなります。この場合、カーネルはTEXT_OFFSET - PAGE_OFFSETに等しいオフセットにシステムはカーネルをロードしなければなりません。

>In any case, the following conditions must be met:

いずれかのケースであっても、下記状態に合致させなければなりません。


>・Quiesce all DMA capable devices so that memory does not get corrupted by bogus network packets or disk data. This will save you many hours of debug.

全てのDMA capable deviceはnetwork packetやdisk dataを取得しないように停止させなければなりません。これは、デバッグのためのあなたの時間を大いに救うことになるでしょう、


>・CPU register settings
r0 = 0,
r1 = machine type number discovered in (3) above.
r2 = physical address of tagged list in system RAM, or physical address of device tree block (dtb) in system RAM
CPU mode

CPUレジスタ設定。
r0 = 0,
r1 = 前記3で述べた、machine type num。
r2 = system RAM内のtagged listの物理アドレス、あるいは、system RAM CPU modeでのdevice tree block(dtb)の物理アドレス。

> All forms of interrupts must be disabled (IRQs and FIQs)

全ての割り込み(IRQ/FIQ)は無効化されていること。

> For CPUs which do not include the ARM virtualization extensions, the CPU must be in SVC mode. (A special exception exists for Angel)

CPUが仮想化拡張を含んでいないのであれば、CPUはSVC modeであること（Angelには特別な例外があります）

> CPUs which include support for the virtualization extensions can be entered in HYP mode in order to enable the kernel to make full use of these extensions. This is the recommended boot method for such CPUs, unless the virtualisations are already in use by a pre-installed hypervisor.

CPUが仮想化拡張を含んでいる場合には、HYP modeに入ることで、これらの拡張をkernelがfullで利用できるようにすること。これは、仮想化があらかじめインストールされているハイパーバイザーによって既に利用されている場合を除いて、このようなCPUに推奨される起動方法です。

> If the kernel is not entered in HYP mode for any reason, it must be entered in SVC mode.

もしカーネルがHYP modeに何らかの理由で入らない場合には、SVC modeに入らなければならない。


>・Caches, MMUs
> The MMU must be off.
> Instruction cache may be on or off.
> Data cache must be off.

・Cache, MMU
MMUはOFFでなければならない。
命令キャッシュは、OnでもOffでもよい。
データキャッシュは、Offでなければならない。

> If the kernel is entered in HYP mode, the above requirements apply to the HYP mode configuration in addition to the ordinary PL1 (privileged kernel modes) configuration. In addition, all traps into the hypervisor must be disabled, and PL1 access must be granted for all peripherals and CPU resources for which this is architecturally possible. 

もし、カーネルがHYP modeで起動する場合には、上記要件は通常のPL1(特権カーネルモード）に加えて、HYP mode構成にも適用されます。更に、ハイパーバイザーへのすべてのtrapを無効化し、PL1はアーキテクチャが利用可能である、すべての周辺機器やCPU Resouceに対してアクセス可能である必要があります。

>Except for entering in HYP mode, the system configuration should be such that a kernel which does not include support for the virtualization extensions can boot correctly without extra help.

HYP modeに入る場合を除いて、システム構成は、仮想化拡張機能のサポートを含まないカーネルが特別な支援なしで正しく起動できるようにする必要があります。

>・The boot loader is expected to call the kernel image by jumping directly to the first instruction of the kernel image.

・boot loaderは、kernel imageの最初のインストラクションに直接ジャンプする事で、kernel imageを呼び出します。

>・On CPUs supporting the ARM instruction set, the entry must be made in ARM state, even for a Thumb-2 kernel.

ARM instruction setをサポートするCPUであれば、Thumb-2 kernelであっても、ARM stateでentryしてよいです。
>
> On CPUs supporting only the Thumb instruction set such as Cortex-M class CPUs, the entry must be made in Thumb state.

Thumb instruction setだけをサポートする、Cortex-M class のようなCPUであれば、Thumb  stateでentryしなければなりません。