*** arch/mips/ld.script.in OUTPUT_ARCH(mips) ENTRY(kernel_entry) SECTIONS { /* Read-only sections, merged into text segment: */ . = @@LOADADDR@@; ここのENTRY(kernel_entry)でこのリンク後のイメージのエントリポイントを 指定している。 @@LOADADDR@@は、arch/mips/Makefileでプラットフォーム別に指定している。 例: ifdef CONFIG_TOSHIBA_JMR3927 CORE_FILES += arch/mips/jmr3927/rbhma3100/jmr3927.o arch/mips/jmr3927/common/tx3927.o SUBDIRS += arch/mips/jmr3927/rbhma3100 arch/mips/jmr3927/common LOADADDR += 0x80050000 endif *** arch/mips/kernel/head.S ここのkernel_entryでarch/mips/kernel/setup.cのinit_arch()を呼び出している。 /* * Kernel entry point */ NESTED(kernel_entry, 16, sp) ... jal init_arch nop END(kernel_entry) *** arch/mips/kernel/setup.c asmlinkage void __init init_arch(int argc, char **argv, char **envp, int *prom_vec) { ... /* Determine which MIPS variant we are running on. */ cpu_probe(); prom_init(argc, argv, envp, prom_vec); ... loadmmu(); ... start_kernel(); } prom_init()は例えば、arch/mips/jmr3927/rbhma3100/init.cにある。 int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) だが、これは同じMIPSアーキテクチャ内でもプラットフォームによって異なる。 例えば、arch/mips/vr4181/osprey/prom.cにある void __init prom_init() SGI用のものでは、arch/mips/arc/init.cにある void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) DEC用のものでは、arch/mips/dec/prom/init.cにある int __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) *** init/main.c asmlinkage void __init start_kernel(void) { ... printk(linux_banner); setup_arch(&command_line); printk("Kernel command line: %s\n", saved_command_line); parse_options(command_line); trap_init(); ... } *** arch/mips/kernel/setup.c static inline void cpu_probe(void) mips_cpu.cputypeにMIPS CPUバリエーションの具体的なタイプを入れる。 例:CPU_TX3927、CPU_R5000等 void __init setup_arch(char **cmdline_p) { ... #ifdef CONFIG_BLK_DEV_INITRD tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; if (tmp < (unsigned long)&_end) tmp += PAGE_SIZE; initrd_header = (unsigned long *)tmp; if (initrd_header[0] == 0x494E5244) { initrd_start = (unsigned long)&initrd_header[2]; initrd_end = initrd_start + initrd_header[1]; } #else ... } このsetup_arch()はasmlinkageが関数定義の先頭に付いていないことに注意。 ここからは通常のCの関数。 initrd_startとinitrd_end変数はボード固有のコードでセットアップする。 ボード固有のコードの方で、__rd_startと__rd_endという変数に代入 しておく。 ramdisk.gz.swをobjdump -hにかけてみて、起動アドレスを知れないか? LOADADDRはどのMIPSプラットフォームでも0x80050000の様に0x80000000から 始まっている。これは物理アドレスでなく、仮想アドレス。 boot loaderからvmlinuxはどのようにMMUをセットアップして呼べばよいのか。 Initial ramdiskはカーネルと直接リンクされる。これはarch/mips/ramdiskディレクトリに ramdisk.gzという名でファイルを置いて、カーネルのconfiguration時(make menuconfig)に ramdisk、initial ramdiskを指定すればよい。 http://www.linux4.be/~jroark/howto/ramdisk.html /usr/src/linux-2.4.20/arch/mips/Makefileに以下のようにある。 # ramdisk/initrd support # You need a compressed ramdisk image, named ramdisk.gz in # arch/mips/ramdisk # ifdef CONFIG_EMBEDDED_RAMDISK CORE_FILES += arch/mips/ramdisk/ramdisk.o SUBDIRS += arch/mips/ramdisk endif MIPSでのramdiskイメージについては以下にも情報がある。 http://decstation.unix-ag.org/docs/ramdisk.html ここでroot file systemをマウントしている。 *** init/do_mounts.c static void __init mount_block_root(char *name, int flags) { }