start_kernelでようやくLinux kernelに入ってきました。細かいところはざっとながしてフィーリングでカーネルのソースを眺めます。
start_kernelを紐解く
start_kernelはinit/main.cにあります。printkでLinuxのバナーを表示しています。
asmlinkage void __init start_kernel(void) { char * command_line; extern char saved_command_line[]; /* * Interrupts are still disabled. Do necessary setups, then * enable them */ lock_kernel(); printk(linux_banner);
こんな表示ですね。
Linux version 2.4.34.5-uc0 (ocha@M715Q-TINY) (gcc version 4.7.2 (GCC) ) #49 Sat May 22 22:05:45 JST 2021
その次にCPUアーキテクチャ用の設定を行っています。ここは関連がありそうなので追ってみます。
setup_arch(&command_line);
setup_archを紐解く
setup_arch()をみてみます。この関数はarch/m68knommu/kernel/setup.cにあります。このあたりはコードとデータのアドレスを変数に設定しているようです。
void setup_arch(char **cmdline_p) { memory_start = PAGE_ALIGN(_ramstart); memory_end = _ramend; /* by now the stack is part of the init task */ init_mm.start_code = (unsigned long) &_stext; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) 0;
次のconfig_BSP()はarch/m68knommu/platform/68EZ328/config.cにあります。
config_BSP(&command_line[0], sizeof(command_line));
config_BSP()ではprintkで68EZ328のバナーを表示したあとにUCSIMMの情報を取得して、コマンドラインに載せていますが、ここは自作ボードですのでコメントにして、コマンドラインには文字列の終端の0だけ入れました。その後各種エントリポイントを設定しているようですが、mountには関係ないので飛ばします。
void config_BSP(char *command, int len) { unsigned char *p; printk("\n68EZ328 DragonBallEZ support (C) 1999 Rt-Control, Inc\n"); #ifdef CONFIG_UCSIMM /* printk("uCsimm serial string [%s]\n",getserialnum()); p = cs8900a_hwaddr = gethwaddr(0); printk("uCsimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", p[0], p[1], p[2], p[3], p[4], p[5]); p = getbenv("APPEND"); if (p) strcpy(p,command); else command[0] = 0; */ command[0] = 0; #endif mach_sched_init = BSP_sched_init; mach_tick = BSP_tick; mach_gettimeoffset = BSP_gettimeoffset; mach_gettod = BSP_gettod; mach_hwclk = NULL; mach_set_clock_mmss = NULL; // mach_mksound = NULL; mach_reset = BSP_reset; // mach_debug_init = NULL; config_M68EZ328_irq(); }
再びsetup_arch()にもどります。このあたりはバナーですね。
printk("\r\nuClinux/" CPU "\n"); printk("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
実際はこんな表示になります。
uClinux/MC68EZ328 Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne
次は重要な部分です。今問題となっているルートデバイスを作っています。
ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
BLKMEM_MAJORはdrivers/block/blkmem.cで定義されていて、31です。
#define BLKMEM_MAJOR 31
Documentation/devices.txtには以下の記述があります。これで/dev/rom0だとわかります
31 block ROM/flash memory card 0 = /dev/rom0 First ROM card (rw) ...
さて、setup_archのソースに戻ります。ここはコマンドラインを保存していますね。
/* Keep a copy of command line */ *cmdline_p = &command_line[0]; memcpy(saved_command_line, command_line, sizeof(saved_command_line)); saved_command_line[sizeof(saved_command_line)-1] = 0;
次はメモリ管理で何かやっているようですが、今のトラブルとは関係なさそうなので飛ばします。
/* * give all the memory to the bootmap allocator, tell it to put the * boot mem_map at the start of memory */ bootmap_size = init_bootmem_node( NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */ PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */ memory_end >> PAGE_SHIFT); /* * free the usable memory, we have to make sure we do not free * the bootmem bitmap so we then reserve it after freeing it :-) */ free_bootmem(memory_start, memory_end - memory_start); reserve_bootmem(memory_start, bootmap_size); /* * get kmalloc into gear */ paging_init(); }
これでsetup_arch()は終わりです。romfsに関連した部分が見つかったのは収穫です。
ふたたび、start_kernelにもどります。(続く)