启动扇区代码分析 FreeBSD 5.2.1 boot0( 六 )


# User"s last try was bad, beep in displeasure.
# Since nothing was printed, just continue on as if the user
# hadn"t done anything. This gives the effect of the user getting a beep
# for all bad keystrokes but no action until either the timeout
# occurs or the user hits a good key.
#
main.10:
movb $0x7,%al # Signal
callw putchr # error
用户输入错误,只是响铃提示,其他什么也不发生 。

#
# Get the keystroke.
#
main.11:
xorb %ah,%ah # BIOS: Get
int $0x16 # keypress
movb %ah,%al # Scan code
用户按下了一个键,把键值扫描码放到al中 。

#
# If it"s CR act as if timed out.
#
cmpb $KEY_ENTER,%al # Enter pressed?
je main.9 # Yes
如果用户按下“Enter”键,和超时等同处理,这样,就启动缺省的boot分区 。

#
# Otherwise check if legal
# If not ask again.
#
subb $KEY_F1,%al # Less F1 scan code
cmpb $0x4,%al # F1..F5?
jna main.12 # Yes
subb $(KEY_1 - KEY_F1),%al # Less #1 scan code
cmpb $0x4,%al # #1..#5?
ja main.10 # No
如果是除“Enter”键外其他的键,则检查是不是F1...F5键,如果不是,
表示输入不合法,跳回到main.10处理 。

#
# We have a selection.
# but if it"s a bad selection go back to complain.
# The bits in MNUOPT were set when the options were printed.
# Anything not printed is not an option.
#
main.12:
cbtw # Option
btw %ax,_MNUOPT(%bp) # enabled?
jnc main.10 # No
如果是F1...F5键,则检查是否在我们提示的范围内,其中,_MNUOPT(%bp)的相应
bit位为1,表示是一个合法的选项,如果不是,跳回到 main.10处理 。

#
# Save the info in the original tables
# for rewriting to the disk.
#
movb %al,_OPT(%bp) # Save option
把我们按下的F1...F5键保存到_OPT(%bp)位置 。

movw $FAKE,%si # Partition for write
movb (%si),%dl # Drive number
把原来的启动分区代码取回到dl中 。

movw %si,%bx # Partition for read
cmpb $0x4,%al # F5 pressed?
pushf # Save
je main.13 # Yes
如果我们按下的是F5键则直接跳转到main.13处理 。

shlb $0x4,%al # Point to
addw $partbl,%ax # selected
xchgw %bx,%ax # partition
movb $0x80,(%bx) # Flag active
上面,我们从按键Fx选择中得到图(三)中的我们选择的四个分区信息中的某一分区信息,
上面计算出的bx为我们选择的分区信息的首地址,我们把此选择到的分区信息的第一个
个字节置为0x80表示它是当前的活动分区 。
#
# If not asked to do a write-back (flags 0x40) don"t do one.
#
main.13:
pushw %bx # Save
testb $0x40,_FLAGS(%bp) # No updates?
jnz main.14 # Yes
movw $start,%bx # Data to write
movb $0x3,%ah # Write sector
callw intx13 # to disk
检查回写标志_FLAGS(%bp)的bit位0x40为,如果设置的是可回写,则把当前选择到的boot
分区作为下次缺省的启动分区 。

main.14:
popw %si # Restore
popf # Restore

#
# If going to next drive, replace drive with selected one.
# Remember to un-ascii it. Hey 0x80 is already set, cool!
#
jne main.15 # If not F5
恢复上面保存的si和标志寄存器的内容 。如果不是按键F5,则直接跳转到main.15去执行 。

movb _NXTDRV(%bp),%dl # Next drive
subb $"0",%dl # number

否则的话,我们选择下一个驱动器作为启动盘 。
#
# load selected bootsector to the LOAD location in RAM.
# If it fails to read or isn"t marked bootable, treat it
# as a bad selection.
# XXX what does %si carry?
#
main.15:
movw $LOAD,%bx # Address for read
movb $0x2,%ah # Read sector
callw intx13 # from disk
jc main.10 # If error
把我们上面选择到的分区读到0x7c00处,就象我们刚刚才加电启动一样,只是活动分区改变
了而已 。如果发生读错误则直接跳转到main.10 。使用户重新选择启动分区 。

推荐阅读