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

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类:

2010-10-18 19:32:04

/* setup.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 / 3 / 2010        liangtao
 *            E-mail:liangtao90s@gmail.com

 *As simple as possible.Because I don't have all the information about the
 *underlying hardware,So only the currently critical information is obtaind
 *by the bios call.Others will be add ASA we need them.
 */

/*
 * add memory probe code.as for now, the existed code can generate something
 * on the screen.so i think it's time to add this code.it will be more easy
 * to debug.just print the memory probe info on the screen. 10 / 12/ 2010
 */

#define __ASM__
#include
#include
#include
#define __DEBUG__ 0

INITSEG            = 0x9000
SETUPSEG            = 0x9020
.code16
.global        begtext, begdata, begbss, endtext, enddata, endbss

.text
begtext:
.data
begdata:
.bss
begbss:

.text
_start:
#if    __DEBUG__
        movw        $SETUPSEG, %ax
        movw        %ax, %ds
        call        print_msg
        movw        $INITSEG, %ax
        movw        %ax, %ds
#endif
        movb        $0x03, %ah
        int        $0x10
        movw        %dx, (0)
        
        

#get the memory map through BIOS call.first try e820h,then e801h, finally
#the traditional 88h way.
#define SMAP 0x534d4150
        xorw        %ax, %ax
        movw        %ax, (E820_MAP_NR)

        movw        $E820_MAP_OFF, %di
        xorl        %ebx, %ebx
mem_e820_probe:
        movw        $E820_MAP_SEG, %ax
        movw        %ax, %es
        movl        $20, %ecx
        movl        $SMAP, %edx
        movl        $0xe820, %eax
        int        $0x15
        jc            mem_e801_probe
        cmpl        $SMAP, %edx
        jne        mem_e801_probe
        movw        (E820_MAP_NR), %ax
        cmpw        $E820_MAP_NR_MAX, %ax
        jnl        mem_e801_probe
        incw        (E820_MAP_NR)
        movw        %di, %ax
        addw        $20, %ax
        movw        %ax, %di
        cmpl        $0, %ebx
        jne        mem_e820_probe

mem_e801_probe:
        xorw        %ax, %ax
        movw        %ax, (E801_FLAG)
        movw        $0xe801, %ax
        int        $0x15
        jc            mem88_probe
        incb        (E801_FLAG)
        andl        $0xffff, %eax
        movl        %eax, (E801_PART1)
        andl        $0xffff, %ebx
        movl        %ebx, (E801_PART2)

mem88_probe:
        xorb        %al, %al
        movb        %al, (MEM88_FLAG)
        movb        $0x88, %ah
        int        $0x15
        jc            mem_probe_end
        incb        (MEM88_FLAG)
#        andl        $0xffff, %eax
        movw        %ax, (MEM88_EXT)
mem_probe_end:
        movw        $SETUPSEG, %ax
        movw        %ax, %ds

#open the a20-gate,prepare to enter the 32-bit protected mode world!
        call        empty_8042
        movb        $0xd1, %al
        outb        %al, $0x64
        call        empty_8042
        movb        $0xdf, %al        #open it!
        out        %al, $0x60
        call        empty_8042
        

#disable interrupt and nmi.then load idtr and gdtr.
        cli
        movb        $0x80, %al
        outb        %al, $0x70

        movb        $0xff, %al        #mask all the interrupts
        outb        %al, $0x21
        .word        0x00eb, 0x00eb
        outb        %al, $0xa1
        .word        0x00eb, 0x00eb
        
        lidt        idt_48
        lgdt        gdt_48

#say goodbye to the real mode...
        movw        $0x0001, %ax
        lmsw        %ax
        jmp        flush_instr
flush_instr:
    .byte 0x66, 0xea            # prefix + jmpi-opcode
    .long    0x10000                
                        
    .word    __KERNEL_CS
        


empty_8042:                                        #taken from linux. setup.S
        pushl        %ecx                            #It's more reasonable.
        movl        $100000, %ecx

empty_8042_loop:
        decl        %ecx
        jz            empty_8042_end_loop

        call        delay

        inb        $0x64, %al            # 8042 status port
        testb        $1, %al                # output buffer?
        jz            no_output

        call        delay
        inb        $0x60, %al            # read it
        jmp        empty_8042_loop

no_output:
        testb        $2, %al                # is input buffer full?
        jnz        empty_8042_loop            # yes - loop
empty_8042_end_loop:
        popl        %ecx
        ret
        
delay:
        outb         %al, $0x80
        ret

gdt_table:
        .long        0, 0                #NULL
        .long        0, 0                 #reserved
#kernel code segment
        .word        0xffff            #limit:0-15 bit
        .word        0x0000            #base: 0-15 bit
        .word        0x9a00            #base: 16-23 bit,type:1010b,s=1,dpl=0,p=1
        .word        0x00cf            #base: 24-31 bit,G=1,B=1,limit: 16-19
#kernel data segment
        .word        0xffff
        .word        0x0000
        .word        0x9200
        .word        0x00cf

idt_48:
        .word        0
        .word        0, 0

gdt_48:
        .word        0x800
        .word        0x200+gdt_table, 0x0009        #base address

#if __DEBUG__
msg:
        .byte 13, 10
        .ascii "I'm in setup"
        .byte 13, 10
MSG_LEN        = 16
print_msg:
        pushw        %ax
        pushw        %bx
        pushw        %cx
        pushw        %bp
        pushw        %es
        movw        $SETUPSEG, %ax
        movw        %ax, %es            
        xorw        %bx, %bx
        movb        $0x03, %ah
        int        $0x10

        movw        $MSG_LEN, %cx
        movw        $0X0007, %bx
        movw        $msg, %bp
        movw        $0x1301, %ax
        int        $0x10
        popw        %es
        popw        %bp
        popw        %cx
        popw        %bx
        popw        %ax
        ret

#endif
.text
endtext:
.data
enddata:
.bss
endbss:
阅读(2251) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~