#
# Copyright (c) 1999 Robert Nordier
# All rights reserved.
#
# Redistribution and use in source and binary forms are freely
# permitted provided that the above copyright notice and this
# paragraph and the following disclaimer are duplicated in all
# such forms.
#
# This software is provided "AS IS" and without any express or
# implied warranties, including, without limitation, the implied
# warranties of merchantability and fitness for a particular
# purpose.
#
# $FreeBSD: src/sys/boot/i386/mbr/mbr.s,v 1.7 2004/08/28 08:39:35 yar Exp $
# A 512 byte MBR boot manager that simply boots the active partition.
.set LOAD,0x7c00 # Load address
.set EXEC,0x600 # Execution address
.set PT_OFF,0x1be # Partition table
.set MAGIC,0xaa55 # Magic: bootable
.set FL_PACKET,0x80 # Flag: try EDD
.set NHRDRV,0x475 # Number of hard drives
.globl start # Entry point
.code16
#
# Setup the segment registers for flat addressing and setup the stack.
#
# 在/sys/boot/i386/mbr/Makefile中定义的LDFLAGS包含了
# "-e start -Ttext ${ORG}",即指定程序入口为"start",
# 并指定.text section的起始为止在绝对地址ORG处,而ORG
# 在同一Makefile中被定义为0x600,因此,出现在汇编指令
# 中的"$start"即表示0x600。这部分引导代 *** 是被bios加载到
# 0x7c00的,所以此处"start:"标号对应的"cld"指令的地址
# 就是0x7c00,这是第一条引导指令。此时,cpu主要寄存器的
# 内容如下:
# rax: 0x00000000:0000aa55 rcx: 0x00000000:00000000
# rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
# rsp: 0x00000000:0000ffda rbp: 0x00000000:00000000
# rsi: 0x00000000:ffff0000 rdi: 0x00000000:0008ffac
# r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
# r10: 0x00000000:00000000 r11: 0x00000000:00000000
# r12: 0x00000000:00000000 r13: 0x00000000:00000000
# r14: 0x00000000:00000000 r15: 0x00000000:00000000
# rip: 0x00000000:00007c00
# eflags 0x00000082
start: cld # String ops inc # 保证后续字符串 *** 作为增向。
xorw %ax,%ax # Zero
movw %ax,%es # Address
movw %ax,%ds # data
movw %ax,%ss # Set up
movw $LOAD,%sp # stack # 将ax、es、ds、ss清0,并将sp指向"LOAD",LOAD在本文中被
# 定义为0x7c00,这是bios加载引导扇区的地址,也即"start:"
# 标号处的"cld"指令的地址。此时,cpu主要寄存器的内容如下:
# rax: 0x00000000:00000000 rcx: 0x00000000:00000000
# rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
# rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
# rsi: 0x00000000:ffff0000 rdi: 0x00000000:0008ffac
# r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
# r10: 0x00000000:00000000 r11: 0x00000000:00000000
# r12: 0x00000000:00000000 r13: 0x00000000:00000000
# r14: 0x00000000:00000000 r15: 0x00000000:00000000
# rip: 0x00000000:00007c0c
# eflags 0x00000046
#
# Relocate ourself to a lower address so that we are out of the way when
# we load in the bootstrap from the partition to boot.
#
movw $main-EXEC+LOAD,%si # Source
movw $main,%di # Destination
movw $0x200-(main-start),%cx # Byte count
rep # Relocate
movsb # code # 由于bios将本段引导代 *** 的入口加载至0x7c00,而本段代 *** 链接时
# 指定的绝对入口地址是0x600,因此须将本段代 *** 拷贝至0x600处才能
# 正确执行后续与地址相关的指令。下面的jmp指令是在0x7c00区域
# 执行的最后一条指令,jmp之后就开始在0x600区域继续执行新建的
# 引导代 *** 复本了,而在0x600区域执行的第一条语句就是"main:"标号
# 对应的xorw指令,因此0x7c00区域中从"start:"到"main:"之间的
# 内容是不用拷贝到0x600的。EXEC在本文件中定义为0x600,这是
# "start:"标号的链接地址,LOAD则是bios对本段引导代 *** 的初始加载
# 位置,即0x7c00,因此,main-EXEC+LOAD就是0x7c00加上"main:"距
# "start:"的偏移,即"xorw %si,%si"指令在0x7c00区域的地址,引导
# 代 *** 的拷贝从这里开始。拷贝的目的地则直接使用"main:"标号的链接
# 地址,即"xorw %si,%si"指令在0x600区域的地址。在计算需要拷贝的
# 字节数时需要从引导扇区尺寸512字节(0x200)中减去
# "main:"和"start:" 之间的内容。执行实际拷贝指令之前cpu主要
# 寄存器的内容如下:
# rax: 0x00000000:00000000 rcx: 0x00000000:000001e6
# rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
# rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
# rsi: 0x00000000:ffff7c1a rdi: 0x00000000:0008061a
# r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
# r10: 0x00000000:00000000 r11: 0x00000000:00000000
# r12: 0x00000000:00000000 r13: 0x00000000:00000000
# r14: 0x00000000:00000000 r15: 0x00000000:00000000
# rip: 0x00000000:00007c15
# eflags 0x00000046
# 此时,源地址是0x7c1a,目的地址是0x061a,分别是0x7c00和0x600
# 偏移0x1a的位置,这正是"main:"和"start:"之间的距离。拷贝完成
# 之后cpu主要寄存器的内容如下:
# rax: 0x00000000:00000000 rcx: 0x00000000:00000000
# rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
# rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
# rsi: 0x00000000:ffff7e00 rdi: 0x00000000:00080800
# r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
# r10: 0x00000000:00000000 r11: 0x00000000:00000000
# r12: 0x00000000:00000000 r13: 0x00000000:00000000
# r14: 0x00000000:00000000 r15: 0x00000000:00000000
# rip: 0x00000000:00007c17
# eflags 0x00000046
#
# Jump to the relocated code.
#
jmp main-LOAD+EXEC # To relocated code # 跳转至0x600区域中"main:"标号对应的指令位置,这是在0x7c00
# 区域执行的最后一条指令。跳转完成之后cpu主要寄存器的内容如下:
# rax: 0x00000000:00000000 rcx: 0x00000000:00000000
# rdx: 0x00000000:00000080 rbx: 0x00000000:00000000
# rsp: 0x00000000:00007c00 rbp: 0x00000000:00000000
# rsi: 0x00000000:ffff7e00 rdi: 0x00000000:00080800
# r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
# r10: 0x00000000:00000000 r11: 0x00000000:00000000
# r12: 0x00000000:00000000 r13: 0x00000000:00000000
# r14: 0x00000000:00000000 r15: 0x00000000:00000000
# rip: 0x00000000:0000061a
# eflags 0x00000046
#
# Scan the partition table looking for an active entry. Note that %ch is
# zero from the repeated string instruction above. We save the offset of
# the active partition in %si and scan the entire table to ensure that>
嘿嘿 我刚装完FreeBSD7.0 就看到了这个文章 学习啦
会员注册
会员登录
个人空间
发表评论