Linux内核bootsect.S的一个小BUG

读Linux 2.4.33.4的时候发现一个不怎么显眼的bug,位置/arch/i386/boot/bootsect.S,第271行,read_track子程序处:

read_track:
 pusha
 pusha 
 movw $0xe2e, %ax   # loading... message 2e = .
 movw $7, %bx
 int $0x10
 popa  

# Accessing head, track, sread via %si gives shorter code.

 movw 4(%si), %dx  # 4(%si) = track
 movw (%si), %cx  # (%si)  = sread
 incw %cx
 movb %dl, %ch
 movw 2(%si), %dx  # 2(%si) = head
 movb %dl, %dh
 andw $0x0100, %dx
 movb $2, %ah
 pushw %dx   # save for error dump
 pushw %cx
 pushw %bx
 pushw %ax
 int $0x13
 jc bad_rt

 addw $8, %sp
 popa
 ret

 

而在bad_rt处:

 

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

 

红色部分就是问题所在,如果读取一个磁道失败,程序跳转至bad_rt,复位磁盘后再次调用read_track子程序。

但注意此时会再次在屏幕上输出一个'.'。假设一个磁盘的磁道出现问题,则内核会一直在屏幕上输出'.'并且无法继续。当然这样不会有什么大的影响,不过这样做不太符合通常的逻辑,即读取失败光标应该卡住。一个比较好的方法是:

 

read_track:
 pusha

# Accessing head, track, sread via %si gives shorter code.

 movw 4(%si), %dx  # 4(%si) = track
 movw (%si), %cx  # (%si)  = sread
 incw %cx
 movb %dl, %ch
 movw 2(%si), %dx  # 2(%si) = head
 movb %dl, %dh
 andw $0x0100, %dx
 movb $2, %ah
 pushw %dx   # save for error dump
 pushw %cx
 pushw %bx
 pushw %ax
 int $0x13
 jc bad_rt
 addw $8, %sp

 movw $0xe2e, %ax   # loading... message 2e = .
 movw $7, %bx
 int $0x10 
 popa
 ret

 

'.'应该在成功读取一个磁道后才输出,而不是在其之前。

 

该BUG早在0.12版就已经有了!!,不过在最新的2.6系列内核中,因为不再支持从软盘引导,这部分代码已经被移除。

 

 

你可能感兴趣的:(Linux内核bootsect.S的一个小BUG)