📄 entry.asm
字号:
;
; My os startup code
; Copyright 2004-1-12
; By YaoSiHai
;
.586p
P_GDT_START equ 30000h
P_IDT_START equ 50000h
P_LDT_START equ 00000h
NULL_AREA EQU -1
LOADER_ESP_TOP equ 2ffff0h
LOADER_CODE_START equ 80000h
Code16 SEGMENT WORD PUBLIC USE16 'CODE'
startup:
;stop interupt
;Setup a temp stack
cli
cli
cli
cli
mov ax,9000h ;temp 9000:0000 same as load.c
mov sp,ax
mov ax,9000h
mov ss,ax
;a vesa display
mov ax,0003h;4f02h
mov bx,112h
int 10h
mov ah,1
mov cx,0107h
int 10h
cli
mov al,80h
out 70h,al
xor al,al
out 0f0h,al
call delay
out 0f1h,al
call delay
enableA20:
;; Make sure interrupts are disabled
mov CX, 5
a2startAttempt1:
;; Wait for the controller to be ready for a command
a2commandWait1:
xor AX, AX
in AL, 64h
bt AX, 1
jc a2commandWait1
;; Tell the controller we want to read the current status.
;; Send the command D0h: read output port.
mov AL, 0D0h
out 64h, AL
;; Wait for the controller to be ready with a byte of data
a2dataWait1:
xor AX, AX
in AL, 64h
bt AX, 0
jnc a2dataWait1
;; Read the current port status from port 60h
xor AX, AX
in AL, 60h
;; Save the current value of (E)AX
push AX ; 16-BIT
;; push EAX ; 32-BIT
;; Wait for the controller to be ready for a command
a2commandWait2:
in AL, 64h
bt AX, 1
jc a2commandWait2
;; Tell the controller we want to write the status byte again
mov AL, 0D1h
out 64h, AL
;; Wait for the controller to be ready for the data
a2commandWait3:
xor AX, AX
in AL, 64h
bt AX, 1
jc a2commandWait3
;; Write the new value to port 60h. Remember we saved the old
;; value on the stack
pop AX ; 16-BIT
;; pop EAX ; 32-BIT
;; Turn on the A20 enable bit
or AL, 00000010b
out 60h, AL
;; Finally, we will attempt to read back the A20 status
;; to ensure it was enabled.
;; Wait for the controller to be ready for a command
a2commandWait4:
xor AX, AX
in AL, 64h
bt AX, 1
jc a2commandWait4
;; Send the command D0h: read output port.
mov AL, 0D0h
out 64h, AL
;; Wait for the controller to be ready with a byte of data
a2dataWait2:
xor AX, AX
in AL, 64h
bt AX, 0
jnc a2dataWait2
;; Read the current port status from port 60h
xor AX, AX
in AL, 60h
;; Is A20 enabled?
bt AX, 1
;; Check the result. If carry is on, A20 is on.
jc a2success
;; Should we retry the operation? If the counter value in ECX
;; has not reached zero, we will retry
loop a2startAttempt1
;; Keep a counter so that we can make up to 5 attempts to turn
;; on A20 if necessary
mov CX, 5
a2startAttempt2:
;; Wait for the keyboard to be ready for another command
a2commandWait6:
xor AX, AX
in AL, 64h
bt AX, 1
jc a2commandWait6
;; Tell the controller we want to turn on A20
mov AL, 0DFh
out 64h, AL
;; Again, we will attempt to read back the A20 status
;; to ensure it was enabled.
;; Wait for the controller to be ready for a command
a2commandWait7:
xor AX, AX
in AL, 64h
bt AX, 1
jc a2commandWait7
;; Send the command D0h: read output port.
mov AL, 0D0h
out 64h, AL
;; Wait for the controller to be ready with a byte of data
a2dataWait3:
xor AX, AX
in AL, 64h
bt AX, 0
jnc a2dataWait3
;; Read the current port status from port 60h
xor AX, AX
in AL, 60h
;; Is A20 enabled?
bt AX, 1
;; Check the result. If carry is on, A20 is on, but we might warn
;; that we had to use this alternate method
jc a2warn
;; Should we retry the operation? If the counter value in ECX
;; has not reached zero, we will retry
loop a2startAttempt2
;; OK, we weren't able to set the A20 address line. Do you want
;; to put an error message here?
jmp a2fail
a2warn:
;; Here you may or may not want to print a warning message about
;; the fact that we had to use the nonstandard alternate enabling
;; method
a2success:
a2fail:
;program PIC
mov al,00010001b
out 20h,al
call delay
out 0a0h,al
call delay
mov al,80h
out 21h,al
call delay
mov al,88h
out 0a1h,al
call delay
mov al,00001100b
out 21h,al
call delay
mov al,00000010b
out 0a1h,al
call delay
mov al,00000001b
out 21h,al
call delay
out 0a1h,al
call delay
;
mov al,0h
out 21h,al
call delay
mov al,00h
out 0a1h,al
call delay
;make current ds and es to cs,fs and gs to 0
push cs
pop ds
mov ax,8000h
mov es,ax
xor ax,ax
mov fs,ax
mov gs,ax
;relocate 32-bit code to 80000:00000000
mov di,code16_end_mask+0Ch+16+8
mov cx,0
mov si,0
.while cx<0fffeh
mov al,[di]
mov es:[si],al
inc di
inc si
inc cx
.endw
;calculate the GDTItem Linear address
;xor eax,eax
;mov ax,ds
;shl eax,4
;lea ebx,MyGDTItem
;add eax,ebx
;lea ebx,MyGDT
;mov dword ptr [ebx+2],eax ;fill linear address
;load this GDT to the 3000:0000
lea esi,MyGDTItem
mov ax,3000h
mov fs,ax
mov cx,0
mov di,0
.while cx<0fffeh
mov byte ptr fs:[di],-1
inc di
inc cx
.endw
mov cx,6*8
mov di,0
.while cx>0
mov al,[si]
mov fs:[di],al
inc si
inc di
dec cx
.endw
mov ax,4000h
mov fs,ax ;idt
mov cx,0
mov di,0
.while cx<0fffeh
mov byte ptr fs:[di],-1
inc di
inc cx
.endw
mov ax,5000h
mov fs,ax ;ldt
mov cx,0
mov di,0
.while cx<0fffeh
mov byte ptr fs:[di],-1
inc di
inc cx
.endw
lgdt fword ptr MyGDT
lidt fword ptr MyIDT
mov eax,cr0 ;Get cr0
or eax,1b ;Set PE(protected enable)bit
mov cr0,eax ;Store cr0,so the CPU is in P mode
jmp flush ;clear the order pipe
flush:
db 66h,0eah ;far jmp to 32-bit segment
dword 00000000h ;offset (EIP) in new segment
word 0000000000001000b ;Selector in gdt
delay proc near
word 00ebh
ret
delay endp
MyGDT:
WORD 0800h
DWORD P_GDT_START
MyIDT:
WORD 0800h
DWORD P_IDT_START
;In my OS,there are only one GDT,32-bit code is located at 80000:00000000
MyGDTItem:
;Dumy in GDT ;index 0: Dumy
dw 0,0,0,0
;32-bit Code segment selector ;index 1: 32-bit code
dw 0ffffh
dw 0000h
db 08h
db 10011010b
db 11001111b
db 00h
;32-bit Data segment selector ;index 2: 32-bit data
dw 0ffffh
dw 0000h
db 00h
db 10010010b
db 11001111b
db 00b
;32-bit Stack segment selector ;index 3: 32-bit stack
dw 0ffffh
dw 0000h
db 00b
db 10010010b
db 11001111b
db 00b
;32-bit TSS selector ;index 4: 32-bit TSS
dw 0ffffh
dw 0000
db 00h
db 10001001b
db 10001111b
db 00b
;32-bit LDT selector ;index 5: 32-bit LDT
dw 0ffffh
dw 0000h
db 05h
db 10000010b
db 11001111b
db 00b
code16_end_mask:
db 1,2,3,4,5,6,7,8,9,0AH,0BH,0CH,0DH,0eh,0fh,0,0,0,0,0,0,0,0
code16 ends
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
EXTRN _main_start:near
org 12
start_code_32:
cli
cli
cli
cli
cli
cli
cli
cli
cli
cli
;Load stack segment and pointer
mov ax,3
shl ax,3
mov ss,ax
mov esp,LOADER_ESP_TOP
;load data segment
mov ax,2
shl ax,3
mov ds,ax
mov fs,ax
mov es,ax
mov gs,ax
;load LDT
mov ax,5
shl ax,3
lldt ax
;Setup the 32-flag
mov eax,1000010000000000000010b
push eax
popfd
jmp _main_start
_TEXT ends
end startup
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -