-
Notifications
You must be signed in to change notification settings - Fork 101
jp arch mem map
Susumu Mashimo edited this page Sep 8, 2020
·
12 revisions
- メモリ・マップに関する情報は基本的に Memory/MemoryMapTypes.sv にて定義されている
- アドレスのマッピングの他に,PC の初期値や IO のアドレスなども含む
- 32ビットの論理アドレスから,物理アドレスへの変換が行われる
- 各キャッシュや LSQ ではこの物理アドレスに基づいて処理が行われる
- 論理から物理アドレスへのマッピングは,現在は固定ルールで行われる
- アドレス変換時に論理アドレスの範囲がチェックされ,無効な場合は例外が発生する
- 物理メモリの実際の容量は Src/BasicType.sv の MEMORY_ADDR_BIT_SIZE によって決められる.現在のRSDの物理アドレス幅は21-bitである.
物理アドレスは,下記のように最上位ビットがisUncachableとisIOのpacked structで定義される.
typedef struct packed {
logic isUncachable // True if address is uncachable
logic isIO; // True if address is IO
PhyRawAddrPath addr;
} PhyAddrPath;
論理アドレス | 物理アドレス | 内容 |
---|---|---|
0x0000_1000 ~ 0x0000_FFFF | 0x00_1000 ~ 0x00_FFFF | ROM |
0x8000_0000 ~ 0x8003_FFFF | 0x01_0000 ~ 0x04_FFFF | RAM (Cachable) |
0x8004_0000 ~ 0x8004_FFFF | 0x25_0000 ~ 0x25_FFFF | RAM (Uncachable) |
0x4000_0000 ~ 0x4000_0007 | 0x10_0000 ~ 0x10_0007 | Timer |
0x4000_2000 ~ 0x4000_2003 | 0x10_2000 ~ 0x10_2003 | UART |
-
Verification/TestCode/rsd-crt.s
- スタートアップルーチン
- main 関数に入る前にこれが実行される
- スタックの初期値はここでレジスタに代入している
- ローダ(Verification/TestCode/rsd-loader.c )がここで呼ばれ,ROM にあるデータを RAM に展開する
- テキスト領域はコピーしない.ROM上で実行する
- 現在は Zephyr を動かす際も
CONFIG_XIP
(Execute In Place)オプションをつけてコードは ROM 上に置いたままにしている
- 現在は Zephyr を動かす際も
-
Verification/TestCode/rsd-ld.script
- リンカースクリプト
- リンク時のコードやデータのアドレス配置が定義されている
-
セクションとアドレスの関係
- 0x0000_1000 - 0x0001_7fff: text(コード)
- 0x8000_0000 - 0x8000_7fff: data, bss(静的データ)
- 0x8001_8000 - 0x8002_0000: stack
スタートアップルーチン
stack_top = 0x80020000
...
li x29,0
li x30,0
li x31,0
li sp,0x80020000
リンカースクリプト
OUTPUT_FORMAT("elf32-littleriscv");
OUTPUT_ARCH("riscv")
/* エントリポイント._start は rsd-crt.s で定義 */
ENTRY(_start);
MEMORY {
ROM(rxai) : ORIGIN = 0x00001000, LENGTH = 32k
RAM(wa) : ORIGIN = 0x80000000, LENGTH = 32k
}
SECTIONS
{
.text : { *(.text) } > ROM
.rodata : { *(.rodata) } > ROM
__rodata_end = .;
.data : {
__data_start = .;
*(.data)
*(.sdata)
__data_end = .;
} > RAM AT> ROM
. = ALIGN(4);
.bss : {
__bss_start = .;
*(.bss)
*(.sbss)
__bss_end = . ;
} > RAM AT> ROM
.comment : { *(.comment) } > ROM
}
- symbol = .; しておくと,そのアドレスに,変数が置かれるので,C言語の方でextern int symbol; とやって &symbol を見ればそのアドレスが分かる
- "> RAM" はプログラム実行中に参照する時はRAMにあるように見える,という意味
- "AT > ROM" はELFを展開するローダはROM領域に置くようにしろということ(rsd-loaderはさらに実行時にROM領域内の静的データをRAM領域に展開する別のローダ)
- このローダが変数を置くアドレス(LMA; Load Memory Address)は objdump でも確認できるが,readelfだと Virtual Address として表示される
- ややこしいことに,readelf でいう Physical Address が objdump のいう Virtual Memory Address (VMA) になる