内核引导的捷径(代码)
上一篇讲完简述了利用grub内核引导的流程.
下面就是代码时间了.
首先来看boot.S,规范上提供了范例代码,这里用NASM语法改写
global loader ; making entry point visible to linker extern kmain ; 这是kernel的入口函数
global start,_start ;默认的链接入口地址
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries MEMINFO equ 1<<1 ; provide memory map FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header CHECKSUM equ -(MAGIC + FLAGS) ; checksum required TEMPSTACKSIZE equ 0x4000 ;16k [section .text] align 4 ;Align 32 bits boundary
start:
_start: multiboot_header: dd MAGIC dd FLAGS ;这个FLAGS标志,便是需要设置的,你需要到时候加载器返回给你信息 dd CHECKSUM ;如果这里使用了ELF文件格式,引导头中的一部分可以不写 multiboot_entry: mov esp, stack+TEMPSTACKSIZE ; set up the temp stack push ebx ; push Multiboot info structure push eax ;push Multiboot magic number call kmain ; call kernel prope cli loop: hlt jmp loop [section .bss] align 32 stack: ;我只是临时用的堆栈而已,切换GDT后会被抛弃 resb TEMPSTACKSIZE ; reserve 16k stack on a quadword boundary
接着就应该是kernel.c 文件了.
1 void kmain( void* mbd, unsigned int magic ) 2 { 3 if ( magic != 0x2BADB002 ) 4 {
//这里用来检测,引导头是否返回的值正确,然后用来保存各种信息.
//为了简洁全部忽略 7 }
//打印一个久违的Hello,World! 8 unsigned char *videoram = (unsigned char *) 0xb8000; 9 char str[]="hello world"; 10 int i; 11 for (i=0;i<sizeof(str);i++)
{ 12 videoram[i*2] = str[i]; 13 videoram[1] = 0x07; /* forground, background color. */ 14 }
//接下来的事情,可以随意发挥了.
16 }
最后一步还是挺关键:我们的编译命令
gcc -m32 kernel.c -c -fno-stack-protector //-fno-stack-protector 这是GCC高级版本为了修改堆栈溢出问题二加入大补丁,默认GCC会开启这个功能
ld -m elf_i386 boot.o kernel.o -o kernel.img
注意:gcc fatal error: bits/predefs.h 如果出现这个错误 sudo apt-get install g++-multilib
这里我们就完成了kernel.img镜像的制作..我们迫不及待的要开始看看我们的程序是否运行正常!!
最快捷的方法,我把这个镜像文件放到了我的ubuntu的根目录,重启电脑.
出现grub2的时候不加载默认的选项,按e编辑,按F2进入命令行,输入
set root=hd0,msdos1 (这里你必须知道你的linux /根目录的分区号,我们在已存在的配置文件中可以看到这个信息,之前对一个配置文件按E的时候,可以看到)
multiboot /kernel.img (我的内核文件在/目录下)
boot
//注意grub的话,貌似命令root(0,0) 反正这一步设置根目录路径
用bochs 模拟一下这个现象,一睹为快.
看到了这番场景,是不是很愉快呢,接下来我会介绍,如何在U盘上安装grub2(grub gurb out 而且网上也有很多安装的攻略),当然我们需要linux环境这样很方便.
让我们写内核和测试更加便捷.