;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RDOS operating system ; Copyright (C) 2000, Leif Ekblad ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. The only exception to this rule ; is for commercial usage in embedded systems. For information on ; usage in commercial embedded systems, contact embedded@rdos.net ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; The author of this program may be contacted at leif@rdos.net ; ; BOOTPROM.ASM ; Bootloader for PROM ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NAME bootprom ;;;;;;;;; INTERNAL PROCEDURES ;;;;;;;;;;; .model Small GateSize = 16 INCLUDE ..\os.def INCLUDE ..\driver.def INCLUDE ..\os\system.def INCLUDE ..\os\system.inc DRAM_SIZE EQU 0000E0000h PROM_BASE EQU 0FFFE0000h DefaultIdtEntry MACRO dw OFFSET DefaultInt dw device_code_sel dw 8E00h dw 0 ENDM BootIdtEntry MACRO Offs dw OFFSET Offs dw device_code_sel dw 8E00h dw 0 ENDM BootExceptionOnePar MACRO Entry push bp mov bp,sp sti push eax push ebx push ds mov al,Entry ShutDownPreTask ENDM BootExceptionNoPar MACRO Entry push dword ptr 0 push bp mov bp,sp sti push eax push ebx push ds mov al,Entry ShutDownPreTask ENDM FindRam MACRO Local RamLoop Local RamNext Local RamFound mov ax,flat_sel mov ds,ax jmp RamNext RamLoop: mov eax,AllocMemSign mov [esi],eax cmp eax,[esi] je RamFound RamNext: add esi,1000h cmp esi,DRAM_SIZE jc RamLoop stc RamFound: ENDM .code .386p ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CalcCrc ; ; DESCRIPTION: Calculate CRC for one byte ; ; PARAMETERS: AX CRC ; DS:ESI Address to data ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CalcCrc Proc near push cx mov cl,[esi] inc esi xor ah,cl ; mov cx,1021h shl ax,1 jnc no_xor0 xor ax,cx no_xor0: shl ax,1 jnc no_xor1 xor ax,cx no_xor1: shl ax,1 jnc no_xor2 xor ax,cx no_xor2: shl ax,1 jnc no_xor3 xor ax,cx no_xor3: shl ax,1 jnc no_xor4 xor ax,cx no_xor4: shl ax,1 jnc no_xor5 xor ax,cx no_xor5: shl ax,1 jnc no_xor6 xor ax,cx no_xor6: shl ax,1 jnc no_xor7 xor ax,cx no_xor7: pop cx ret CalcCrc Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GetAdapter ; ; DESCRIPTION: ; ; PARAMETERS: ESI Adress to start search at ; ; RETURNS: ESI Adapter base ; ECX Size of adapter ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetAdapter Proc near push ds mov ax,flat_sel mov ds,ax GetAdapterSearch: mov eax,[esi] cmp eax,RdosSign je GetAdapterFound GetAdapterNext: add esi,1000h or esi,esi jne GetAdapterSearch stc jmp GetAdapterDone GetAdapterCorrupt: pop esi jmp GetAdapterNext GetAdapterFound: push esi xor ecx,ecx GetAdapterNextDriver: cmp [esi].sign,RdosSign jne GetAdapterCorrupt ; cmp [esi].typ,RdosEnd je GetAdapterOk mov edx,[esi].len add ecx,edx cmp ecx,1000000h jnc GetAdapterCorrupt ; xor ax,ax push ecx push esi mov ecx,edx add esi,SIZE rdos_header sub ecx,SIZE rdos_header jz GetAdapterCrcDone GetAdapterCrcLoop: call CalcCrc sub ecx,1 jnz GetAdapterCrcLoop GetAdapterCrcDone: pop esi pop ecx cmp ax,[esi].crc jne GetAdapterCorrupt ; add esi,edx jmp GetAdapterNextDriver GetAdapterOk: pop esi clc GetAdapterDone: pop ds ret GetAdapter Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: AdapterCrc ; ; DESCRIPTION: ; ; PARAMETERS: ESI Adapter base ; ECX Size of adapter ; ; RETURNS: AX Adapter CRC ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AdapterCrc Proc near push ds mov ax,flat_sel mov ds,ax xor ax,ax push ecx push esi AdapterCrcLoop: call CalcCrc sub ecx,1 jnz AdapterCrcLoop pop esi pop ecx pop ds ret AdapterCrc Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: AddAdapter ; ; DESCRIPTION: ; ; PARAMETERS: ESI Adapter base ; ECX Size of adapter ; AX Adapter CRC ; BX Current Adapter record ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AddAdapter Proc near push dx push di add ecx,SIZE rdos_header mov di,OFFSET rom_adapters mov dx,ds:rom_modules AddAdapterCheck: or dx,dx jz AddAdapterDo cmp ecx,[di].adapter_size jne AddAdapterCheckNext cmp ax,[di].adapter_crc je AddAdapterEnd AddAdapterCheckNext: dec dx add di,SIZE adapter_typ jmp AddAdapterCheck AddAdapterDo: inc ds:rom_modules mov [bx].adapter_base,esi mov [bx].adapter_size,ecx mov [bx].adapter_crc,ax add bx,SIZE adapter_typ AddAdapterEnd: pop di pop dx ret AddAdapter Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GetAllAdapters ; ; DESCRIPTION: Get all adapters ; ; PARAMETERS: ESI Adress to start search at ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetAllAdapters Proc near mov ax,system_data_sel mov ds,ax mov ds:rom_modules,0 mov bx,OFFSET rom_adapters mov esi,PROM_BASE get_adapters_loop: call GetAdapter jc get_adapters_done call AdapterCrc call AddAdapter add esi,ecx dec esi and si,0F000h add esi,1000h jmp get_adapters_loop get_adapters_done: ret GetAllAdapters Endp PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: StartShutdownDevice ; ; DESCRIPTION: Starts shutdown-device ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; StartShutDownDevice Proc near mov ax,system_data_sel mov ds,ax mov ax,flat_sel mov es,ax mov cx,ds:rom_modules mov bx,OFFSET rom_adapters or cx,cx jz StartShutDeviceEnd StartShutAdapterLoop: push bx push cx mov esi,[bx].adapter_base StartShutDeviceLoop: cmp es:[esi].typ,RdosShutDown je StartShutDeviceDo cmp es:[esi].typ,RdosEnd je StartShutNextAdapter add esi,es:[esi].len jmp StartShutDeviceLoop StartShutNextAdapter: pop cx pop bx add bx,SIZE adapter_typ loop StartShutAdapterLoop jmp StartShutDeviceEnd StartShutDeviceDo: pop cx pop bx ; push ds push es pushad push cs push OFFSET StartShutDeviceInitied mov ax,flat_sel mov ds,ax mov bx,shutdown_code_sel push bx mov ecx,[esi].len add esi,SIZE rdos_header push word ptr [esi].init_ip add esi,SIZE device_header mov ax,gdt_sel mov ds,ax dec cx mov [bx],cx mov [bx+2],esi mov ah,9Ah xchg ah,[bx+5] xor al,al mov [bx+6],ax retf StartShutDeviceInitied: mov ax,gdt_sel mov ds,ax mov bx,idt_sel mov eax,[bx+2] sub eax,OFFSET rom_idt add eax,OFFSET boot_idt mov [bx+2],eax mov al,[bx+7] xchg al,[bx+5] db 66h lidt [bx] xchg al,[bx+5] popad pop es pop ds ; StartShutDeviceEnd: ret StartShutDownDevice Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GetBootDevice ; ; DESCRIPTION: Get header of boot-device ; ; RETURNS: NC ; ESI Boot device base ; CY No boot device ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetBootDevice Proc near mov ax,system_data_sel mov ds,ax mov ax,flat_sel mov es,ax mov cx,ds:rom_modules mov bx,OFFSET rom_adapters or cx,cx jz GetBootDeviceFail GetBootAdapterLoop: push bx push cx mov esi,[bx].adapter_base GetBootDeviceLoop: cmp es:[esi].typ,RdosKernel je GetBootDeviceOk cmp es:[esi].typ,RdosEnd je GetBootNextAdapter add esi,es:[esi].len jmp GetBootDeviceLoop GetBootNextAdapter: pop cx pop bx add bx,SIZE adapter_typ loop GetBootAdapterLoop jmp GetBootDeviceFail GetBootDeviceOk: pop cx pop bx clc jmp GetBootDeviceEnd GetBootDeviceFail: stc GetBootDeviceEnd: ret GetBootDevice Endp DefaultInt: hlt rom_gdt: gdt0: dw 0 dd 0 dw 0 gdt8: dw 10h*8-1 dd 92FFF000h + OFFSET rom_idt dw 0FF00h gdt10: dw 28h-1 dd 92FFF000h + OFFSET rom_gdt dw 0FF00h gdt18: dw 0FFFFh dd 9AFFF000h dw 0FF00h gdt20: dw 0FFFFh dd 92000000h dw 8Fh rom_idt: DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry DefaultIdtEntry Boot0: BootExceptionNoPar 0 Boot1: BootExceptionNoPar 1 Boot2: BootExceptionNoPar 2 Boot3: BootExceptionNoPar 3 Boot4: BootExceptionNoPar 4 Boot5: BootExceptionNoPar 5 Boot6: BootExceptionNoPar 6 Boot7: BootExceptionNoPar 7 Boot8: BootExceptionNoPar 8 Boot9: BootExceptionNoPar 9 BootA: BootExceptionNoPar 0Ah BootB: BootExceptionOnePar 0Bh BootC: BootExceptionOnePar 0Ch BootD: BootExceptionOnePar 0Dh BootE: BootExceptionNoPar 0Eh BootF: BootExceptionNoPar 0Fh boot_idt: BootIdtEntry Boot0 BootIdtEntry Boot1 BootIdtEntry Boot2 BootIdtEntry Boot3 BootIdtEntry Boot4 BootIdtEntry Boot5 BootIdtEntry Boot6 BootIdtEntry Boot7 BootIdtEntry Boot8 BootIdtEntry Boot9 BootIdtEntry BootA BootIdtEntry BootB BootIdtEntry BootC BootIdtEntry BootD BootIdtEntry BootE BootIdtEntry BootF idt_reg: dw 10h*8-1 dd 0FFFFF000h + OFFSET rom_idt gdt_reg: dw 28h-1 dd 0FFFFF000h + OFFSET rom_gdt init: cli db 66h lgdt cs:fword ptr gdt_reg + 0F000h db 66h lidt cs:fword ptr idt_reg + 0F000h xor ax,ax lahf mov ebx,cr0 or bl,1 mov cr0,ebx db 0EAh dw OFFSET prot_init dw device_code_sel prot_init: mov ax,flat_sel mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax ; xor esi,esi FindRam mov edx,esi mov edi,esi xor esi,esi mov ax,gdt_sel mov ds,ax mov ecx,2*5 rep movs dword ptr es:[edi],[esi] mov ax,flat_sel mov ds,ax mov esi,edx mov ebx,gdt_sel add ebx,esi mov word ptr [ebx],0FFFh mov [ebx+2],esi mov byte ptr [ebx+5],92h mov word ptr [ebx+6],0 lgdt [esi+gdt_sel] ; FindRam mov ax,gdt_sel mov ds,ax mov bx,system_data_sel mov word ptr [bx],0FFFh mov [bx+2],esi mov byte ptr [bx+5],92h mov word ptr [bx+6],0 ; mov ax,system_data_sel mov ds,ax mov ds:alloc_base,esi ; mov ax,gdt_sel mov ss,ax mov sp,1000h ; call GetAllAdapters call StartShutDownDevice call GetBootDevice jnc DoBoot hlt DoBoot: mov ax,system_data_sel mov ds,ax mov ds:ram1_size,DRAM_SIZE mov ds:ram2_size,0 mov ds:rom1_base,PROM_BASE mov ds:rom1_size,-PROM_BASE mov ds:rom2_size,0 mov ds:rom_shadow,1 ; mov ax,flat_sel mov ds,ax push kernel_code mov ecx,[esi].len add esi,SIZE rdos_header push [esi].init_ip add esi,SIZE device_header mov ax,gdt_sel mov ds,ax dec cx mov bx,kernel_code mov [bx],cx mov [bx+2],esi mov ah,9Ah xchg ah,[bx+5] xor al,al mov [bx+6],ax retf END init