一、自制内核环境的选择
在windows下自制操作系统,可参考《30天自制操作系统》,怎么评价这本书呢,
1.汇编器、编译器是作者自制,有很多不透明的地方
2.系统引导用了一些与其他系统不同的方法,比如从汇编跳转到C语言执行
当然,自制操作系统有很多方法也可以参考这本书,但是在ubuntu等linux操作系统下,使用这本书需要修改很多地方,劳力伤身,不可取。
推荐还是在ubuntu下编写自己的toy OS,那么参考的书就不叫多了:
1.选择在multiboot的前提下,编写操作系统:
因为有了bootloader的引导前提下,省略的大量的汇编工作,现在linux内核也基本改成支持这种模式了。可参考网上的《JamesM's kernel development tutorials》,当然也有人按照这个写了一个中文版的文档,按照这个可以很快进入C语言环境编写操作系统。
2.另一种引导模式,按照最开始linux内核的方法编写操作系统,相当于写一个简单的bootloader.s,然后加载内核,然后跳转执行内核:
可以推荐两个内核,一个是于渊的orange内核,有参考书籍,但是本人看见那个使用大量汇编搜索文件名就害怕,所以没有作为主要参考的内核。另一个就是airix内核,这个内核推荐一下,但是里边注释太少了,当里边进入保护模式和跳转到另一个bin执行和跳转到C语言执行可参考,可到github搜索该内核。
二、汇编器、编译器选择
当然是nasm和gcc、ld即可,但是这个跟主机系统关系有点,在编写一个基于X86内核时,最开始是16位的,最后进入保护模式以后就是32位的,如果ubuntu(采用ubuntu环境)是64位的,需要ld的命令。
具体不同可以看见如下我的makefile:
重点在C_FLAGS、ASM_FLAGS、LD_FLAGS,我的ubuntu系统是64位的所以如上设置,最开始参考<30天自制操作系统>,由于开发环境的改变,修改了很多地方,也修改了很久。################################################## # Makefile ################################################## BOOT:=boot/boot.asm LDR:=init/kernel.asm BOOT_BIN:=$(subst .asm,.bin,$(BOOT)) LDR_BIN:=$(subst .asm,.bin,$(LDR)) C_SOURCES = $(shell find ./init -name "*.c") C_OBJECTS = $(patsubst %.c,%.o,$(C_SOURCES)) S_SOURCES = $(shell find ./init -name "*.asm") S_OBJECTS = $(patsubst %.asm,%.o,$(S_SOURCES)) CC = gcc ASM = nasm LD = ld C_FLAGS = -c -Wall -m32 -ggdb -gstabs+ -nostdinc -fno-builtin -fno-stack-protector -I include LD_FLAGS = -Ttext-seg=0x8000 -m elf_i386 #LD_FLAGS = -T scripts/kernel.ld -m elf_i386 ASM_FLAGS = -felf -g -F stabs IMG:=deeppink.img deeppink.img : $(BOOT_BIN) $(S_OBJECTS) $(C_OBJECTS) link dd if=/dev/zero of=$(IMG) bs=512 count=2880 dd if=$(BOOT_BIN) of=$(IMG) conv=notrunc dd if=$(LDR_BIN) of=$(IMG) seek=1 conv=notrunc $(BOOT_BIN) : $(BOOT) nasm $< -o $@ #kernel.bin : $(LDR) # nasm kernel.asm -o kernel.bin $(C_OBJECTS):$(C_SOURCES) $(CC) $(C_FLAGS) $< -o $@ $(S_OBJECTS):$(S_SOURCES) @echo $(S_SOURCES) $(ASM) $(ASM_FLAGS) $< -o $@ link: @echo $(S_SOURCES) $(LD) $(LD_FLAGS) $(S_OBJECTS) $(C_OBJECTS) -o init/kernel.bin .PHONY:qemu qemu: @echo '启动虚拟机...' qemu-system-i386 -boot order=a -fda deeppink.img .PHONY:clean clean : rm -f $(BOOT_BIN) $(LDR_BIN) $(S_OBJECTS) $(C_OBJECTS) .PHONY:debug debug: qemu-system-i386 -s -S deeppink.img #qemu-system-i386 -s -S -boot order=a -fda deeppink.img .PHONY:bochs bochs: bochs .PHONY:dis dis: ndisasm ./boot/boot.bin > ./boot/boot.txt objdump -d ./init/kernel.bin > ./init/kernel.txt
三、仿真器选择
首先bochs,调试方便。尤其是如果只是参考上面的内核,没有大量借鉴其中的代码,总是会出现很多问题(跳转是否成功,默认跳转段等等),尤其是进入保护模式以后,对于没有精通汇编的人来说,bochs的调试功能特别方便,当然我也使用了qemu,试了qemu的调试功能,不是很方便。