/*bootsect.S
*I don't mean to write the whole OS kernel.I just want to put what I have
*already learned into practice.But what will it be end up looking like.
*I don't know.ALA I have some free time,I will write something.Just like
*linus once said,"Just for fun".I don't care what this small ugly codes
*will be capable of,or does it worth something.I just write it for fun,
*and for practice.
* 10 / 2 / 2010 liangtao
* E-mail:liangtao90s@gmail.com
*i don't know much about the underlying implementation of GRUB or LILO or
*anything that can load a OS's kernel into the RAM. i also don't know much
*about how to load the something into the RAM from a hard-disk.So, here i
*can only write something to load the instructions from a floppy into the
*RAM.It's rather simply. *IF anyone knows loading from a disk. CC me.
*Many thanks...
*As the excuted instruction flow starts from 0x7c00,So, it first
*moves itself to address 0x90000.Then loads the setup.S and place it at
*address 0x90200.After this, it prints out something information telling
*the user what is currently going on.Finally,It's time to load the system
*image into the RAM.
*/
BOOTSEG = 0x7c0
INITSEG = 0x9000
SETUPSEG = 0x9020
SYSSEG = 0x1000
SETUPLEN = 4
ENDSEG = 0x4000
#define __DEBUG__ 0
STACK_TOP = 0xff00
MSG_LEN = 14
MSG_COLOR = 0x0007
.code16
.text
.global __start
__start:
movw $BOOTSEG, %ax #moves itself
movw %ax, %ds
movw $INITSEG, %ax
movw %ax, %es
xorw %si, %si
xorw %di, %di
movw $256, %cx
rep
movsw
ljmp $INITSEG, $__new_start # cs = seg, ip = offset
__new_start:
movw %ax, %ds
movw %ax, %ss
movw $STACK_TOP, %ax
movw %ax, %sp
__load_setup:
movw $SETUPSEG, %ax #destination segment
movw %ax, %es
xorw %bx, %bx
xorw %dx, %dx # head 0, drive 0
movw $0x0002, %cx
movb $SETUPLEN, %al
movb $0x02, %ah
int $0x13
jnc __ok_load_setup
__reset_controller:
xorb %bl, %bl
xorb %ah, %ah
int $0x13
jnc __load_setup
jmp __reset_controller
__ok_load_setup:
#print sth...
movw $INITSEG, %ax
movw %ax, %es # need it! see above ...
xorw %bx, %bx
movb $0x03, %ah
int $0x10
movw $MSG_LEN, %cx
movw $MSG_COLOR, %bx
movw $msg, %bp
movw $0x1301, %ax
int $0x10
# prepare to load the system, first we need to get the number of sectors per
# track the media have so that we can get through it much easier and faster.
xorb %bl, %bl
movb $0x08, %ah
int $0x13
andb $0x3f, %cl
xorb %ch, %ch
movw %cx, sectors
movw $SYSSEG, %ax
movw %ax, %es
call __read_it
call __kill_motor
#if __DEBUG__
movw $INITSEG, %ax
movw %ax, %es
xorw %bx, %bx
movb $0x03, %ah
int $0x10
movw $54, %cx
movw $0x0007, %bx
movw $msg_debug, %bp
movw $0x1301, %ax
int $0x10
#endif
# don't bother to check the root dev. just simply jump to SETUPSEG:0
ljmp $SETUPSEG, $0
# rather boring...
nr_read:
.word 1 + SETUPLEN
cur_head:
.word 0
cur_track:
.word 0
__read_it:
movw %es, %ax
testw $0x0fff, %ax
die:
jne die
xorw %bx, %bx
rp_read:
movw %es, %ax
cmpw $ENDSEG, %ax
jb ok1_read
ret
ok1_read:
movw sectors, %ax
subw nr_read, %ax
movw %ax, %cx
shlw $9, %cx
addw %bx, %cx
jnc ok2_read
xor %ax, %ax
subw %bx, %ax
shrw $9, %ax
ok2_read:
call read_track
movw %ax, %cx
addw nr_read, %ax
cmpw %ax, sectors
jne ok3_read
movw $1, %ax
subw cur_head, %ax
jnz ok4_read
incw cur_track
ok4_read:
movw %ax, cur_head
xorw %ax, %ax
ok3_read:
movw %ax, nr_read
shlw $9, %cx
addw %cx, %bx
jnc rp_read
movw %es, %ax
addw $0x1000, %ax
movw %ax, %es
xorw %bx, %bx
jmp rp_read
read_track:
pushw %ax
pushw %bx
pushw %cx
pushw %dx
movw cur_track, %dx
movw nr_read, %cx
incb %cl
movb %dl, %ch
movw cur_head, %dx
movb %dl, %dh
xorb %dl, %dl
movb $0x02, %ah
int $0x13
jc bad_read
popw %dx
popw %cx
popw %bx
popw %ax
ret
bad_read:
xorb %dl, %dl
xorb %ah, %ah
int $0x13
popw %dx
popw %cx
popw %bx
popw %ax
jmp read_track
__kill_motor:
pushw %dx
movw $0x03f2, %dx
movb $0, %al
outb %al, %dx
popw %dx
ret
#if __DEBUG__
msg_debug:
.ascii "bootsect successfully completed...congratuations...!"
.byte 13, 10
#endif
sectors:
.word 0
msg:
.byte 13, 10
.ascii "Loading..."
.byte 13, 10
.org 510
boot_magic:
.word 0xaa55
阅读(2343) | 评论(0) | 转发(0) |