⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entry.asm

📁 一个最简单的操作系统,boot用NASM写的,使用最简单的汇编知识,大家下载后自己看吧
💻 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 + -