随笔分类 -  Linux

编写和运行简单的"Hello World"操作系统内核
摘要:通常编写一个操作系统内核是一项浩大的工程。但我今天的目标是制作一个简单的内核,用比较方便的方法在虚拟机上验证它能够被grub装载和运行,并且可通过gdb进行调试,为接下去的工作创造一个基础环境。首先,为了方便运行和调试我们需要一个虚拟机。虚拟机有很多选择,这里用最简单的qemu。先用dd创建一个文件作为虚拟盘,100MB就可以了:$ dd if=/dev/zero of=disk.img count=204800 bs=512然后对这个虚拟磁盘进行分区:$ fdisk -c=dos disk.img用命令n创建一个分区就可以了。通常情况下分区的起始扇区是2048(不带选项-c=dos),如果用 阅读全文

posted @ 2014-02-15 00:36 silmerusse 阅读(1686) 评论(0) 推荐(2)

GRUB2 分析 (四)
摘要:接上一篇kernel.img由startup.S以及一堆c文件编译而成。这是一个ELF格式的文件。(其实前面的boot.img、 diskboot.img、lzma_decompress.img本来也都是ELF格式文件,但是经过了精简。)kernel.img链接时,目标装载地址是0x9000,这是在Makefile.core.dep中定义的:i386_pc_ldflags= '$(TARGET_IMG_BASE_LDOPT),0x9000';但是现在kernel.img被加载到了0x100000,startup.S里的代码开始执行。所以开头的几个指令首先是把startup_ra 阅读全文

posted @ 2014-01-30 08:39 silmerusse 阅读(1320) 评论(5) 推荐(1)

GRUB2 分析 (三)
摘要:接上一篇从地址0x8200开始的是lzma_decompress.img。这是由startup_raw.S编译生成的。这个文件稍微复杂点。首先一开始就是个跳转指令:ljmp $0, $ABS(LOCAL (codestart)) /* 机器码:ea 1c 82 */ 跳转到0x821c,这里是真正的开始代码。0x8203到0x821b之间存放的是一些特殊数据,如压缩数据前后的长度、冗余数据的长度等,由GRUB安装时填写,后面会用到。接下来设置实模式堆栈后,切换到保护模式:DATA32 call real_to_prot然后打开Gate A20,即第21根地址线的控制线: call grub_g 阅读全文

posted @ 2014-01-29 14:58 silmerusse 阅读(1111) 评论(0) 推荐(0)

GRUB2 分析 (一)
摘要:GRUB是目前较流行启动引导程序。其第二版被主流Linux发行版所包括。本文将探索和分析GRUB的设计和实现机制。boot.S是第一个研究对象,因为boot.S将被编译成boot.img(512字节),安装时安装在0号扇区,即主引导扇区(MBR)。BIOS引导时会把主引导扇区装载到0x7c00开始的512字节内存区域,并设置CS:IP为0x0000:7c00。接着CPU会执行0x7c00处的指令,即boot.img(boot.S)中的第一条指令: jmp LOCAL(after_BPB) /* 机器码: eb 63 */ ,跳转到偏移量0x65的地方。 接下去的代码检查并设置正确的引导驱动器号 阅读全文

posted @ 2014-01-28 23:34 silmerusse 阅读(1784) 评论(0) 推荐(0)