ローダのテスト

ローダっぽいものを作ってみた。
きちんと関数定義するでもなく、ユーザランドへのメモリ割り当てはユーザランドプログラムとカーネルの双方で予め当たらないように定義(ユーザランドコンパイル時にロード先アドレスをリンカスクリプトで設定)、カーネルは何にも考えずにメモリにロードしてしまうという豪快なものだ。

	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

仕方がないのでカーネルモードで動かした所、システムコールを受け取れている事が確認できた。