コグノスケ


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

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

2020年2月16日

Zephyrのブート処理 - C言語と出会うまで

目次: Zephyr

以前(2020年2月1日の日記参照)Zephyrのエントリアドレスを調べましたが、もう少し先までZephyrのブート処理を調べます。復習となりますが、起動の仕方は下記のとおりです。

QEMU SpikeモードでZephyrを起動
$ qemu-system-riscv32 -nographic -machine spike -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel zephyr/build/zephyr/zephyr.elf -s -S

$ riscv64-zephyr-elf-gdb zephyr/build/zephyr/zephyr.elf

...

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00001000 in ?? ()

ブート処理を追うにはデバッガが必須です(ブート部分でシリアル出力はできません)。これも前回の復習となりますが、QEMUはGDBでデバッグするためのオプションを持っています。オプション -sはGDBの接続をlocalhost:1234で受け付けます、という意味で、オプション -SはエミュレータをHalted状態で起動するという意味です。

GDBを接続すると、PCは0x1000を指しています。QEMU Spikeモードはリセット後0x1000から実行を開始するようです。何度かステップ実行siを行うと、0x1010から0x80000000にジャンプするはずです。

QEMUブート直後

   0x1000:      auipc   t0,0x0
   0x1004:      addi    a1,t0,32
   0x1008:      csrr    a0,mhartid
   0x100c:      lw      t0,24(t0)
=> 0x1010:      jr      t0        # 0x80000000にジャンプ

0x1000: 0x00000297      0x02028593      0xf1402573      0x0182a283
0x1010: 0x00028067      0x00000000      0x80000000      0x00000000
                                        ↑この値をロードする

特に難しい話ではなく0x1000 + 24 = 0x1018からロード(0x80000000が書かれている)して、ジャンプするだけです。ジャンプ先にはZephyrのエントリポイント __startがいます。

__start(0x80000000ジャンプ後)

// zephyr/soc/riscv/riscv-privilege/common/vector.S

SECTION_FUNC(vectors, __start)
        .option norvc;

        /*
         * Set mtvec (Machine Trap-Vector Base-Address Register)
         * to __irq_wrapper.
         */
        la t0, __irq_wrapper
        csrw mtvec, t0

        /* Jump to __initialize */
        tail __initialize


// zephyr/arch/riscv/core/isr.S

/*
 * Handler called upon each exception/interrupt/fault
 * In this architecture, system call (ECALL) is used to perform context
 * switching or IRQ offloading (when enabled).
 */
SECTION_FUNC(exception.entry, __irq_wrapper)
        /* Allocate space on thread stack to save registers */
        addi sp, sp, -__z_arch_esf_t_SIZEOF

        /*
         * Save caller-saved registers on current thread stack.
         * NOTE: need to be updated to account for floating-point registers
         * floating-point registers should be accounted for when corresponding
         * config variable is set
         */
        RV_OP_STOREREG ra, __z_arch_esf_t_ra_OFFSET(sp)
        RV_OP_STOREREG gp, __z_arch_esf_t_gp_OFFSET(sp)
        RV_OP_STOREREG tp, __z_arch_esf_t_tp_OFFSET(sp)
        RV_OP_STOREREG t0, __z_arch_esf_t_t0_OFFSET(sp)
        ...

__startは __irq_wrapper関数のアドレス(C言語の関数ではないので、関数と呼ぶのは変ですが)を割り込みベクタに設定したあと、__initializeにジャンプします。

__initialize

// zephyr/arch/riscv/core/reset.S

/*
 * Remainder of asm-land initialization code before we can jump into
 * the C domain
 */
SECTION_FUNC(TEXT, __initialize)
        /*
         * This will boot master core, just halt other cores.
         * Note: need to be updated for complete SMP support
         */
        csrr a0, mhartid
        beqz a0, boot_master_core

loop_slave_core:
        wfi
        j loop_slave_core

boot_master_core:

#ifdef CONFIG_INIT_STACKS
        ...
#endif

        /*
         * Initially, setup stack pointer to
         * _interrupt_stack + CONFIG_ISR_STACK_SIZE
         */
        la sp, _interrupt_stack
        li t0, CONFIG_ISR_STACK_SIZE
        add sp, sp, t0

#ifdef CONFIG_WDOG_INIT
        call _WdogInit
#endif

        /*
         * Jump into C domain. _PrepC zeroes BSS, copies rw data into RAM,
         * and then enters kernel z_cstart
         */
        call _PrepC

最初にmhartidというCPUコアのIDを読み取ります。0番をマスターコアとして、0番以外のコアは割り込み待ち(wfi)の無限ループに入ります。マスターコアはスタックポインタの初期化を行って、_PrepC() 関数を呼び出します。

ここからやっとC言語の世界です。

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

コメント一覧

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



link もっと前
2020年2月16日 >>> 2020年2月16日
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の...」

最近の記事3件

  • 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 もっとみる

こんてんつ

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