web-dev-qa-db-ja.com

ARMの起動プロセスとは何ですか?

ご存じのとおり、X86アーキテクチャの場合:電源ボタンを押すと、マシンは0xFFFFFFF0でコードの実行を開始し、ハードウェアの初期化を行うためにBIOSでコードの実行を開始します。 BIOSの実行後、ブートローダーを使用してOSイメージをメモリにロードします。最後に、OSコードの実行が開始されます。 ARMアーキテクチャの場合、使用後の電源ボタンを押した後の起動プロセスは何ですか?ありがとう!

51
Fengwei Zhang

現在、ARMアーキテクチャには2つの例外モデルがあります(リセットは一種の例外と見なされます):

以前のCortexチップと現在のCortex-A/Rチップで使用されるクラシックモデル。その中で、0のメモリにはいくつかの例外ハンドラが含まれています。

 Offset  Handler
 ===============
 00      Reset 
 04      Undefined Instruction
 08      Supervisor Call (SVC)
 0C      Prefetch Abort
 10      Data Abort
 14      (Reserved)
 18      Interrupt (IRQ)
 1C      Fast Interrupt (FIQ)

例外が発生すると、プロセッサは特定のオフセットから実行を開始するだけなので、通常、このテーブルにはコード内の完全なハンドラーへの単一命令の分岐が含まれます。典型的な古典的なベクターテーブルは次のようになります。

00000000   LDR   PC, =Reset
00000004   LDR   PC, =Undef
00000008   LDR   PC, =SVC
0000000C   LDR   PC, =PrefAbort
00000010   LDR   PC, =DataAbort
00000014   NOP
00000018   LDR   PC, =IRQ
0000001C   LDR   PC, =FIQ

実行時には、ベクトルテーブルを0xFFFF0000に再配置できます。これは、最速の例外処理のために密結合メモリ範囲として実装されることがよくあります。ただし、パワーオンリセットは通常0x00000000から始まります(ただし、一部のチップでは、プロセッサピンによって0xFFFF0000に設定できます)。

新しいマイクロコントローラーモデルは、Cortex-Mのチップラインで使用されています。そこでは、0のベクターテーブルは、実際には命令ではなくベクター(ポインター)のテーブルです。最初のエントリには、SPレジスタの起動値が含まれ、2番目はリセットベクトルです。これにより、プロセッサがスタックをセットアップするため、Cにリセットハンドラを直接書き込むことができます。 Cortex-Mの典型的なベクターテーブルは、次のように始まります。

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                [...more vectors...]

OMAP3やAppleのA4などの最新の複雑なチップでは、通常実行される最初のコードはユーザーコードではなく、オンチップブートROMであることに注意してください。さまざまな条件をチェックして、ユーザーコードをどこから読み込むか、まったく読み込むかどうかを判断します(たとえば、有効なデジタル署名が必要な場合があります)。このような場合、ユーザーコードは異なる起動規則に従う必要があります。

61
Igor Skochinsky

...最後に、OSコードの実行が開始されます。 ARMアーキテクチャの場合、使用後の電源ボタンを押した後の起動プロセスはどうなりますか?

この答えは主にコンテキストまたは最新のCortex-A CPUにあります。さまざまなARMプラットフォームがあります。ただし、PC(タブレット、携帯電話など)のようなARMの場合...

ARM CPUは、0x0または0xffff0000から命令をフェッチします(Cortex-Mの場合、命令ではなくデータです)。典型的なARM SOCには、このメカニズムを使用するブートROMがあります。エンドユーザーの場合は、マニュアルを参照して、コードを実行する方法を決定する必要があります。つまり、[〜#〜] bios [〜#〜]があり、ベクターを使用する多くのARM SOCに組み込まれています、ただし、コードを実行するには別のものを使用する必要があります。

通常、ARM SOCは複数のブートデバイスをサポートします。デバイスは、いくつかのヒューズ(製造ツールによって設定)またはサンプリングピンによって決定されます。ピンは実行中のシステムのCPU出力ですが、ブートデバイスを構成するためにプルアップ/ダウンされています。各ブートデバイスには固有の詳細があります。 ROMは単純ですが、NANDフラッシュ、SPIフラッシュ、MMCなどには構成の詳細が必要です。これらは、多くの場合、オンチップのヒューズやサンプリングピンによって提供されます。デバイスをさらに構成するために、デバイスのごく一部を読み取ることができます。

深く埋め込まれたARMチップの場合、オンボードフラッシュからのみ起動でき、このプロセスははるかに簡単です。しかし、私はあなたがより高度なARM CPUに言及している質問の文脈から信じています。より高度なARMシステムにはブートローダーがあります。これは、ROMローダーがロードするコードの量が制限または制限されていることが多いためです。また、SDRAMのセットアップは複雑であることが多く、ブートローダーは、SDRAMを構成する内部スタティックRAMから実行するように構成されている場合があります。

参照: ブートローダーが必要な理由

OSの実行には固有の問題があります。 ARM Linuxの場合、ATAGSでしたが、現在はデバイスツリーです。人々はそこに独自のブートローダーをコーディングするか、多くのオープンソースプロジェクトの1つを使用し、u-bootが最も一般的です。 U-bootsは、vxWorks、Linux、NetBSD、Plan9、OSE、QNX、Integrity、OpenRTOS、およびバイナリイメージをサポートしています。

オリジナルのARM Linuxデバイスの多くは、ブートローダーなしのLinuxのダイレクトブートをサポートしていました。ただし、Linuxは、いくつかの非常に古いARM SOC /コアを除き、メインラインでこれをサポートしていません。

3
artless noise

電源がオンになった後、CPUは例外モードの実行を開始します。最初のリセットはリセットされます。CPUはこの実行時にレジスタの状態を知らないため、リセットはスーパーバイザーモードとして実行する必要があります。小さなコードを書く必要があります(最後を参照)。この他の例外は、PCにアドレスをロードすることで処理できます。

.globl _start
 _start: b       reset
    ldr     pc, _undefined_instruction
    ldr     pc, _software_interrupt
    ldr     pc, _prefetch_abort
    ldr     pc, _data_abort
    ldr     pc, _not_used
    ldr     pc, _irq
    ldr     pc, _fiq

reset:
    mrs     r0,cpsr                 /* set the cpu to SVC32 mode        */
    bic     r0,r0,#0x1f             /* (superviser mode, M=10011)       */
    orr     r0,r0,#0x13
    msr     cpsr,r0
3
user1813332