您的位置:首页 > 其它

一步一步实现一个简单的OS(加载内核)

2016-03-08 10:42 197 查看
这一块更新的代码比较多,所以就不方便全部贴出来了。。。具体的代码大家直接到群里面找就可以了(OS0.3)

另外,我配置了bochs虚拟机,这样大家载下来就可以使用bochs虚拟机直接调试了。

下面我就直接贴一下主要的代码吧,,,,,,

setupasm.S ( 这里,跳转到c函数直接call就可以了)

start32:
# 初始化保护模式下的各个段的段寄存器
movw    $PROT_MODE_DSEG, %ax
movw    %ax, %ds
movw    %ax, %es
movw    %ax, %fs
movw    %ax, %gs
movw    %ax, %ss

movl    $start, %esp      # 之前的代码没用了,让堆栈覆盖了吧

# 这里跳转到C语言编写的程序中
call    setupmain

# 好了,到这里死循环吧,下节,弄C语言的,这样看起来就简单多了
# 其实,我觉得,还是这个简单
1:
hlt
jmp     1b


setupmain.c (这里就直接贴重定向ELF文件的代码,之前是想用PE格式的了,然后看了下,PE的重定向篇幅比较大,所以就直接用ELF的了。)

// 初始化内核加载地址
elf = (struct elfhdr*)0x10000;

// 载入内核
readseg((uint)elf, SECTSIZE*8, KERNEL_DISK_OFFSET);

// 判断内核是否为ELF文件格式
if(elf->magic != ELF_MAGIC)
goto bad;

// 对ELF文件重定向
ph = (struct proghdr*)((uchar*)elf + elf->phoff);
eph = ph + elf->phnum;
for(; ph < eph; ph++)
readseg(ph->va & 0xFFFFFF, ph->memsz, ph->offset + KERNEL_DISK_OFFSET);  // 这里是要加入偏移的,用WinHex看ELF头格式,可以具体分析出来

// 获取内核入口点,并跳入内核
entry = (void(*)(void))(elf->entry & 0xFFFFFF);
entry();   // 跳入内核入口


main.c (这里,直接就简单的写一下,用来测试setup加载内核是否正确, 实现了printf函数,这样以后写起来就方便多了)

/**
* 内核入口
*/
int kmain()
{
// 这里,就显示个信息吧,简单些
printf("in the kernel code\n");
// 其实这里是不可以返回的。
// 不过就这样吧,看看返回去有没有错误
return 0;
}


下面就贴一个运行的截图吧。。。。。。感觉贴张图,看的人就多了,好奇怪



OK, 就这些了,不懂的群里问吧[QQ qun: 545250960]。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: