「φ(・・*)ゞ ウーン jailhouseのコードを読んでみるの2」の続きでinit_early()を。
init_early()の呼び出し元はhypervisor/setup.cのentry()。
最初に行われるのはGlobal Offset Tableの初期化。
static void init_early(unsigned int cpu_id) { unsigned long size; master_cpu_id = cpu_id; /* must be first, printk/arch_dbg_write uses the GOT */ got_init();
gotの初期化はhypervisor/arch/x86/entry.Sにてアセンブラで書かれています。
/* Fix up Global Offset Table with absolute hypervisor address */ .globl got_init got_init: lea __got_start(%rip),%rdx lea __got_end(%rip),%rcx lea hypervisor_header(%rip),%rax got_loop: cmp %rdx,%rcx je got_done add %rax,(%rdx) add $8,%rdx jmp got_loop got_done: ret
処理の内容自体は単純ですね。
dbgはdebugの略かなと何となく予想ができるところ。
arch_dbg_write_init();
x86の場合はhypervisor/arch/x86/dbg-write.cに関数があります。ここで使われているUART_XXXXというマクロ名、outb()であーやっぱりなと思ってみたりする訳です。
void arch_dbg_write_init(void) { outb(UART_LCR_DLAB, UART_BASE + UART_LCR); #ifdef CONFIG_UART_OXPCIE952 outb(0x22, UART_BASE + UART_DLL); #else outb(1, UART_BASE + UART_DLL); #endif outb(0, UART_BASE + UART_DLM); outb(UART_LCR_8N1, UART_BASE + UART_LCR); }
( ´∀`)bグッ!
printk("\nInitializing Jailhouse hypervisor on CPU %d\n", cpu_id); printk("Code location: %p\n", __start + sizeof(struct jailhouse_header));
ここは名前の通りだろうから後で読む。paging_init()はhypervisor/paging.cに。
error = paging_init(); if (error) return;
ページを確保してハイパーバイザ用にページテーブルを作成。細かいところは後で読む。page_map_create()はhypervisor/paging.cに。
if (system_config->config_memory.size > 0) { size = PAGE_ALIGN(system_config->config_memory.size); config_memory = page_alloc(&remap_pool, size / PAGE_SIZE); if (!config_memory) { error = -ENOMEM; return; } error = page_map_create(hv_page_table, system_config->config_memory.phys_start, size, (unsigned long)config_memory, PAGE_READONLY_FLAGS, PAGE_DEFAULT_FLAGS, PAGE_DIR_LEVELS); if (error) return; }
メモリアドレスの範囲とかアクセス属性などのチェック(hypervisor/control.c)
error = check_mem_regions(&system_config->system); if (error) return;
アーキテクチャ固有の初期化。これも後で読む。 hypervisor/arch/x86/setup.cで実施。
error = arch_init_early(&linux_cell, &system_config->system); if (error) return;
cellの初期化。後で読む。hypervisor/control.c
error = cell_init(&linux_cell, &system_config->system, false); if (error) return; cell_list = &linux_cell;
初期化の第一段階が終了!
page_map_dump_stats("after early setup"); printk("Initializing first processor:\n"); }
ここまでで「後で読む」としたのは以下の4個。
- hypervisor/paging.cpaging_init()
- hypervisor/paging.cpage_map_create()
- hypervisor/arch/x86/setup.carch_init_early()
- hypervisor/control.ccell_init()
init_early()が行っている内容は