ローダのテスト
ローダっぽいものを作ってみた。
きちんと関数定義するでもなく、ユーザランドへのメモリ割り当てはユーザランドプログラムとカーネルの双方で予め当たらないように定義(ユーザランドはコンパイル時にロード先アドレスをリンカスクリプトで設定)、カーネルは何にも考えずにメモリにロードしてしまうという豪快なものだ。
elf32_header_t hdr = {0}; int fd = open("/TESTAPP", 0, 0); if(fd < 0) panic("open failed\n"); if(read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) panic("read failed\n"); assert(sizeof(elf32_program_header_t) == hdr.e_phentsize); assert(sizeof(elf32_section_header_t) == hdr.e_shentsize); if(hdr.e_phoff) { elf32_program_header_t ph[hdr.e_phnum]; memset(ph, 0, sizeof(ph)); if(lseek(fd, hdr.e_phoff, 0) < 0) panic("seek failed\n"); if(read(fd, ph, sizeof(ph)) != sizeof(ph)) panic("read failed\n"); int i; for(i = 0; i < hdr.e_phnum; i++) { if(ph[i].p_type == 0x1) { assert(ph[i].p_offset); assert(ph[i].p_paddr); assert(ph[i].p_filesz); assert(ph[i].p_memsz); unsigned char *dest = (unsigned char *)ph[i].p_paddr; memset(dest, 0, ph[i].p_memsz); if(lseek(fd, ph[i].p_offset, 0) < 0) panic("seek failed\n"); if(read(fd, dest, ph[i].p_filesz) != ph[i].p_filesz) panic("read failed\n"); } } } void (*testapp)(void) = (void (*)(void))hdr.e_entry; thread_t *tapp = thread_create(testapp); // tapp->md.sr |= 16; /* set status register to usermode */ thread_yield();
で、実行してみた所で気がついた。
今試しているMIPSアーキテクチャには、ユーザランド用の物理アドレス空間がないorz