打印

Linux 0.00

[复制链接]
127|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
linux, ov, TE, se, ST
/////////////////////////////////////////// boot.s

!    boot.s

!

! It then loads the system at 0x10000, using BIOS interrupts. Thereafter

! it disables all interrupts, changes to protected mode, and calls the



BOOTSEG = 0x07c0

SYSSEG  = 0x1000            ! system loaded at 0x10000 (65536).

SYSLEN  = 17                ! sectors occupied.



entry start

start:

    jmpi    go,#BOOTSEG

go:    mov    ax,cs

    mov    ds,ax

    mov    ss,ax

    mov    sp,#0x400        ! arbitrary value >>512



! ok, we've written the message, now

load_system:

    mov    dx,#0x0000

    mov    cx,#0x0002

    mov    ax,#SYSSEG

    mov    es,ax

    xor    bx,bx

    mov    ax,#0x200+SYSLEN

    int     0x13

    jnc    ok_load

die:    jmp    die



! now we want to move to protected mode ...

ok_load:

    cli            ! no interrupts allowed !

    mov    ax, #SYSSEG

    mov    ds, ax

    xor    ax, ax

    mov    es, ax

    mov    cx, #0x2000

    sub    si,si

    sub    di,di

    rep

    movw

    mov    ax, #BOOTSEG

    mov    ds, ax

    lidt    idt_48        ! load idt with 0,0

    lgdt    gdt_48        ! load gdt with whatever appropriate



! absolute address 0x00000, in 32-bit protected mode.

    mov    ax,#0x0001    ! protected mode (PE) bit

    lmsw    ax        ! This is it!

    jmpi    0,8        ! jmp offset 0 of segment 8 (cs)



gdt:    .word    0,0,0,0        ! dummy



    .word    0x07FF        ! 8Mb - limit=2047 (2048*4096=8Mb)

    .word    0x0000        ! base address=0x00000

    .word    0x9A00        ! code read/exec

    .word    0x00C0        ! granularity=4096, 386



    .word    0x07FF        ! 8Mb - limit=2047 (2048*4096=8Mb)

    .word    0x0000        ! base address=0x00000

    .word    0x9200        ! data read/write

    .word    0x00C0        ! granularity=4096, 386



idt_48: .word    0        ! idt limit=0

    .word    0,0        ! idt base=0L

gdt_48: .word    0x7ff        ! gdt limit=2048, 256 GDT entries

    .word    0x7c00+gdt,0    ! gdt base = 07xxx

.org 510

    .word   0xAA55





/////////////////////////////////////////// end of boot.s







/////////////////////////////////////////// head.s

#  head.s contains the 32-bit startup code.

#  Two L3 task multitasking. The code of tasks are in kernel area,

#  just like the Linux. The kernel code is located at 0x10000.

SCRN_SEL    = 0x18

TSS0_SEL    = 0x20

LDT0_SEL    = 0x28

TSS1_SEL    = 0X30

LDT1_SEL    = 0x38



.text

startup_32:

    movl $0x10,%eax

    mov %ax,%ds

#    mov %ax,%es

    lss init_stack,%esp



# setup base fields of descriptors.

    call setup_idt

    call setup_gdt

    movl $0x10,%eax        # reload all the segment registers

    mov %ax,%ds        # after changing gdt.

    mov %ax,%es

    mov %ax,%fs

    mov %ax,%gs

    lss init_stack,%esp



# setup up timer 8253 chip.

    movb $0x36, %al

    movl $0x43, %edx

    outb %al, %dx

    movl $11930, %eax        # timer frequency 100 HZ

    movl $0x40, %edx

    outb %al, %dx

    movb %ah, %al

    outb %al, %dx



# setup timer & system call interrupt descriptors.

    movl $0x00080000, %eax   

    movw $timer_interrupt, %ax

    movw $0x8E00, %dx

    movl $0x08, %ecx              # The PC default timer int.

    lea idt(,%ecx,8), %esi

    movl %eax,(%esi)

    movl %edx,4(%esi)

    movw $system_interrupt, %ax

    movw $0xef00, %dx

    movl $0x80, %ecx

    lea idt(,%ecx,8), %esi

    movl %eax,(%esi)

    movl %edx,4(%esi)



# unmask the timer interrupt.

#    movl $0x21, %edx

#    inb %dx, %al

#    andb $0xfe, %al

#    outb %al, %dx



# Move to user mode (task 0)

    pushfl

    andl $0xffffbfff, (%esp)

    popfl

    movl $TSS0_SEL, %eax

    ltr %ax

    movl $LDT0_SEL, %eax

    lldt %ax

    movl $0, current

    sti

    pushl $0x17

    pushl $init_stack

    pushfl

    pushl $0x0f

    pushl $task0

    iret



/****************************************/

setup_gdt:

    lgdt lgdt_opcode

    ret



setup_idt:

    lea ignore_int,%edx

    movl $0x00080000,%eax

    movw %dx,%ax        /* selector = 0x0008 = cs */

    movw $0x8E00,%dx    /* interrupt gate - dpl=0, present */

    lea idt,%edi

    mov $256,%ecx

rp_sidt:

    movl %eax,(%edi)

    movl %edx,4(%edi)

    addl $8,%edi

    dec %ecx

    jne rp_sidt

    lidt lidt_opcode

    ret



# -----------------------------------

write_char:

    push %gs

    pushl %ebx

#    pushl %eax

    mov $SCRN_SEL, %ebx

    mov %bx, %gs

    movl scr_loc, %bx

    shl $1, %ebx

    movb %al, %gs:(%ebx)

    shr $1, %ebx

    incl %ebx

    cmpl $2000, %ebx

    jb 1f

    movl $0, %ebx

1:    movl %ebx, scr_loc   

#    popl %eax

    popl %ebx

    pop %gs

    ret



/***********************************************/

/* This is the default interrupt "handler" :-) */

.align 2

ignore_int:

    push %ds

    pushl %eax

    movl $0x10, %eax

    mov %ax, %ds

    movl $67, %eax            /* print 'C' */

    call write_char

    popl %eax

    pop %ds

    iret



/* Timer interrupt handler */

.align 2

timer_interrupt:

    push %ds

    pushl %eax

    movl $0x10, %eax

    mov %ax, %ds

    movb $0x20, %al

    outb %al, $0x20

    movl $1, %eax

    cmpl %eax, current

    je 1f

    movl %eax, current

    ljmp $TSS1_SEL, $0

    jmp 2f

1:    movl $0, current

    ljmp $TSS0_SEL, $0

2:    popl %eax

    pop %ds

    iret



/* system call handler */

.align 2

system_interrupt:

    push %ds

    pushl %edx

    pushl %ecx

    pushl %ebx

    pushl %eax

    movl $0x10, %edx

    mov %dx, %ds

    call write_char

    popl %eax

    popl %ebx

    popl %ecx

    popl %edx

    pop %ds

    iret



/*********************************************/

current:.long 0

scr_loc:.long 0



.align 2

lidt_opcode:

    .word 256*8-1        # idt contains 256 entries

    .long idt        # This will be rewrite by code.

lgdt_opcode:

    .word (end_gdt-gdt)-1    # so does gdt

    .long gdt        # This will be rewrite by code.



    .align 3

idt:    .fill 256,8,0        # idt is uninitialized



gdt:    .quad 0x0000000000000000    /* NULL descriptor */

    .quad 0x00c09a00000007ff    /* 8Mb 0x08, base = 0x00000 */

    .quad 0x00c09200000007ff    /* 8Mb 0x10 */

    .quad 0x00c0920b80000002    /* screen 0x18 - for display */



    .word 0x0068, tss0, 0xe900, 0x0    # TSS0 descr 0x20

    .word 0x0040, ldt0, 0xe200, 0x0    # LDT0 descr 0x28

    .word 0x0068, tss1, 0xe900, 0x0    # TSS1 descr 0x30

    .word 0x0040, ldt1, 0xe200, 0x0    # LDT1 descr 0x38

end_gdt:

    .fill 128,4,0

init_stack:                          # Will be used as user stack for task0.

    .long init_stack

    .word 0x10



/*************************************/

.align 3

ldt0:    .quad 0x0000000000000000

    .quad 0x00c0fa00000003ff    # 0x0f, base = 0x00000

    .quad 0x00c0f200000003ff    # 0x17



tss0:    .long 0             /* back link */

    .long krn_stk0, 0x10        /* esp0, ss0 */

    .long 0, 0, 0, 0, 0        /* esp1, ss1, esp2, ss2, cr3 */

    .long 0, 0, 0, 0, 0        /* eip, eflags, eax, ecx, edx */

    .long 0, 0, 0, 0, 0        /* ebx esp, ebp, esi, edi */

    .long 0, 0, 0, 0, 0, 0         /* es, cs, ss, ds, fs, gs */

    .long LDT0_SEL, 0x8000000    /* ldt, trace bitmap */



    .fill 128,4,0

krn_stk0:

#    .long 0



/************************************/

.align 3

ldt1:    .quad 0x0000000000000000

    .quad 0x00c0fa00000003ff    # 0x0f, base = 0x00000

    .quad 0x00c0f200000003ff    # 0x17



tss1:    .long 0             /* back link */

    .long krn_stk1, 0x10        /* esp0, ss0 */

    .long 0, 0, 0, 0, 0        /* esp1, ss1, esp2, ss2, cr3 */

    .long task1, 0x200        /* eip, eflags */

    .long 0, 0, 0, 0        /* eax, ecx, edx, ebx */

    .long usr_stk1, 0, 0, 0        /* esp, ebp, esi, edi */

    .long 0x17,0x0f,0x17,0x17,0x17,0x17 /* es, cs, ss, ds, fs, gs */

    .long LDT1_SEL, 0x8000000    /* ldt, trace bitmap */



    .fill 128,4,0

krn_stk1:



/************************************/

task0:

    movl $0x17, %eax

    movw %ax, %ds

    movl $65, %al              /* print 'A' */

    int $0x80

    movl $0xfff, %ecx

1:    loop 1b

    jmp task0



task1:

    movl $0x17, %eax

    movw %ax, %ds

    movl $66, %al              /* print 'B' */

    int $0x80

    movl $0xfff, %ecx

1:    loop 1b

    jmp task1



    .fill 128,4,0

usr_stk1:





/////////////////////////////////////////// end of head.s

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

432

主题

439

帖子

0

粉丝