ご存じのとおり、X86アーキテクチャの場合:電源ボタンを押すと、マシンは0xFFFFFFF0でコードの実行を開始し、ハードウェアの初期化を行うためにBIOSでコードの実行を開始します。 BIOSの実行後、ブートローダーを使用してOSイメージをメモリにロードします。最後に、OSコードの実行が開始されます。 ARMアーキテクチャの場合、使用後の電源ボタンを押した後の起動プロセスは何ですか?ありがとう!
現在、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であることに注意してください。さまざまな条件をチェックして、ユーザーコードをどこから読み込むか、まったく読み込むかどうかを判断します(たとえば、有効なデジタル署名が必要な場合があります)。このような場合、ユーザーコードは異なる起動規則に従う必要があります。
...最後に、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 /コアを除き、メインラインでこれをサポートしていません。
電源がオンになった後、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