この記事で関係するターゲット
staticIdt.o ターゲット
[zephyr_base]/Makefile
staticIdt.o: $(TMP_ELF) $(call cmd,gen_idt)
$(TMP_ELF)
$(TMP_ELF)は、.tmp_zephyr.prebuilt。[zephyr_base]/Makefile
TMP_ELF = .tmp_$(KERNEL_NAME).prebuilt
$(call cmd,gen_idt)
cmd_get_idt ファンクションを実行。cmd_gen_idt ファンクション
[zephyr_base]/Makefile
cmd_gen_idt = \ ( \ $(OBJCOPY) -I $(OUTPUT_FORMAT) -O binary -j intList $< isrList.bin && ・・・①\ $(GENIDT) -i isrList.bin -n $(CONFIG_IDT_NUM_VECTORS) -o staticIdt.bin \ -b int_vector_alloc.bin -m irq_int_vector_map.bin \ -l $(CONFIG_MAX_IRQ_LINES) && ・・・②\ $(OBJCOPY) -I binary -B $(OUTPUT_ARCH) -O $(OUTPUT_FORMAT) \ --rename-section .data=staticIdt staticIdt.bin staticIdt.o && ・・・③\ $(OBJCOPY) -I binary -B $(OUTPUT_ARCH) -O $(OUTPUT_FORMAT) \ --rename-section .data=int_vector_alloc int_vector_alloc.bin \ int_vector_alloc.o && ・・・④\ $(OBJCOPY) -I binary -B $(OUTPUT_ARCH) -O $(OUTPUT_FORMAT) \ --rename-section .data=irq_int_vector_map irq_int_vector_map.bin \ irq_int_vector_map.o && ・・・⑤\ rm staticIdt.bin irq_int_vector_map.bin int_vector_alloc.bin isrList.bin・・・⑥\ )
① $(OBJCOPY) -I $(OUTPUT_FORMAT) -O binary -j intList $< isrList.bin
/Volumes/CrossToolNG/x-tools/i586-pc-elf/bin/i586-pc-elf-objcopy -I elf32-i386 -O binary -j intList .tmp_zephyr.prebuilt isrList.bin
objcopy --help
i586-pc-elf-objcopy [option(s)] in-file [out-file] -I --input-target <bfdname> Assume input file is in format <bfdname> -O --output-target <bfdname> Create an output file in format <bfdname> -j --only-section <name> Only copy section <name> into the output
入力: .tmp_zephyr.prebuilt
出力: isrList.bin
.tmp_zephyr.prebuilt (i386 ELF32ファイル形式)の intList セクションを isrList.bin(バイナリファイル形式)へコピーする。
② $(GENIDT) -i isrList.bin -n $(CONFIG_IDT_NUM_VECTORS) -o staticIdt.bin -b int_vector_alloc.bin -m irq_int_vector_map.bin -l $(CONFIG_MAX_IRQ_LINES)
./scripts/gen_idt/gen_idt -i isrList.bin -n 256 -o staticIdt.bin -b int_vector_alloc.bin -m irq_int_vector_map.bin -l 128
./scripts/gen_idt/gen_idt
[zephyr_base]/scripts/gen_idt/gen_idt.c をコンパイルして生成する。[zephyr_base]/scripts/gen_idt/gen_idt.c
(省略) /** * @file * @brief Generate static IDT and a bitmap of allocated interrupt vectors. * Creates a static IA-32 Interrupt Descriptor Table (IDT). * * This program expects to be invoked as follows: * gen_idt -i <input file> -o <IDT output file> -n <# of interrupt vectors> * -b <allocated vectors bitmap file> * All parameters are required. * * The <input file> is assumed to be a binary file containing the intList * section from the Zephyr Kernel ELF image. * * <number of interrupt vectors> is the same as CONFIG_IDT_NUM_VECTORS. * * It is expected that this program is invoked from within the build system * during the link stage. */ (省略)
$ ./outdir/scripts/gen_idt/gen_idt -h gen_idt -i <input file> -n <n> options -b <allocated interrupt vector bitmap output file> [Mandatory] The interrupt vector bitmap output file. -i <binary file> [Mandatory] The input file in binary format. -o <IDT output file> [Mandatory] The IDT output file. -m <IRQ to interrupt vector map file> [Mandatory] The IRQ to interrupt vector output file -n <n> [Mandatory] Number of vectors -l <n> [Mandatory] Number of IRQ lines -v Display version. -h Display this help. Returns -1 on error, 0 on success
入力: isrList.bin
出力: staticIdt.bin、int_vector_alloc.bin、irq_int_vector_map.bin
isrList.bin をもとに、割り込みディスクリプタテーブルファイル staticIdt.bin、割り込みベクタ割当ビットマップファイル int_vector_alloc.bin、IRQ-割り込みベクタマップファイル irq_int_vector_map.bin を作成する。
割り込みベクタ数は256。IRQ割り込み線数は128。
staticIdt.bin だけでは、デフォルトのハンドラを使ったのか、指定したハンドラを使ったのか区別がつかないから、 int_vector_alloc.binが必要?
staticIdt.bin だけでは、割り込みベクタがIRQで発生したものなのか、例外・ソフトウェア割り込みで発生したものなのか区別がつかないから、irq_int_vector_map.binが必要?
isrList.bin
登録したい割り込み、例外(?)の情報。isrList.binは、下記の genidt_header と supplied_entry[] から構成される。
[zephyr_base]/scripts/gen_idt/gen_idt.c
struct genidt_header_s { void *spurious_addr; // staticIdt.binの生成時に使用。isrList.binで指定しない割り込み用の割り込みハンドラのアドレス。 // 割り込みベクタ番号8,10,11,12,13,14,17で使用。エラー番号をスタックにプッシュする。 // _EXC_ERROR_CODE_FAULTS @ [zephyr_base]/arch/x86/include/idtEnt.h 参照 void *spurious_no_error_addr; // 同上。上記以外の割り込みベクタ番号で使用。エラー内容をスタックにプッシュしない。 unsigned int num_entries; // supplied_entry の数 }; struct genidt_entry_s { void *isr; // 割り込みハンドラのアドレス unsigned int irq; // UNSPECIFIED_IRQ でない時、IRQ番号 unsigned int priority; // 割り込み優先度。この値をもとにマップする割り込みベクタ番号を決定する。 // 0<= priority <= 13。irqがIRQ番号の時(=vector_idが UNSPECIFIED_INT_VECTOR の時)に使用。 unsigned int vector_id; // UNSPECIFIED_INT_VECTOR でない時、割り込みベクタ番号 unsigned int dpl; // Descriptor Privilege Level (プログラム中では0と仮定している。validate_dpl()参照) }; static struct genidt_header_s genidt_header; static struct genidt_entry_s supplied_entry[MAX_NUM_VECTORS];
staticIdt.bin
generate_idt()@[zephyr_base]/scripts/gen_idt/gen_idt.c
unsigned long long idt_entry の配列(割り込みベクタ番号順) // _IdtEntCreate() @ arch/x86/include/idtEnt.h で生成するidt_entryの詳細は、Interrupt Descriptor Table - OSDev Wiki の IDT entry を参照。
isrList.bin内のsupplied_entry[].isr、supplied_entry[].dpl をもとに idt_entry を生成する。
int_vector_alloc.bin
generate_interrupt_vector_bitmap()@[zephyr_base]/scripts/gen_idt/gen_idt.c
unsigned int interrupt_vector_bitmap[num_elements]; // num_elemsents = 8; (割り込みベクタ数+31)/32 // 各ビットが、割り込みハンドラ(?)が割り当てられたかどうかを示す。ビット値が0の時、割り当てられたとする。 // interrupt_vector_bitmap[0]の0ビット目が0の場合、割り込み番号0が割り当てらたことを意味する。 // この配列を int_vector_alloc.bin に書き込む
irq_int_vector_map.bin
外部割り込み(IRQ:Interrupt ReQuest)を割り込みベクタに割り当てた(マップした)結果のファイル。マップの方法:
割り込みベクタ番号は、supplied_entry[].vector_id をもとに、IRQより先に割り当てる。
priority 0 の IRQ は、割り込みベクタ番号 0〜15 の中で未割当の番号に割り当てる。
priority 1 の IRQ は、割り込みベクタ番号 16〜32 の中で未割当の番号に割り当てる。
...
priority 13 の IRQ は、割り込みベクタ番号 224〜239 の中で未割当の番号に割り当てる。
未割当の番号がない場合、エラーとなり、gen_idt は終了する。
generate_interrupt_vector_bitmap()@[zephyr_base]/scripts/gen_idt/gen_idt.c
uint8_t map_irq_to_vector_id[MAX_IRQS] // map_irq_to_vector_id[IRQ番号] = 割り込みベクタ番号 // この配列を irq_int_vector_map.bin に書き込む
$(GENIDT)
[zephyr_base]/Makefile
GENIDT = scripts/gen_idt/gen_idt
$(CONFIG_IDT_NUM_VECTORS)
[zephyr_base]/samples/hello_world/microkernel/outdir/.config
CONFIG_IDT_NUM_VECTORS=256
$(CONFIG_MAX_IRQ_LINES)
[zephyr_base]/samples/hello_world/microkernel/outdir/.config
CONFIG_MAX_IRQ_LINES=128
③ $(OBJCOPY) -I binary -B $(OUTPUT_ARCH) -O $(OUTPUT_FORMAT) --rename-section .data=staticIdt staticIdt.bin staticIdt.o
/Volumes/CrossToolNG/x-tools/i586-pc-elf/bin/i586-pc-elf-objcopy -I binary -B i386 -O elf32-i386 --rename-section .data=staticIdt staticIdt.bin staticIdt.o入力: staticIdt.bin
出力: staticIdt.o
staticIdt.bin(バイナリファイル)の.dataセクション(データ全体?)をstaticIdtにリネームしてstaticIdt.o(elf32-i386形式)に出力する。
$(KERNEL_ELF_NAME) ターゲットで使用し、zephyr.elf へリンクする。
objcopy --help
i586-pc-elf-objcopy [option(s)] in-file [out-file] -I --input-target <bfdname> Assume input file is in format <bfdname> -B --binary-architecture <arch> Set output arch, when input is arch-less -O --output-target <bfdname> Create an output file in format <bfdname> --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>
④ $(OBJCOPY) -I binary -B $(OUTPUT_ARCH) -O $(OUTPUT_FORMAT) --rename-section .data=int_vector_alloc int_vector_alloc.bin int_vector_alloc.o
/Volumes/CrossToolNG/x-tools/i586-pc-elf/bin/i586-pc-elf-objcopy -I binary -B i386 -O elf32-i386 --rename-section .data=int_vector_alloc int_vector_alloc.bin int_vector_alloc.o入力: int_vector_alloc.bin
出力: int_vector_alloc.o
int_vector_alloc.bin(バイナリファイル)の.dataセクション(データ全体?)をint_vector_allocにリネームしてint_vector_alloc.o(elf32-i386形式)に出力する。
$(KERNEL_ELF_NAME) ターゲットで使用し、zephyr.elf へリンクする。
objcopy --helpは上記を参照。
⑤ $(OBJCOPY) -I binary -B $(OUTPUT_ARCH) -O $(OUTPUT_FORMAT) --rename-section .data=irq_int_vector_map irq_int_vector_map.bin irq_int_vector_map.o
/Volumes/CrossToolNG/x-tools/i586-pc-elf/bin/i586-pc-elf-objcopy -I binary -B i386 -O elf32-i386 --rename-section .data=irq_int_vector_map irq_int_vector_map.bin irq_int_vector_map.o入力: irq_int_vector_map.bin
出力: irq_int_vector_map.o
irq_int_vector_map.bin(バイナリファイル)の.dataセクション(データ全体?)をirq_int_vector_mapにリネームしてirq_int_vector_map.o(elf32-i386形式)に出力する。
$(KERNEL_ELF_NAME) ターゲットで使用し、zephyr.elf へリンクする。
objcopy --helpは上記を参照。
⑥ rm staticIdt.bin irq_int_vector_map.bin int_vector_alloc.bin isrList.bin
rm staticIdt.bin irq_int_vector_map.bin int_vector_alloc.bin isrList.bin不要になったstaticIdt.bin、irq_int_vector_map.bin、int_vector_alloc.bin isrList.binを削除する。
コメント