概要
カーネル処理のstart_kernel()の処理を途中まで見てみた。
前回
今回 start_kernel()からrest_init()の途中まで
start_kernelは様々なモジュールを初期化して、内容は盛り沢山。なので今回も自分が気になる箇所だけを切り取りしてみる。
処理概要
- start_kernel()
- カーネル環境の初期化
- sched_init() ランキューの初期化
- fork_init() タスク数の上限の設定
- signal_init() シグナルキューの作成
↓
- setup_arch()
- 機種依存な初期化処理
- initプロセス用のメモリ構造体に初期値を設定
- ページテーブルの作成
↓
- mm_init()
- page構造体とメモリアロケータの初期化
↓
- rest_init()
- kernel_thread(kernel_init,...)
- kernel_thread(kerneladd,...)
- schdule()
- cpu_idle()
start_kernel()
前回の続きから。とりあえず、start_kernelに入った直後にレジスタをみてみた。
(gdb) i r
スタックポインタを見てみると現在、実行している処理はinit_thread_unionところのスタックを利用している。これは前回みたスタックを静的に定義していた箇所のこと。やはりinit(プロセス番号1)というより現在の処理(swapper)が利用するスタックということでよいはず。
setup_arch()
start_kernel() → setup_arch()
initプロセス用のメモリ構造体に初期値を設定している
init_mm.start_code = (unsigned long) _text;
init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata;
init_mm.brk = _brk_end;
メモ:
_textなどはリンカースクリプト(下記載)に記載されている。
SECTIONS
84 {
85 #ifdef CONFIG_X86_32
86 . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
87 phys_startup_32 = startup_32 - LOAD_OFFSET;
88 #else
89 . = __START_KERNEL;
90 phys_startup_64 = startup_64 - LOAD_OFFSET;
91 #endif
92
93 /* Text and read-only data */
94 .text : AT(ADDR(.text) - LOAD_OFFSET) {
95 _text = .;
96 /* bootstrapping code */
97 HEAD_TEXT
98 #ifdef CONFIG_X86_32
99 . = ALIGN(PAGE_SIZE);
100 *(.text.page_aligned)
101 #endif
102 . = ALIGN(8);
103 _stext = .;
メモ:
これがカーネルのリンカースクリプト。カーネルの実行ファイル(vmlinuz)を作成するときにこのリンカースクリプトをみてリンクするオブジェクトファイルの各セクションをまとめたり、そのセクションが仮想メモリ上でどのアドレスに配置されるのかが記載されている。利用するのはオブジェクトファイルをリンクする時。
GDBで変数中身と/proc/iomemと/boot/System.mapを見比べてみた
setup_arch()の中の_textなどがどこのカーネルの仮想アドレスに配置されているのか調べてみた。
GDB
(gdb) print /x _text
$20 = 0xffffffff81000000 <startup_64>
(gdb) print /x _etext
$21 = 0xffffffff81619285
(gdb) print /x _edata
$22 = 0xffffffff81a2ddc0
(gdb) print /x _brk_end
$23 = 0xffffffff81ee4000
メモ:
- 0x1000000がカーネルのエントリポイント(startup_64())でそれは物理アドレス
- 0xffffffff81000000 仮想アドレスにリンクされている。
- GDBで表示したアドレスと一致している
# cat /proc/iomem
000f0000-000fffff : System ROM
00100000-dd7a173f : System RAM
01000000-01619284 : Kernel code
01619285-01a2ddbf : Kernel data
01bc7000-01ee3fff : Kernel bss
2b000000-350fffff : Crash kernel
- /boot/System.map-カーネルバージョン
271 0000000001000000 A phys_startup_64
272 ffffffff81000000 T _text
273 ffffffff81000000 T startup_64
274 ffffffff81000110 T secondary_startup_64
275 ffffffff810001b0 T start_cpu0
276 ffffffff810001c5 t bad_address
28218 ffffffff81618b60 T bad_from_user
28219 ffffffff81618b66 t bad_to_user
28220 ffffffff81619285 T _etext
28221 ffffffff81619288 T __start_notes
28222 ffffffff81619404 T __stop_notes
28223 ffffffff81619410 R __start___ex_table
62139 ffffffff81a2d560 D inet6_protos
62140 ffffffff81a2dd60 d ipv6_packet_offload
62141 ffffffff81a2ddc0 D _edata
62142 ffffffff81a2e000 D __vvar_beginning_hack
62143 ffffffff81a2e000 D __vvar_page
62144 ffffffff81a2e000 D jiffies
69959 ffffffff81ee30e0 b net_header
69960 ffffffff81ee30e8 b klist_remove_lock
69961 ffffffff81ee4000 B __brk_base
69962 ffffffff81ee4000 B __bss_stop
69963 ffffffff81ef4000 b .brk.shared_info_page_brk
69964 ffffffff81ef5000 b .brk.p2m_missing
まとめ
start_kernel()はカーネル環境の様々な初期化をして最後にrest_init()を呼び出して終わる。