grub2 1.95 源码分析之一

/* -*-Asm-*- *//** GRUB — GRand Unified Bootloader* Copyright (C) 1999,2000,2001,2002,2005,2006 Free Software Foundation, Inc.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/

// cppgp 注释版// 转载请注明原作者// 注释版本号 : 1.00// 日期 : 2008-01-22// 联系方式 :// emailyanyg02@163.com// msnyanyg02@hotmail.com// qq281607998

// boot.S 流程及功能简介 ://boot.S 生成 512 字节的机器码存储在硬盘或者软盘的 MBR 中 , 被 BIOS 加载// 到内存 0x7C00 处 , 然后 BIOS 设置 CPU 跳转至 0x7C00 处开始执行 , 控制权到了// boot.S 手中 . boot.S 根据 BIOS 设置的寄存器初始值和一些 INT 中断调用 , 判断// 引导驱动器是 LBA硬盘/CHS硬盘/软盘 中的哪一种 , 并保存磁盘参数到磁盘参数块地// 址(BPB) , 然后读取由 kernel_sector 处的 8 字节确定的扇区块 ( 即diskboot.img// 由 bootdisk.S 生成的二进制码文件 )内存储的 512 字节的内容到内存地址 0x70000// 处 , 再拷贝到内存 0x8000 处 , 然后跳转至 0x8000 开始执行 , 由 bootdisk.S 获// 得控制权 , 而 boot.S 就功成身退了. 但是 boot.S 设置的实模式下的堆栈及寄// 存器值,以及引导驱动器的模式和参数 , 在 bootdisk.S 中都有用到 . 具体请看代码// 注释及 diskboot.S 的注释 . 如果在加载 diskboot.img 的过程中出错, 则输出错误// 提示信息 , 进入死循环 , 等待手工重起或者关闭.//boot.S 生成的机器码被加载在 0x7C00~0x7DFF 处, 具体机器码见文档最后部分

// 这个头文件里面只定义了一个版本号#include <grub/boot.h>

// 这个头文件即../.././include/grub/i386/pc/boot.h , 定义引导需要的系统常量定义#include <grub/machine/boot.h>

// 在代码中使用宏的地方 , 我都做了宏的说明 , 读者不需要跟踪到对应 .h 文件中看宏定义

/** defines for the code go here*/

/* Absolute addresses This makes the assembler generate the address without support from the linker. (ELF can’t relocate 16-bit addresses!)*/

// ABS(x)计算x的绝对地址,用来生成不受连接器限制的地址(ELF不能生成可重入的地址).#define ABS(x) (x-_start+0x7c00)

/* Print message string */// 打印 x 指向的字符串到终端#define MSG(x)movw $ABS(x), %si; call message

/* XXX:binutils-2.9.1.0.x doesn’t produce a short opcode for this. */#defineMOV_MEM_TO_AL(x).byte 0xa0; .word x// binutils-2.9.1.0.x不能生成short操作码,使用这个宏传递x给AL.file"boot.S"

.text

/* Tell GAS to generate 16-bit instructions so that this code works in real mode.*/// 告知GAS生成16位的指令,使以下代码可以工作在实模式下// 说明 : GAS是gcc的汇编器

.code16

// 以下代码被BIOS启动例程加载至0X7C00处并且跳转到此处执行,过程描述如下:// (为降低分析复杂度,我们假设从硬盘启动.)// BIOS读取硬盘的MBR扇区共512字节,并放在地址0X0000:0X7C00处// 跳转到0X0000:0X7C00处去执行// 此时设置寄存器如下://CS:IP = 0X0000:0X7C00!即代码段基址为0,偏移量为0X7C00//ES:SI!指向BIOS中硬盘分区表的地址.//DL!引导设备number,00×80~0xFF

.globl _start; _start:/* * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00 */

/* * Beginning of the sector is compatible with the FAT/HPFS BIOS * parameter block. */// 扇区开始处和BIOS参数块都是FAT/HPFS格式兼容的.

// 跳转到after_BPB内存处jmpafter_BPBnop/* do I care about this ??? */// nop 永远不会执行!

/* * This space is for the BIOS parameter block!!!! Don’t change * the first jump, nor start the code anywhere but right after * this area. */// 以下空间是留给BIOS参数块的!!!// 不要更改跳转指令// 除了恰在BIOS参数块后的位置,也不要开始执行指令

. = _start + 4// 保留空间 : 使本节代码占用的空间到_start+4处.如下分析://jmp after_BPB占用2字节//nop占用1字节// 因此多保留一字节地址并以0填充.// 事实上,在生成的.img文件中,开始处四字节的机器码是:eb4b9000//Address0x7C000x7C010x7C020x7C03//Valueeb4b9000//Operatorjmpsfter_BPBnop00

/* scratch space *///保留的空间//占用 4 字节 , _start+0x00 ~ _start+0x03

没有朋友的人生是孤独的,不完整的,可是,因为生活的忙碌,

grub2 1.95 源码分析之一

相关文章:

你感兴趣的文章:

标签云: