Zephyrのビルドプロセスを追え!

はじめに

色々こねこねするために、Zephyrのビルドプロセスを解析します。 最小構成のZephyrがどのようにビルドされるか、を見ていきます。

ビルドログ

|> zephyr/samples/hello_world

おなじみのHello WorldプログラムをQEMU Cortex-M3で動かす場合を対象とします。

ヘッダファイル生成

まず、ターゲット用のヘッダファイルを生成します。 このあたりは、pythonが動いているはずです(要確認)。

[  1%] Generating include/generated/kobj-types-enum.h, include/generated/otype-to-str.h
[  1%] Built target kobj_types_h_target
[  2%] Generating include/generated/syscall_macros.h
[  2%] Built target syscall_macros_h_target
[  3%] Preparing syscall dependency handling

[  4%] Generating misc/generated/syscalls_subdirs.trigger
[  5%] Generating misc/generated/syscalls.json
[  6%] Generating include/generated/syscall_dispatch.c, include/generated/syscall_list.h
[  6%] Built target syscall_list_h_target
[  7%] Generating include/generated/driver-validation.h
[  7%] Built target driver_validation_h_target

オフセットなので、ベクタテーブル周りの設定でしょうか?

Scanning dependencies of target offsets
[  8%] Building C object zephyr/CMakeFiles/offsets.dir/arch/arm/core/offsets/offsets.c.obj
[  9%] Linking C static library liboffsets.a
[  9%] Built target offsets
[ 10%] Generating include/generated/offsets.h
[ 10%] Built target offsets_h

生成されたヘッダファイルを確認してみます。

|> include/generated/offsets.h

/* THIS FILE IS AUTO GENERATED.  PLEASE DO NOT EDIT.
 *
 * This header file provides macros for the offsets of various structure
 * members.  These offset macros are primarily intended to be used in
 * assembly code.
 */

#ifndef __GEN_OFFSETS_H__
#define __GEN_OFFSETS_H__

#define ___kernel_t_current_OFFSET 0x8
#define ___kernel_t_nested_OFFSET 0x0
#define ___kernel_t_irq_stack_OFFSET 0x4
#define ___cpu_t_current_OFFSET 0x8
#define ___cpu_t_nested_OFFSET 0x0
#define ___cpu_t_irq_stack_OFFSET 0x4
#define ___kernel_t_ready_q_OFFSET 0x20
...

うーん、いまいち何者かわかりにくいです。

アプリケーションビルド

ユーザーアプリケーションがビルドされます。main.cしかないため、これだけです。

Scanning dependencies of target app
[ 10%] Building C object CMakeFiles/app.dir/src/main.c.obj
[ 11%] Linking C static library libapp.a
[ 11%] Built target app

kernelビルド

Zephyr kernelをビルドします。libkernel.aというライブラリが生成されます。

Scanning dependencies of target kernel
[ 12%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/alert.c.obj
[ 13%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/device.c.obj
[ 14%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/errno.c.obj
[ 15%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/idle.c.obj
[ 16%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/init.c.obj
[ 17%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mailbox.c.obj
[ 18%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mem_slab.c.obj
[ 20%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mempool.c.obj
[ 21%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/msg_q.c.obj
[ 22%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mutex.c.obj
[ 23%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/pipes.c.obj
[ 23%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/queue.c.obj
[ 24%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/sched.c.obj
[ 25%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/sem.c.obj
[ 26%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/stack.c.obj
[ 27%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/system_work_q.c.obj
[ 28%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/thread.c.obj
[ 29%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/thread_abort.c.obj
[ 30%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/version.c.obj
[ 31%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/work_q.c.obj
[ 32%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/smp.c.obj
[ 33%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/timeout.c.obj
[ 34%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/timer.c.obj
[ 35%] Linking C static library libkernel.a
[ 35%] Built target kernel

スケジューラや、プロセス間通信、スレッド、スタックあたりのアーキテクチャに依存しないコードがビルドされているようです。

リンカスクリプト生成

ここで、リンカスクリプトを生成しています。

Scanning dependencies of target linker_script
[ 36%] Generating linker.cmd
[ 36%] Built target linker_script

ターゲットZephyrビルド

KconfigやターゲットSoCまでのソースコードをビルドしているようです。

Scanning dependencies of target zephyr
[ 37%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/common/isr_tables.c.obj
[ 37%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/common/sw_isr_common.c.obj
[ 38%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/thread_entry.c.obj
[ 40%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/work_q.c.obj
[ 41%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/fdtable.c.obj
[ 42%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/crc/crc32_sw.c.obj
[ 43%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/crc/crc16_sw.c.obj
[ 44%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/crc/crc8_sw.c.obj
[ 45%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/mempool/mempool.c.obj
[ 46%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/rbtree/rb.c.obj
[ 47%] Building C object zephyr/CMakeFiles/zephyr.dir/misc/printk.c.obj
[ 48%] Building C object zephyr/CMakeFiles/zephyr.dir/misc/generated/configs.c.obj
[ 49%] Building C object zephyr/CMakeFiles/zephyr.dir/soc/arm/ti_lm3s6965/soc.c.obj
[ 50%] Building C object zephyr/CMakeFiles/zephyr.dir/soc/arm/ti_lm3s6965/soc_config.c.obj
[ 51%] Building ASM object zephyr/CMakeFiles/zephyr.dir/soc/arm/ti_lm3s6965/reboot.S.obj
[ 52%] Building C object zephyr/CMakeFiles/zephyr.dir/soc/arm/ti_lm3s6965/sys_arch_reboot.c.obj
[ 53%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/console/uart_console.c.obj
[ 54%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/timer/sys_clock_init.c.obj
[ 55%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/timer/cortex_m_systick.c.obj
[ 56%] Linking C static library libzephyr.a
[ 56%] Built target zephyr

ターゲットアーキテクチャ (ARM) 用ソースコードのビルド

ARM固有のアセンブリなどをビルドしています。

Scanning dependencies of target arch__arm__core
[ 57%] Building ASM object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/exc_exit.S.obj
[ 58%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/irq_init.c.obj
[ 60%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/swap.c.obj
[ 61%] Building ASM object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/swap_helper.S.obj
[ 62%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/fault.c.obj
[ 63%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/irq_manage.c.obj
[ 64%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/thread.c.obj
[ 65%] Building ASM object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/cpu_idle.S.obj
[ 66%] Building ASM object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/fault_s.S.obj
[ 67%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/fatal.c.obj
[ 68%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/sys_fatal_error_handler.c.obj
[ 69%] Building C object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/thread_abort.c.obj
[ 70%] Building ASM object zephyr/arch/arm/core/CMakeFiles/arch__arm__core.dir/isr_wrapper.S.obj
[ 71%] Linking C static library libarch__arm__core.a
[ 71%] Built target arch__arm__core

Cortex-M用ソースコードのビルド

Cortex-M用のベクタテーブルやリセット周りのソースコードをビルドしています。

Scanning dependencies of target arch__arm__core__cortex_m
[ 72%] Building ASM object zephyr/arch/arm/core/cortex_m/CMakeFiles/arch__arm__core__cortex_m.dir/vector_table.S.obj
[ 73%] Building ASM object zephyr/arch/arm/core/cortex_m/CMakeFiles/arch__arm__core__cortex_m.dir/reset.S.obj
[ 74%] Building ASM object zephyr/arch/arm/core/cortex_m/CMakeFiles/arch__arm__core__cortex_m.dir/nmi_on_reset.S.obj
[ 75%] Building C object zephyr/arch/arm/core/cortex_m/CMakeFiles/arch__arm__core__cortex_m.dir/prep_c.c.obj
[ 76%] Building C object zephyr/arch/arm/core/cortex_m/CMakeFiles/arch__arm__core__cortex_m.dir/scb.c.obj
[ 76%] Building C object zephyr/arch/arm/core/cortex_m/CMakeFiles/arch__arm__core__cortex_m.dir/nmi.c.obj
[ 77%] Building C object zephyr/arch/arm/core/cortex_m/CMakeFiles/arch__arm__core__cortex_m.dir/exc_manage.c.obj
[ 78%] Linking C static library libarch__arm__core__cortex_m.a
[ 78%] Built target arch__arm__core__cortex_m

minimal libcのビルド

今回の設定では、Zephyrが提供しているminimalのlibcを使用しています。 minimalのlibcをビルドします。

Scanning dependencies of target lib__libc__minimal
[ 80%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdlib/atoi.c.obj
[ 81%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdlib/strtol.c.obj
[ 82%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdlib/strtoul.c.obj
[ 82%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdlib/malloc.c.obj
[ 83%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/string/strncasecmp.c.obj
[ 84%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/string/strstr.c.obj
[ 85%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/string/string.c.obj
[ 86%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdout/prf.c.obj
[ 87%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdout/stdout_console.c.obj
[ 88%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdout/sprintf.c.obj
[ 89%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdout/fprintf.c.obj
[ 90%] Linking C static library liblib__libc__minimal.a
[ 90%] Built target lib__libc__minimal

driverのビルド

利用するdriverをビルドします。 今回は、UARTのみが対象です。

Scanning dependencies of target drivers__serial
[ 91%] Building C object zephyr/drivers/serial/CMakeFiles/drivers__serial.dir/uart_stellaris.c.obj
[ 92%] Linking C static library libdrivers__serial.a
[ 92%] Built target drivers__serial

prebuilt elf

このprebuilt elfを作るプロセスが何をしているのか、は良く分かっていません。追って調査します。

[ 93%] Building C object zephyr/CMakeFiles/zephyr_prebuilt.dir/misc/empty_file.c.obj
[ 94%] Linking C executable zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:        7608 B       256 KB      2.90%
            SRAM:        4020 B        64 KB      6.13%
        IDT_LIST:           8 B         2 KB      0.39%
[ 94%] Built target zephyr_prebuilt

仕上げ

最終的なリンカスクリプトを生成し、最終的なelfファイルをビルドします。

Scanning dependencies of target linker_pass_final_script
[ 95%] Generating linker_pass_final.cmd
[ 95%] Built target linker_pass_final_script
[ 96%] Generating isr_tables.c
Scanning dependencies of target kernel_elf
[ 97%] Building C object zephyr/CMakeFiles/kernel_elf.dir/misc/empty_file.c.obj
[ 98%] Building C object zephyr/CMakeFiles/kernel_elf.dir/isr_tables.c.obj
[100%] Linking C executable zephyr.elf
Generating files from zephyr.elf for board: qemu_cortex_m3
[100%] Built target kernel_elf

まとめ

アプリケーション、kernel、Zephyr、ARM、Cortex-M、ライブラリ、driver、それぞれのstatic libraryを作成して、最終的にリンクする、というプロセスでした。