コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2020年2月1日 >>> 2020年2月1日
link もっと後

2020年2月1日

Zephyrのエントリアドレス

目次: Zephyr

Zephyrをqemu_riscv32ボード向けにコンフィグし、ビルドディレクトリ下でninja runを実行すると、最終的に下記のコマンドが実行され、QMEUが起動します。

QEMUの起動コマンド
$ /usr/bin/qemu-system-riscv32 -nographic -machine sifive_e -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel zephyr/build/zephyr/zephyr.elf -s -S

GDBで追うとわかりますが、QEMUの実行開始アドレスは0x1000です。0x1000には0x20400000にジャンプするコードだけが置かれています。

0x1000にあるコード

   0x1000:      lui     t0,0x20400
=> 0x1004:      jr      t0
   0x1008:      unimp
   0x100a:      unimp

HiFive1実機であれば0x20400000はQSPI Flashがマッピングされているアドレスです(SiFive FE310-G000 Manual v2p3を参照)。QEMUの場合はELFファイルbuild/zephyr/zephyr.elfのセクション情報通りに配置されます。

0x1000にあるコード
$ riscv64-zephyr-elf-readelf -a build/zephyr/zephyr.elf  | less

...

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] vector            PROGBITS        20400000 000094 000010 00  AX  0   0  4
  [ 2] exceptions        PROGBITS        20400010 0000a4 000258 00  AX  0   0  4
  [ 3] text              PROGBITS        20400268 0002fc 002ad4 00  AX  0   0  4
  [ 4] sw_isr_table      PROGBITS        20402d3c 002dd0 000200 00  WA  0   0  4
  [ 5] devconfig         PROGBITS        20402f3c 002fd0 000060 00   A  0   0  4
  [ 6] rodata            PROGBITS        20402f9c 003030 000215 00   A  0   0  4
  [ 7] datas             PROGBITS        80000000 003248 000018 00  WA  0   0  4
  [ 8] initlevel         PROGBITS        80000018 003260 000060 00  WA  0   0  4
  [ 9] _k_mutex_area     PROGBITS        80000078 0032c0 000014 00  WA  0   0  4
  [10] bss               NOBITS          80000090 0032e0 00013c 00  WA  0   0  8
  [11] noinit            NOBITS          800001d0 0032e0 000e00 00  WA  0   0 16

...

ジャンプ先の0x20400000にはvectorというセクションが対応していることがわかります。ELFファイルを逆アセンブルしてみると、

0x20400000にあるコード

zephyr/zephyr.elf:     file format elf32-littleriscv


Disassembly of section vector:

20400000 <__start>:

        /*
         * Set mtvec (Machine Trap-Vector Base-Address Register)
         * to __irq_wrapper.
         */
        la t0, __irq_wrapper
20400000:       00000297                auipc   t0,0x0
20400004:       01028293                addi    t0,t0,16 # 20400010 <__irq_wrapper>
        csrw mtvec, t0
20400008:       30529073                csrw    mtvec,t0

        /* Jump to __initialize */
        tail __initialize
2040000c:       4b40106f                j       204014c0 <__initialize>

以上のように __startという関数が居るようです。実装はzephyr/soc/riscv/riscv-privilege/common/vector.Sにあります。

Zephyrとデバイスツリー

このエントリポイントアドレスはどのように決まるのでしょう?Zephyrでは、ボード用のデバイスツリーzephyr/boards/riscv/qemu_riscv32/qemu_riscv32.dtsにあるFlashの先頭アドレスを変えるとELFのエントリポイント(0x20400000)も追従します。

ボード用のデバイスツリーのchosenノード

        chosen {
                zephyr,console = &uart0;
                zephyr,shell-uart = &uart0;
                zephyr,sram = &dtim;
                zephyr,flash = &flash0;
        };

このchosen以下を検知しているようです。スクリプトscripts/dts/gen_defines.pyを見ると、SPIのときだけ特殊処理になっていて、それ以外はregの値を先頭アドレスとみなしています。

Flashのサイズを見ている箇所

# zephyr/scripts/dts/gen_defines.py

...

def write_flash_node(edt):
    # Writes output for the top-level flash node pointed at by
    # zephyr,flash in /chosen

    node = edt.chosen_node("zephyr,flash")

    out_comment(f"/chosen/zephyr,flash ({node.path if node else 'missing'})")

    if not node:
        # No flash node. Write dummy values.
        out("FLASH_BASE_ADDRESS", 0)
        out("FLASH_SIZE", 0)
        return

    if len(node.regs) != 1:
        err("expected zephyr,flash to have a single register, has "
            f"{len(node.regs)}")

    if node.on_bus == "spi" and len(node.bus_node.regs) == 2:
        reg = node.bus_node.regs[1]  # QSPI flash
    else:
        reg = node.regs[0]

    out("FLASH_BASE_ADDRESS", hex(reg.addr))
    if reg.size:
        out("FLASH_SIZE", reg.size//1024)

...

FlashのアドレスはDT_FLASH_BASE_ADDRESSというマクロで参照できます。エントリーポイントを最終的に決めるのはリンカースクリプトです。SoCで独自のリンカースクリプトを実装することもできるようになっていますが、RISC-Vの多くのSoCは、下記のスクリプトを使っています。

エントリーポイントを決めている箇所

// zephyr/include/arch/riscv/common/linker.ld

MEMORY
{
#ifdef CONFIG_XIP
    ROM (rx)  : ORIGIN = DT_FLASH_BASE_ADDRESS, LENGTH = KB(DT_FLASH_SIZE)
#endif
    RAM (rwx) : ORIGIN = CONFIG_SRAM_BASE_ADDRESS, LENGTH = KB(CONFIG_SRAM_SIZE)
    /* Used by and documented in include/linker/intlist.ld */
    IDT_LIST  (wx)      : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
}

Zephyrのエントリポイントがどうやって決まるのか、少しわかった気がします。

編集者:すずき(2023/09/24 12:02)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2020年2月1日 >>> 2020年2月1日
link もっと後

管理用メニュー

link 記事を新規作成

<2020>
<<<02>>>
------1
2345678
9101112131415
16171819202122
23242526272829

最近のコメント5件

  • link 20年6月19日
    すずきさん (04/06 22:54)
    「ディレクトリを予め作成しておけば良いです...」
  • link 20年6月19日
    斎藤さん (04/06 16:25)
    「「Preferencesというメニューか...」
  • link 21年3月13日
    すずきさん (03/05 15:13)
    「あー、このプログラムがまずいんですね。ご...」
  • link 21年3月13日
    emkさん (03/05 12:44)
    「キャストでvolatileを外してアクセ...」
  • link 24年1月24日
    すずきさん (02/19 18:37)
    「簡単にできる方法はPowerShellの...」

最近の記事20件

  • link 24年4月17日
    すずき (04/18 22:44)
    「[VSCodeとMarkdownとPlantUMLのローカルサーバー] 目次: LinuxVSCodeのPlantUML Ex...」
  • link 23年4月10日
    すずき (04/18 22:30)
    「[Linux - まとめリンク] 目次: Linuxカーネル、ドライバ関連。Linuxのstruct pageって何?Linu...」
  • link 20年2月22日
    すずき (04/17 02:22)
    「[Zephyr - まとめリンク] 目次: Zephyr導入、ブート周りHello! Zephyr OS!!Hello! Ze...」
  • link 24年4月16日
    すずき (04/17 02:05)
    「[Zephyr SDKのhosttoolsは移動してはいけない、その2 - インストール時のバイナリ書き換え] 目次: Zep...」
  • link 24年4月15日
    すずき (04/17 01:47)
    「[Zephyr SDKのhosttoolsは移動してはいけない、その1 - 移動させると動かなくなる] 目次: ZephyrZ...」
  • link 24年4月11日
    すずき (04/17 00:37)
    「[VScodeとAsciiDocとKrokiローカルサーバー] 目次: LinuxAsciiDoc ExtensionはAsc...」
  • link 24年4月12日
    すずき (04/16 00:12)
    「[台湾東部沖地震に寄付] ささやかではありますが台湾東部沖地震に寄付しました。日本の赤十字社→台湾の赤十字(正式名称...」
  • link 22年9月3日
    すずき (04/16 00:08)
    「[MarkDownのその向こう] 目次: Linux簡単なドキュメントやメモはMarkDownで書くことが多いですが、気合を入...」
  • link 22年9月4日
    すずき (04/16 00:08)
    「[Asciidocをさらに活用] 目次: Linux前回(2022年9月3日の日記参照)、Asciidocのプレビュー環境の設...」
  • link 24年3月19日
    すずき (04/16 00:07)
    「[モジュラージャックの規格] 目次: Arduino古くは電話線で、今だとEthernetで良く見かけるモジュラージャックとい...」
  • link 23年6月2日
    すずき (04/16 00:07)
    「[Arduino - まとめリンク] 目次: Arduino一覧が欲しくなったので作りました。 M5Stackとesp32とA...」
  • link 24年4月9日
    すずき (04/12 12:44)
    「[初めて作ったボード動作せず(手で直した)] 目次: Arduino以前(2024年3月24日の日記参照)発注して、全く動ない...」
  • link 24年4月2日
    すずき (04/12 11:00)
    「[KiCadが動かなくなったのでビルド] 目次: ArduinoDebian Testingなマシンをapt-get upgr...」
  • link 24年4月3日
    すずき (04/12 11:00)
    「[初めて作ったボード動作せず(燃えた)] 目次: Arduino以前(2024年3月24日の日記参照)発注したPCBが届いたの...」
  • link 24年3月24日
    すずき (04/12 11:00)
    「[PCBを設計して注文] 目次: Arduinoシューティングの練習でいつもお世話になっているTARGET-1秋葉原店に、6つ...」
  • link 24年3月25日
    すずき (03/26 03:20)
    「[Might and Magic Book One TASのその後] 目次: Might and Magicファミコン版以前(...」
  • link 21年10月4日
    すずき (03/26 03:14)
    「[Might and Magicファミコン版 - まとめリンク] 目次: Might and Magicファミコン版TASに挑...」
  • link 24年3月18日
    すずき (03/19 11:47)
    「[画面のブランクを無効にする] 目次: LinuxROCK 3 model CのDebian bullseyeイメージは10分...」
  • link 24年3月3日
    すずき (03/19 11:07)
    「[解像度の設定を保存する] 目次: LinuxRaspberry Pi 3 Model B (以降RasPi 3B)のHDMI...」
  • link 24年3月14日
    すずき (03/16 23:03)
    「[JavaとM5Stamp C3とBluetooth LE - Bluetoothデバイスとの通信] 目次: ArduinoM...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 04/18 22:44