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

📄 load.asm

📁 一个类linux的dos下开发的操作系统.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	mov ax,DATA_SEL16
	mov ss,ax
	mov ds,ax
	mov es,ax
	mov fs,ax
	mov gs,ax
	mov eax,cr0
	and al,0FEh		; pmode off
	mov cr0,eax
	jmp far [real_mode_ip]

pmode16_to_real:		; finish switching to real mode
	lidt [real_idt_ptr]
	mov ax,cs
	mov ss,ax
	mov ds,ax
	mov es,ax
	mov fs,ax
	mov gs,ax
real:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; enable unreal mode
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	cli
	push ds
		lgdt [gdt_ptr]
		mov eax,cr0
		or al,1
		mov cr0,eax	; partial switch to pmode
		mov ax,LINEAR_DATA_SEL
		mov ds,ax	; selector to segment w/ 4G limit
		mov es,ax	; set seg limits in descriptor caches
		mov fs,ax
		mov gs,ax	; (do NOT change CS nor SS)
		mov eax,cr0
		and al,0FEh
		mov cr0,eax	; back to (un)real mode
		nop
	pop ds			; segment regs back to old values,
	xor ax,ax		; but now 32-bit addresses are OK
	mov es,ax
	mov fs,ax
	mov gs,ax

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get virt-to-phys conversion value to EDX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	mov ebx,end		; offset of end of this .COM file
	add ebx,[end + 8]	; offset of DJGPP kernel in initial RAM disk

	mov edi,[load_adr]	; physical (load) adr of .text
	mov edx,edi
	sub edx,[bx + COFF_TEXT_VIRT] ; virtual adr of .text

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; copy kernel .text and .data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	mov ecx,[bx + COFF_TEXT_SIZE]
	mov esi,[bx + COFF_TEXT_OFFSET]
	add esi,ebx
	mov edi,[bx + COFF_TEXT_VIRT]
	add edi,edx
	a32
	rep movsb

	mov ecx,[bx + COFF_DATA_SIZE]
	mov esi,[bx + COFF_DATA_OFFSET]
	add esi,ebx
	mov edi,[bx + COFF_DATA_VIRT]
	add edi,edx
	a32
	rep movsb

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; zero kernel .bss
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	mov ecx,[bx + COFF_BSS_SIZE]
	mov edi,[bx + COFF_BSS_VIRT]
	add edi,edx
	xor eax,eax
	push edi
		a32
		rep stosb
	pop edi

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; store machine state in kernel BSS and registers:
; BSS + 0	conventional memory size (bytes)
; BSS + 4	extended memory size (bytes)
; BSS + 8	linear address of initial RAM disk (RDSK file)
; BSS + 12	size of initial RAM disk file
; BSS + 16	kernel command line
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	mov eax,[conv_mem]	; conventional memory size
	mov [es:edi + 0],eax

	mov eax,[ext_mem]	; extended memory size
	mov [es:edi + 4],eax

	mov eax,end
	add eax,ebp
	mov [es:edi + 8],eax	; initial RAM disk address

	mov eax,[file_len]	; RDSK file length
	mov [es:edi + 12],eax

	xor eax,eax
	mov [es:edi + 16],eax	; kernel command line (xxx - implement)

	mov eax,[bx + AOUT_ENTRY_POINT]	; virtual entry point
	add eax,edx			; physical entry point

; stash the entry point. This is self-modifying code,
; but it's the only way I can see of jumping to the kernel
; with all of the data segment registers already loaded
	mov [entry + 2],eax

; interrupts off
	push dword 0
	popfd

; convert SS:SP to ESP
	xor eax,eax
	mov ax,ss
	shl eax,4
	xor ebx,ebx
	mov bx,sp
	add eax,ebx
	mov esp,eax

; set PE bit
	mov ebx,cr0
	inc bx
	mov cr0,ebx

; load data segment registers
	mov eax,LINEAR_DATA_SEL
	mov ds,eax
	mov ss,eax
	mov es,eax
	mov fs,eax
	mov gs,eax
entry:
; 2-byte JMP at [entry+0]:	66 EA
; 4-byte offset at [entry+2]:	00 00 00 00
; 2-byte selector at [entry+6]:	08 00
	jmp LINEAR_CODE_SEL:dword 0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; exit to DOS with error code and message
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

die:
	mov ah,0Eh		; INT 10h: teletype output
	xor bx,bx		; video page 0
	jmp die3
die2:
	int 10h
die3:
	lodsb
	or al,al
	jne die2
	mov ax,4C00h		; DOS terminate
	int 21h

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; await keyboard controller ready
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

kbd0:
	jmp short $+2
	in al,60h
kbd:
	jmp short $+2
	in al,64h
	test al,1
	jnz kbd0
	test al,2
	jnz kbd
	ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; verify A20 is on
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

test_a20:
	push ax
	push ds
	push es
		xor ax,ax
		mov ds,ax		; DS=0
		dec ax
		mov es,ax		; ES=0FFFFh

		mov ax,[es:10h]		; read word at FFFF:0010 (1 meg)
		not ax			; 1's complement
		push word [0]		; save word at 0000:0000
			mov [0],ax	; word at 0 = ~(word at 1 meg)
			mov ax,[0]	; read it back
		pop word [0]
		cmp ax,[es:10h]		; fail if word at 0 == word at 1 meg
	pop es
	pop ds
	pop ax
	ret		; if ZF=1, the A20 gate is NOT enabled

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; handler for VCPI exceptions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	BITS 32

unhand:
	mov ax,LINEAR_DATA_SEL
	mov ds,ax
	mov byte [dword 0B8000h],'!'
	jmp $

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

page_info:
	times 1024 dd 0         ; padding to 4K boundary
	times 1024 dd 0         ; page table somewhere in here
	dd 0			; a page dir with one entry

tss:
	dw 0, 0			; back link

	dd 0			; ESP0
	dw DATA_SEL32, 0	; SS0, reserved

	dd 0			; ESP1
	dw 0, 0			; SS1, reserved

	dd 0			; ESP2
	dw 0, 0			; SS2, reserved

	dd 0			; CR3
	dd 0, 0			; EIP, EFLAGS
	dd 0, 0, 0, 0		; EAX, ECX, EDX, EBX
	dd 0, 0, 0, 0		; ESP, EBP, ESI, EDI
	dw 0, 0			; ES, reserved
	dw 0, 0			; CS, reserved
	dw 0, 0			; SS, reserved
	dw 0, 0			; DS, reserved
	dw 0, 0			; FS, reserved
	dw 0, 0			; GS, reserved
	dw 0, 0			; LDT, reserved
	dw 0, 0			; debug, IO perm. bitmap

gdt:
	dw 0			; limit 15:0
	dw 0			; base 15:0
	db 0			; base 23:16
	db 0			; type
	db 0			; limit 19:16, flags
	db 0			; base 31:24
LINEAR_CODE_SEL	equ	$-gdt
	dw 0FFFFh
	dw 0
	db 0
	db 9Ah			; present, ring 0, code, non-conforming, readable
	db 0CFh			; page-granular, 32-bit
	db 0
LINEAR_DATA_SEL	equ	$-gdt
	dw 0FFFFh
	dw 0
	db 0
	db 92h			; present, ring 0, data, expand-up, writable
	db 0CFh			; page-granular, 32-bit
	db 0
CODE_SEL32	equ	$-gdt
gdt3:
	dw 0FFFFh
	dw 0
	db 0
	db 9Ah			; present, ring 0, code, non-conforming, readable
	db 0CFh			; page-granular, 32-bit
	db 0
DATA_SEL32	equ	$-gdt
gdt4:
	dw 0FFFFh
	dw 0
	db 0
	db 92h			; present, ring 0, data, expand-up, writable
	db 0CFh			; page-granular, 32-bit
	db 0
CODE_SEL16	equ	$-gdt
gdt5:
	dw 0FFFFh
	dw 0
	db 0
	db 9Ah			; present, ring 0, code, non-conforming, readable
	db 0			; byte-granular, 16-bit
	db 0
DATA_SEL16	equ	$-gdt
gdt6:
	dw 0FFFFh
	dw 0
	db 0
	db 92h			; present, ring 0, data, expand-up, writable
	db 0			; byte-granular, 16-bit
	db 0
TSS_SEL		equ	$-gdt
gdt7:
	dw 103
	dw 0
	db 0
	db 089h			; Ring 0 available 32-bit TSS
	db 0
	db 0
VCPI_CODE_SEL	equ	$-gdt
gdt8:				; these are set by INT 67h AX=DE01h
	dd 0, 0
VCPI_DATA_SEL	equ	$-gdt
	dd 0, 0
VCPI_LINEAR_SEL	equ	$-gdt
	dd 0, 0
gdt_end:

idt:
	%rep 32
		dw unhand	; low 16 bits of ISR offset
		dw CODE_SEL32	; selector
		db 0
		db 8Eh		; present, ring 0, 32-bit intr gate
		dw 0		; high 16 bits of ISR (unhand >> 16)
	%endrep
idt_end:

gdt_ptr:
	dw gdt_end - gdt - 1	; GDT limit
	dd gdt			; linear, physical adr of GDT

idt_ptr:
	dw idt_end - idt - 1	; IDT limit
	dd idt			; linear, physical address of IDT

real_idt_ptr:
	dw 3FFh			; limit 1023
	dd 0			; IDT (IVT, actually) at address 0

real_mode_ip:
	dw pmode16_to_real
real_mode_cs:
	dw 0

vcpi_control_block:
vcpi_cr3:
	dd 0
vcpi_gdtr:
	dd gdt_ptr
vcpi_idtr:
	dd idt_ptr
;vcpi_ldtr:
	dw 0
;vcpi_tr:
	dw TSS_SEL
;vcpi_eip:
	dd vcpi_to_pmode32
;vcpi_cs:
	dw CODE_SEL32

ext_mem:
	dd 0

conv_mem:
	dd 0

file_len:
	dd 0

load_adr:
	dd 0

cpu_msg:
	db "32-bit CPU (386SX or better) required", 13, 10, 0

usage_msg:
	db "Loads and executes Mobius-format initial RAM disk"
	db 13, 10, 0

open_msg:
	db "Couldn't open file", 13, 10, 0

read_msg:
	db "Error reading file", 13, 10, 0

invalid_msg:
	db "This file is not a Mobius-format initial RAM disk", 13, 10, 0

seek_msg:
	db "Seek failed (file may be corrupt)", 13, 10, 0

mem_msg:
	db "Not enough contiguous memory to load kernel", 13, 10, 0

coff_msg:
	db "First file in this RDSK file is not a DJGPP COFF file", 13, 10, 0

a20_msg:
	db "Could not enable A20 gate", 13, 10, 0

v86_msg:
	db "CPU is in virtual 8086 mode, but no VCPI", 13, 10
	db "Are you running this code from Windows? (don't)", 13, 10, 0

vcpi_err_msg:
	db "VCPI call (INT 67h AX=DE01h) failed (?)", 13, 10, 0

success_msg:
	db "Success!", 13, 10, 0

	times 512 dw 0
stack:

end:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -