Chinaunix首页 | 论坛 | 博客
  • 博客访问: 380002
  • 博文数量: 56
  • 博客积分: 1449
  • 博客等级: 中尉
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-08 10:24
文章分类

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类:

2010-10-18 19:30:29

/*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
阅读(2348) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~