热门关键字:  ubuntu  分区  Fedora  linux系统进程  函数

当前位置 :| 主页>Linux教程>内核研究>

bootsect.s注释

来源: 作者: 时间:2008-08-27 Tag: 点击:

/*
* 测试输入的段值.必须位于内存地址64KB边界处,否则进入死循环.
*/
movw %es, %ax
testw $0x0fff, %ax
die: jne die # es must be at 64kB boundary

xorw %bx, %bx # bx is starting address within segment [bx为段内偏移位置]
rp_read:
#ifdef __BIG_KERNEL__
bootsect_kludge = 0x220 # 0x200 (size of bootsector) + 0x20 (offset
lcall bootsect_kludge # of bootsect_kludge in setup.S)
#else
movw %es, %ax
subw $SYSSEG, %ax
#endif
cmpw syssize, %ax # have we loaded all yet ?
jbe ok1_read

ret
ok1_read:
movw sectors, %ax /* 取每磁道扇区数 */
subw sread, %ax /* 减去当前磁道已读扇区数 */
movw %ax, %cx /* cx = ax = 当前磁道未读扇区数. */
shlw $9, %cx /* cx = cx * 512字节. */
addw %bx, %cx /* cx = cx + 段内当前偏移值(bx) = 此次读操作后,段内共读入的字节数. */
jnc ok2_read /* 无进位转移.若没超过64KB字节,则跳转至ok2_read处执行. */

je ok2_read

xorw %ax, %ax /* 若加上此次将读磁道上所有未读扇区时会超过64KB,则计算此时最多能读 */
subw %bx, %ax /* 入的字节数(64KB - 段内读偏移位置),再转换需要读取的扇区数. */
shrw $9, %ax

ok2_read:
call read_track
movw %ax, %cx /* cx = 该次操作已读取的扇区数. */
addw sread, %ax /* 当前磁道上已经读取的扇区数. */
cmpw sectors, %ax /* 如果当前磁道上还有扇区未读,则跳到ok3_read处. */
jne ok3_read

/* 读该磁道的下一磁头面(1号磁头)上的数据.如果已经完成,则去读下一磁道. */
mov $1, %ax
subw head, %ax /* 判断当前磁头号. */
jne ok4_read /* 如果是0磁头,则再去读1磁头同上的扇区数据. */

incw track /* 否则去读下一磁道. */
ok4_read:
movw %ax, head /* 保存当前磁头号. */
xorw %ax, %ax /* 清当前磁道已读扇区数. */
ok3_read:
movw %ax, sread /* 保存当前磁道已读扇区数. */
shlw $9, %cx /* 上次已读扇区数 * 512字节. */
addw %cx, %bx /* 调整当前段内数据开始位置. */
jnc rp_read /* 若小于64KB边界值,则跳转到rp_read处,继续读数据.
* 否则调整当前值,为读下一段数据作准备. */
movw %es, %ax
addb $0x10, %ah /* 将段基址调整为指向下一个64KB段内存. */
movw %ax, %es
xorw %bx, %bx /* 清段内数据开始偏移值. */
jmp rp_read /* 继续读数据. */
read_track:
pusha
pusha
movw $0xe2e, %ax # loading... message 2e = .
movw $7, %bx
int $0x10
popa
movw track, %dx /* 取当前磁道号. */
movw sread, %cx /* 取当前磁道上已读扇区数. */
incw %cx /* cl = 开始读扇区. */
movb %dl, %ch /* ch = 当前磁道号. */
movw head, %dx /* 取当前磁头号 */
movb %dl, %dh /* dh等于磁头号 */
andw $0x0100, %dx /* 磁头号不大于1. */
movb $2, %ah /* ah = 2,读磁盘扇区功能号 */
pushw %dx # save for error dump
pushw %cx
pushw %bx
pushw %ax
int $0x13
jc bad_rt /* 若出错,则跳转至bad_rt. */

addw $8, %sp
popa
ret
/* 执行驱动器复位操作(磁盘中断功能号0),再跳转到read_track处重试. */
bad_rt:
pushw %ax # save error code
call print_all # ah = error, al = read
xorb %ah, %ah
xorb %dl, %dl
int $0x13
addw $10, %sp
popa
jmp read_track
# print_all is for debugging purposes.
#
# it will print out all of the registers. The assumption(假定) is that this is
# called from a routine, with a stack frame like
#
# %dx
# %cx
# %bx
# %ax
# (error)
# ret <- %sp
print_all:
movw $5, %cx # error code + 4 registers
movw %sp, %bp
print_loop:
pushw %cx # save count left
call print_nl # nl for readability
cmpb $5, %cl
jae no_reg # see if register name is needed

movw $0xe05 + 'A' - 1, %ax
subb %cl, %al
int $0x10
movb $'X', %al
int $0x10
movb $':', %al
int $0x10
no_reg:
addw $2, %bp # next register
call print_hex # print it
popw %cx
loop print_loop
ret
/* 屏幕打印"回车/换行"符 */
print_nl:
movw $0xe0d, %ax # CR
int $0x10
movb $0xa, %al # LF
int $0x10
ret
# print_hex is for debugging purposes, and prints the word
# pointed to by ss:bp in hexadecimal(十六进制).
/* 用十六进制的格式打印ss:bp处的字 */
print_hex:
movw $4, %cx # 4 hex digits
movw (%bp), %dx # load word into dx
print_digit:
rolw $4, %dx # rotate to use low 4 bits
movw $0xe0f, %ax # ah = request
andb %dl, %al # al = mask for nybble
addb $0x90, %al # convert al to ascii hex
daa # in only four instructions!
adc $0x40, %al
daa
int $0x10
loop print_digit
ret
# this procedure turns off the floppy drive motor, so
# that we enter the kernel in a known state, and
# don't have to worry about it later.'
# 这个子程序用于关闭软驱的马达,这样我们进入内核后它处于已知状态,以后也就无须担心它了
kill_motor:
movw $0x3f2, %dx # 软驱控制卡的驱动端口,只写
xorb %al, %al # A驱动器,关闭FDC,禁止DMA和中断请求,关闭马达
outb %al, %dx
ret
sectors: .word 0 # 存放当前启动软盘每磁道的扇区数
disksizes: .byte 36, 18, 15, 0
msg1: .byte 13, 10 # 回车,换行的ASCII码
.ascii "Loading"
# XXX: This is a "very" snug fit.
.org 497
setup_sects: .byte SETUPSECS
root_flags: .word CONFIG_ROOT_RDONLY
syssize: .word SYSSIZE
swap_dev: .word SWAP_DEV
ram_size: .word RAMDISK
vid_mode: .word SVGA_MODE
root_dev: .word ROOT_DEV
boot_flag: .word 0xAA55




相关文章:
精通initramfs构建step by step
Linux利用kexec迅速切换内核
进程上下文VS中断上下文
内核通知链 学习笔记
linux spi子系统驱动分析
menuconfig 配置选项
《Linux操作系统内核实习》之练习一
udev详解
什么叫微内核,宏内核?
Linux 信号signal处理机制
开发简单的 Linux2.6 内核模块
删除内核的perl脚本
Linux2.6内核usb gadget驱动移植
GCC hacks in the Linux kernel
iomem
kernel学习的想法
让自己的驱动支持udev
linux内核编译步骤
内核的等待队列
Linux内核wait_queue深入分析
升级和删除内核
SD卡驱动分析2
Linux Kernel VDSO本地权限提升漏洞
内核中的TCP的追踪分析-15-TCP(IPV4)的客户端与
linux 2.6内核可加载模块的编译
内核模块HelloWorld
在环回接口上发送一个数据报
ARP初始化
1分钟编译FreeBSD内核
linux设备模型之uart驱动架构分析