一个操作系统的实现-笔记-开启时钟中断

##版本0.2 设置IDT,开启时钟中断

代码如下

kernel.asm

; nasm -f elf kernel.asm -o kernel.o
; ld -s -Ttext 0x10000 kernel.o -o kernel.bin        
; dd if=kernel.bin of=a.img bs=512 seek=1 conv=notrunc

[section .text]
[bits 32]

global _start

_start:
    mov ax, 16
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov esp, 0x7c00
    mov ax, 24
    mov gs, ax

    lidt [idtptr]

    call print
    call init8259a

    sti

end:
    jmp end

print:
    mov edi, (80 * 11 + 79) * 2
    mov ah, 0x0c
    mov al, 'K'
    mov [gs:edi], ax
    ret

_clock:
clock equ _clock - $$ + 0x10000           ; 0x10000就是ld中的入口地址
    inc byte [gs:((80 * 11 + 79) * 2)]
    mov edi, (80 * 11 + 78) * 2
    mov ah, 0x0c
    mov al, 'I'
    mov [gs:edi], ax

    mov al, 0x20
    out 0x20, al
    iretd

init8259a:
    mov al, 0x11
    out 0x20, al
    call io_delay

    out 0xa0, al
    call io_delay

    mov al, 0x20
    out 0x21, al
    call io_delay

    mov al, 0x28
    out 0xa1, al
    call io_delay

    mov al, 0x04
    out 0x21, al
    call io_delay

    mov al, 0x02
    out 0xa1, al
    call io_delay

    mov al, 0x01
    out 0x21, al
    call io_delay

    out 0xa1, al
    call io_delay

    mov al, 11111110b ;
    out 0x21, al
    call io_delay

    mov al, 11111111b
    out 0xa1, al
    call io_delay

    ret

io_delay:
    nop
    nop
    nop
    nop
    ret

idt:
%rep 255
    dw (clock & 0xffff)
    dw 8
    dw 0x8e00
    dw (clock >> 16)
%endrep

idtlen equ $-idt
idtptr dw idtlen-1
       dd idt

通过readelf -a kernel.bin, 可以知道.text的大小是0x8ac,4个多扇区,所以直接读入内存5个扇区。

bootsect.asm

; nasm bootsect.asm -o bootsect.bin
; dd if=bootsect.bin of=a.img bs=512 count=1 conv=notrunc
org 0x7c00

jmp start

gdt:
    dw 0
    dw 0
    dw 0
    dw 0
gdt_code:       ; 基址为0,大小4GB的32位可执行代码段
    dw 0xffff
    dw 0x0000
    dw 0x9a00
    dw 0x00cf
gdt_data:       ; 基址为0,大小4GB的32位可读写数据段
    dw 0xffff
    dw 0x0000
    dw 0x9200
    dw 0x00cf
gdt_video:      ; 基址为0xb8000,大小64KB的可读写显存段
    dw 0xffff
    dw 0x8000
    dw 0x920b
    dw 0x0000

gdtlen equ $ - gdt
gdtptr dw gdtlen -1
       dd gdt

start:
; 利用0x13号BIOS中断,将软盘kernel.bin中的.text读入内存0x1000:0x0000(实模式)。
    mov ax, 0x1000
    mov es, ax
    mov bx, 0

    mov ax, 0x0205  ; 读入5个扇区
    mov cx, 0x000a
    mov dx, 0

    int 0x13

into_kernel:
    ; 加载GDT
    lgdt [gdtptr]

    ; 关中断
    cli

    ; 开启A20线
    in al, 0x92
    or al, 00000010b
    out 0x92, al

    ; 打开保护模式
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    ; 进入保护模式
    jmp dword 0x8:0x10000 ; 0x8, 可执行代码段gdt_code

fill:
   times 510-($ - $$) db 0
   dw 0xaa55

转载于:https://my.oschina.net/wangconglin87/blog/549402

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值