23 Commits
Author SHA1 Message Date
josh 872d562d6a Import backup from 2004-07-10 2017-07-25 22:23:47 -04:00
josh 0729754659 Import backup from 2004-07-09 2017-07-25 22:23:47 -04:00
josh f3fe4ef3b8 Import backup from 2004-06-16 2017-07-25 22:23:47 -04:00
josh c76725eac3 Import backup from 2004-06-12 2017-07-25 22:23:47 -04:00
josh 9a8d2c29cb Import backup from 2004-06-10 2017-07-25 22:23:47 -04:00
josh b54b8191c4 Import backup from 2004-06-09 2017-07-25 22:23:47 -04:00
josh fdf6b71a91 Import backup from 2004-06-08 2017-07-25 22:23:47 -04:00
josh 802a07ebfe Import backup from 2004-06-07 2017-07-25 22:23:46 -04:00
josh b5ba5b63fe Import backup from 2004-06-03 2017-07-25 22:23:46 -04:00
josh b4aca026d4 Import backup from 2004-06-01 2017-07-25 22:23:46 -04:00
josh 6d941b7b16 Import backup from 2004-05-23 2017-07-25 22:23:46 -04:00
josh a982312d2c Import backup from 2004-05-22 2017-07-25 22:23:46 -04:00
josh 6b6e19effd Import backup from 2004-05-21 2017-07-25 22:23:46 -04:00
josh 38f009f2ca Import backup from 2004-04-05 2017-07-25 22:23:46 -04:00
josh 6236c341dd Import backup from 2004-04-03 2017-07-25 22:23:46 -04:00
josh 7110307896 Import backup from 2004-03-15 2017-07-25 22:23:46 -04:00
josh ab576bf18f Import backup from 2004-03-12 2017-07-25 22:23:46 -04:00
josh 302538b8ff Import backup from 2004-03-10 2017-07-25 22:23:46 -04:00
josh 7f886e44e1 Import backup from 2004-03-09 2017-07-25 22:23:46 -04:00
josh 8d0e6de040 Import backup from 2004-03-08 2017-07-25 22:23:46 -04:00
josh 0b9d7fde22 Import backup from 2004-03-02 2017-07-25 22:23:46 -04:00
josh 48f4046e79 Import backup from 2004-02-13 2017-07-25 22:23:46 -04:00
josh 2cd08dee70 Import backup from 2004-02-11 2017-07-25 22:23:46 -04:00
58 changed files with 622 additions and 4539 deletions

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
# configuration file generated by Bochs
config_interface: textconfig
display_library: x
megs: 32
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000
vgaromimage: /usr/share/bochs/VGABIOS-lgpl-latest
boot: floppy
floppya: 1_44="hos.flp", status=inserted
# no floppyb
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata1: enabled=0
ata2: enabled=0
ata3: enabled=0
parport1: enabled=1, file=""
com1: enabled=1, dev=""
usb1: enabled=1, ioaddr=0xff80, irq=10
# no sb16
floppy_bootsig_check: disabled=0
vga_update_interval: 30000
keyboard_serial_delay: 20000
keyboard_paste_delay: 100000
floppy_command_delay: 50000
ips: 500000
text_snapshot_check: 0
mouse: enabled=0
private_colormap: enabled=0
i440fxsupport: enabled=0
clock: sync=none, time0=local
# no ne2k
newharddrivesupport: enabled=1
# no loader
log: -
logprefix: %t%e%d
debugger_log: -
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
pass: action=fatal
keyboard_mapping: enabled=0, map=
keyboard_type: mf
user_shortcut: keys=none
# no cmosimage
-276
View File
@@ -1,276 +0,0 @@
//Functions.c
//05/07/03 Josh Holtrop
//for HOS
//Modified: 10/30/03
//Writes a byte out to a port
inline void outportb(unsigned int port, unsigned char value) // Output a byte to a port
{
asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
};
//Writes a word out to a port
inline void outportw(unsigned int port, unsigned int value) // Output a word to a port
{
asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value));
};
//Reads a byte from a port
inline byte inportb(unsigned short port)
{
unsigned char ret_val;
asm volatile("inb %w1,%b0"
: "=a"(ret_val)
: "d"(port));
return ret_val;
};
//Enables (SeTs) Interrupt Flag on the processor
inline void enable_ints()
{
asm("sti");
};
//Disables (CLears) Interrupt Flag on the processor
inline void disable_ints()
{
asm("cli");
};
char *strcat(char *dest, char *src)
{
strcpy(dest+strlen(dest), src);
}
//converts a binary-coded-decimal byte to its decimal equivalent
inline byte bcd2byte(byte bcd)
{
return (10* ((bcd & 0xF0) >> 4)) + (bcd & 0x0F);
}
//converts a binary-coded-decimal byte to its decimal equivalent
inline byte byte2bcd(byte bite)
{
return ((bite / 10) << 4) | (bite % 10);
}
void rtrim(char *str)
{
str += strlen(str); //now points to the null character at the end of the string
str--;
for (;;)
{
if ((*str == ' ') || (*str == '\t') || (*str == '\n'))
*str-- = 0;
else
break;
}
}
char *ucase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'a') && (*str <= 'z'))
*str = (*str) - 32;
str++;
}
return ret;
}
char *lcase(char *str)
{
char *ret = str;
for (;;)
{
if (*str == 0)
break;
if ((*str >= 'A') && (*str <= 'Z'))
*str = (*str) + 32;
str++;
}
return ret;
}
//Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address
void remap_pics(int pic1, int pic2)
{
byte a1, a2;
a1 = inportb(PIC1_DATA); //0x21
a2 = inportb(PIC2_DATA); //0xA1
outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); //0x20, 0x10+0x01 00010001b
outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); //0xA0, 0x10+0x01 00010001b
outportb(PIC1_DATA, pic1); //0x21, pic1
outportb(PIC2_DATA, pic2); //0xA1, pic2
outportb(PIC1_DATA, 4); //0x21, 0x04 00000100b
outportb(PIC2_DATA, 2); //0xA1, 0x02 00000010b
outportb(PIC1_DATA, ICW4_8086); //0x21, 0x01 00000001b
outportb(PIC2_DATA, ICW4_8086); //0xA1, 0x01 00000001b
outportb(PIC1_DATA, a1); //0x21
outportb(PIC2_DATA, a2); //0xA1
}
//Masks interrupts on first Programmable Interrupt Controller
inline void pic1_mask(byte mask)
{
outportb(PIC1_DATA, mask); //0x21, maskfield *OCW1*
}
//Masks interrupts on second Programmable Interrupt Controller
inline void pic2_mask(byte mask)
{
outportb(PIC2_DATA, mask); //0xA1, maskfield *OCW1*
}
//Restarts the computer
inline void restart()
{
enable_ints();
byte temp;
do
{
temp = inportb(0x64);
if (temp & 1)
inportb(0x60);
} while(temp & 2);
outportb (0x64, 0xfe);
for (;;)
{
}
}
//Halts (freezes) the computer
inline void halt()
{
asm("cli");
asm("hlt");
while (1)
;
}
//Initializes 8253 Programmable Interrupt Timer
inline void init_timer()
{
//set timer : 2e9c = 100hz
outportb(0x43, 0x34);
outportb(0x40, 0x9c); //lsb
outportb(0x40, 0x2e); //msb
}
//Signals an End Of Interrupt signal to the first PIC
inline void eoi()
{
outportb(0x20, 0x20);
}
//Signals an End Of Interrupt signal to both the second and first PIC unit
inline void eoi2()
{
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
//Returns the size of the kernel (code & data)
// - this does not include the bss section
// - this should be 4kb aligned per the linker script
// - this should be the size of kernel.bin
inline dword kernel_size()
{
return (dword)(&_bss)-(dword)(&_code);
}
//These functions are for reading and writing various values stored on the CMOS Real Time Clock
byte rtc_readDay()
{
outportb(0x70, 7);
return bcd2byte(inportb(0x71));
}
byte rtc_readMonth()
{
outportb(0x70, 8);
return bcd2byte(inportb(0x71));
}
byte rtc_readYear()
{
outportb(0x70, 9);
return bcd2byte(inportb(0x71));
}
byte rtc_readSecond()
{
outportb(0x70, 0);
return bcd2byte(inportb(0x71));
}
byte rtc_readMinute()
{
outportb(0x70, 2);
return bcd2byte(inportb(0x71));
}
byte rtc_readHour()
{
outportb(0x70, 4);
return bcd2byte(inportb(0x71));
}
void rtc_setDay(byte day)
{
outportb(0x70, 7);
outportb(0x71, byte2bcd(day));
}
void rtc_setMonth(byte month)
{
outportb(0x70, 8);
outportb(0x71, byte2bcd(month));
}
void rtc_setYear(byte year)
{
outportb(0x70, 9);
outportb(0x71, byte2bcd(year));
}
void rtc_setSecond(byte second)
{
outportb(0x70, 0);
outportb(0x71, byte2bcd(second));
}
void rtc_setMinute(byte minute)
{
outportb(0x70, 2);
outportb(0x71, byte2bcd(minute));
}
void rtc_setHour(byte hour)
{
outportb(0x70, 4);
outportb(0x71, byte2bcd(hour));
}
+48
View File
@@ -0,0 +1,48 @@
# Makefile for HOS
# Josh Holtrop
# Created: 07/09/04
FLOPPY=/dev/fd0
FLOPPY_MOUNT=./mnt_flp
FLOPPY_IMAGE=hos.flp
GRUB_IMAGE=grub.flp
all:
make -C kernel
# make -C rmmod
clean:
make -C kernel clean
make -C include clean
# make -C rmmod clean
- rm *~ hos.flp
grub:
- mkdir $(FLOPPY_MOUNT)
mke2fs $(FLOPPY)
mount -t ext2 $(FLOPPY) $(FLOPPY_MOUNT)
grub-install --root-directory=$(FLOPPY_MOUNT) fd0
umount $(FLOPPY_MOUNT)
- rmdir $(FLOPPY_MOUNT)
grub_image:
dd if=$(FLOPPY) of=$(GRUB_IMAGE)
install:
- mkdir $(FLOPPY_MOUNT)
mount -t ext2 $(FLOPPY) $(FLOPPY_MOUNT)
cp kernel/kernel.bin $(FLOPPY_MOUNT)
cp menu.lst $(FLOPPY_MOUNT)/boot/grub
umount $(FLOPPY_MOUNT)
- rmdir $(FLOPPY_MOUNT)
install_img:
- mkdir $(FLOPPY_MOUNT)
cp grub.flp $(FLOPPY_IMAGE)
mount -t ext2 -o loop $(FLOPPY_IMAGE) $(FLOPPY_MOUNT)
cp kernel/kernel.bin $(FLOPPY_MOUNT)
cp menu.lst $(FLOPPY_MOUNT)/boot/grub
umount $(FLOPPY_MOUNT)
- rmdir $(FLOPPY_MOUNT)
-470
View File
@@ -1,470 +0,0 @@
; asmfuncs.asm
; Josh Holtrop
; Created: 10/23/03
; Modified: 12/25/03
[extern _putc]
[extern _console_memory]
[extern _cursorPosition]
[extern _video_drawConsole]
[extern _videoMode]
%macro jzfar 1
jnz %%skip
jmp %1
%%skip:
%endmacro
;stores the parameter to the CR0 register
;extern dword write_cr0(dword cr0);
[global _write_cr0]
_write_cr0:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr0, eax
pop ebp
ret
;returns the value in the CR0 register
;extern dword read_cr0();
[global _read_cr0]
_read_cr0:
mov eax, cr0;
ret
;stores the parameter to the CR3 register
;extern dword write_cr3(dword cr3);
[global _write_cr3]
_write_cr3:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr3, eax
pop ebp
ret
;returns the value in the CR2 register
;extern dword read_cr2();
[global _read_cr2]
_read_cr2:
mov eax, cr2;
ret
;returns the value in the CR3 register
;extern dword read_cr3();
[global _read_cr3]
_read_cr3:
mov eax, cr3;
ret
;compares one string to another
;returns 0 if the strings are different
;extern dword strcmp(char *str1, char *str2);
[global _strcmp]
_strcmp:
push ebp
mov ebp, esp
push esi
push edi
mov esi, [ebp+8]
mov edi, [ebp+12]
strcmp_loop1:
lodsb
mov ah, [edi]
inc edi
cmp ah, al
jnz strcmp_ne
or al, al
jz strcmp_e
jmp strcmp_loop1
strcmp_e:
mov eax, 1
jmp short strcmp_done
strcmp_ne:
xor eax, eax
strcmp_done:
pop edi
pop esi
pop ebp
ret
;copies a string from the source to the destination parameter
;extern void strcpy(char *dest, char *src);
[global _strcpy]
_strcpy:
push ebp
mov ebp, esp
push esi
push edi
mov edi, [ebp+8]
mov esi, [ebp+12]
strcpyloop:
lodsb
stosb
or al, al
jnz strcpyloop
pop edi
pop esi
pop ebp
ret
;copies memory of n bytes from src to destination
;extern void memcpy(dword dest, dword src, dword n);
[global _memcpy]
_memcpy:
push ebp
mov ebp, esp
push esi
push edi
push ecx
mov edi, [ebp+8]
mov esi, [ebp+12]
mov ecx, [ebp+16]
rep movsb
pop ecx
pop edi
pop esi
pop ebp
ret
;returns the number of characters in a string
;extern dword strlen(char *str);
[global _strlen]
_strlen:
push ebp
mov ebp, esp
push esi
push ebx
mov esi, [ebp+8]
xor ebx, ebx
strlenloop:
lodsb
or al, al
jz strlendone
inc ebx
jmp strlenloop
strlendone:
mov eax, ebx
pop ebx
pop esi
pop ebp
ret
;this function invalidates the page directory/table entry that
; would be used to access the memory address given in the parameter
;extern void invlpg(dword addr);
[global _invlpg]
_invlpg:
mov eax, [esp+4]
invlpg [eax]
ret
;
;void writeCursorPosition(word pos)
;
[global _writeCursorPosition]
_writeCursorPosition:
push ebp
mov ebp, esp
push eax
push ebx
push edx
mov eax, [ebp+8] ;cursor position in ax
mov bl, al
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
mov al, ah
out dx, al
dec dx
mov al, 0x0F
out dx, al
inc dx
mov al, bl
out dx, al
pop edx
pop ebx
pop eax
pop ebp
ret
;
;word getCursorPosition()
;
[global _getCursorPosition]
_getCursorPosition:
push ebx
push edx
xor eax, eax
mov dx, 0x03D4
mov al, 0x0E
out dx, al
inc dx
in al, dx
mov bl, al
dec dx
mov al, 0x0F
out dx, al
inc dx
in al, dx
mov ah, bl
pop edx
pop ebx
ret
;
;void console_scroll()
;
[global _console_scroll]
_console_scroll:
pusha
mov esi, _console_memory+160
mov edi, _console_memory
mov ecx, 960 ;(2000-80)/2
rep movsd
mov ax, 0x0720
mov ecx, 80
rep stosw
mov esi, _console_memory
mov edi, 0xC00B8000
mov ecx, 1000
rep movsd
mov eax, [_videoMode]
cmp eax, 0
jz _console_scroll_end
call _video_drawConsole
_console_scroll_end:
popa
ret
;
;void console_cls()
;
[global _console_cls]
_console_cls:
pusha
mov edi, _console_memory
mov ax, 0x0720
mov ecx, 2000
rep stosw
push dword 0
call _writeCursorPosition
add esp, 4
mov [_cursorPosition], dword 0
mov esi, _console_memory
mov edi, 0xC00B8000
mov ecx, 1000
rep movsd
popa
ret
;
;int puts(char *str)
;
[global _puts]
_puts:
push ebp
mov ebp, esp
push esi
push eax
mov esi, [ebp+8] ;esi = to string
puts_loop:
lodsb
cmp al, 0
jz puts_done
push eax
call _putc
add esp, 4
jmp puts_loop
puts_done:
pop eax
pop esi
pop ebp
ret
[global _putDecu]
_putDecu:
push ebp
mov ebp, esp
sub esp, 24
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L2:
mov edx, DWORD [ebp+8]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
cmp eax, DWORD [ebp-4]
jae L4
jmp L3
L4:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L2
L3:
nop
L5:
cmp DWORD [ebp-4], 1
ja L7
jmp L6
L7:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L5
L6:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
[global _putDec]
_putDec:
push ebp
mov ebp, esp
sub esp, 24
cmp DWORD [ebp+8], 0
jns L9
sub esp, 12
push 45
call _putc
add esp, 16
neg DWORD [ebp+8]
L9:
mov DWORD [ebp-4], 1
mov BYTE [ebp-5], 0
L10:
mov eax, DWORD [ebp+8]
cmp eax, DWORD [ebp-4]
jae L12
jmp L11
L12:
mov eax, DWORD [ebp-4]
mov edx, eax
sal edx, 2
add edx, eax
lea eax, [edx+edx]
mov DWORD [ebp-4], eax
jmp L10
L11:
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
L13:
cmp DWORD [ebp-4], 1
ja L15
jmp L14
L15:
mov edx, DWORD [ebp+8]
mov eax, edx
mov edx, 0
div DWORD [ebp-4]
mov DWORD [ebp-12], eax
mov al, BYTE [ebp-12]
mov BYTE [ebp-5], al
mov eax, 0
mov al, BYTE [ebp-5]
imul eax, DWORD [ebp-4]
sub DWORD [ebp+8], eax
mov edx, DWORD [ebp-4]
mov eax, -858993459
mul edx
mov eax, edx
shr eax, 3
mov DWORD [ebp-4], eax
lea eax, [ebp-5]
add BYTE [eax], 48
sub esp, 12
mov eax, 0
mov al, BYTE [ebp-5]
push eax
call _putc
add esp, 16
jmp L13
L14:
sub esp, 12
mov al, BYTE [ebp+8]
add eax, 48
and eax, 255
push eax
call _putc
add esp, 16
leave
ret
-12
View File
@@ -1,12 +0,0 @@
@echo off
echo Backing up to .\Backup\%1
mkdir .\Backup\%1
copy *.h .\Backup\%1
copy *.c .\Backup\%1
copy *.inc .\Backup\%1
copy *.asm .\Backup\%1
copy *.ld .\Backup\%1
copy *.bat .\Backup\%1
-26
View File
@@ -1,26 +0,0 @@
%define VERSION "0.13" ;HOS version
%define BOOT_FAT_SEG 0x07E0 ;right after boot sector
%define BOOT_ROOT_SEG 0x0900 ;right after FAT
%define BOOT_KERNEL_SEG 0x0AC0 ;right after ROOT_DIR
%define BOOT_STAGE2_SEG 0x0B00 ;right after KERNEL_SEG
%define BOOT_STAGE2_ADD 0xB000 ;address of stage2 to jump to, org at
%define BOOT_KERNEL_ADD 0x106000 ;final pmode kernel destination - physical
%define BOOT_RD_ADD 0x200000 ;2mb for ram disk
%define BOOT_DATA_SEG 0x9000 ;data gathered by stage2 loader goes here
%define BOOT_HASRD 0x0000 ;1
%define BOOT_VESA 0x0002 ;2 - 0 for console, otherwise VESA mode
%define BOOT_VESA_OEM 0x0004 ;258 - null-terminated OEM identification string
%define BOOT_VESA_VBE 0x0106 ;512 - copy of VESA VBEInfoBlock
%define BOOT_VESA_INFO 0x0306 ;256 - copy of VESA ModeInfoBlock for selected mode
%define BOOT_MEMENTRIES 0x040A ;4 - dword = number of memmap entries
%define BOOT_MEMMAP 0x2000 ;? - memory map information
%define BOOT_DRIVE 0x7C24 ;1 - boot drive
-2
View File
@@ -1,2 +0,0 @@
nasmw -f aout -o ks.o -l .\lst\kernel.lst kernel.asm
-1
View File
@@ -1 +0,0 @@
gcc -ffreestanding -fno-builtin -nostdlib -nodefaultlibs -c kernel.c -o kernel.o
-1
View File
@@ -1 +0,0 @@
nasmw -f aout -o asmfuncs.o -l .\lst\asmfuncs.lst asmfuncs.asm
-1
View File
@@ -1 +0,0 @@
copy kernel.bin a:
-2
View File
@@ -1,2 +0,0 @@
rem rawrite -f stage1.bin -d a -n
partcopy stage1.bin 0 200 -f0
-1
View File
@@ -1 +0,0 @@
copy stage2.bin a:
-1
View File
@@ -1 +0,0 @@
nasmw -f bin -o stage1.bin -l .\lst\stage1.lst stage1.asm
-1
View File
@@ -1 +0,0 @@
nasmw -f bin -o stage2.bin -l .\lst\stage2.lst stage2.asm
-345
View File
@@ -1,345 +0,0 @@
// fat12.c
// Author: Josh Holtrop
// Created: 01/04/04
// Modified: 01/14/04
byte *fat12_readFile(char *fileName, DiskDevice *dd)
{
char *fileNameUCase = malloc(strlen(fileName) + 1);
strcpy(fileNameUCase, fileName);
ucase(fileNameUCase);
dword iMadeClusterChain = getClusterChain(dd);
Fat12Entry fe;
if (fat12_getFileHandle(fileNameUCase, dd, &fe))
{
free(fileNameUCase);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 0;
}
byte *fp = (byte *)fat12_readClusterChain(dd, &fe);
free(fileNameUCase);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return fp;
}
dword fat12_getFileHandle(char *fileName, DiskDevice *dd, Fat12Entry *destination)
{
if (strlen(fileName) < 1)
return 1;
if (fileName[strlen(fileName)-1] == '/')
return 2;
dword iMadeClusterChain = getClusterChain(dd);
int fileName_length = strlen(fileName);
int a;
int entries = 1;
for (a = 0; a < fileName_length; a++)
{
if (fileName[a] == '/')
{
fileName[a] = 0;
entries++;
}
}
char *pointer = fileName;
Fat12Entry *workingDirectory = 0;
Fat12Entry workingDir;
for (a = 0; a < (entries - 1); a++)
{
if (fat12_getDirectoryHandle(pointer, dd, workingDirectory, &workingDir)) //an error occurred if this returns nonzero
{
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 3;
}
workingDirectory = &workingDir;
for (;;) //advance to the next dir name
{
pointer++;
if (*pointer == 0)
{
pointer++;
break;
}
}
}
if (fat12_getFileHandleInDirectory(pointer, dd, workingDirectory, destination)) //an error occurred if this returns nonzero
{
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 4;
}
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return 0;
}
dword fat12_getFileHandleInDirectory(char *fileName, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination)
{
if (!currDir) // we are working in the root directory
{
Fat12Entry *rootDir = malloc(14*512); //root directory is 14 sectors long
vfs_readSector(dd, 19, (byte *)rootDir, 14);
int a;
for (a = 0; a < 224; a++) //224 max root directory entries in 14 sectors
{
if (rootDir[a].fileName[0] == 0)
break;
if ((byte)rootDir[a].fileName[0] != 0xE5)
{
if ((rootDir[a].attributes & 0x18) == 0) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, rootDir[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, rootDir[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, fileName)) //the entry found is a match
{
free(rootDir);
*destination = rootDir[a];
return 0;
}
}
}
}
free(rootDir);
return 1; //no match found
}
dword retVal = 2;
dword iMadeClusterChain = getClusterChain(dd);
Fat12Entry *subDirectory = fat12_readClusterChain(dd, currDir);
if (!subDirectory)
return 5;
dword numberOfClusters = fat12_readClusterChainCount(dd, currDir);
int a;
for (a = 0; a < (numberOfClusters * 16); a++)
{
if (subDirectory[a].fileName[0] == 0)
break;
if ((byte)subDirectory[a].fileName[0] != 0xE5)
{
if ((subDirectory[a].attributes & 0x18) == 0) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, subDirectory[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, subDirectory[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, fileName)) //the entry found is a match
{
*destination = subDirectory[a];
retVal = 0;
break;
}
}
}
}
free(subDirectory);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return retVal;
}
dword fat12_getDirectoryHandle(char *directory, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination)
{
if (!currDir) // we are working in the root directory
{
Fat12Entry *rootDir = malloc(14*512); //root directory is 14 sectors long
vfs_readSector(dd, 19, (byte *)rootDir, 14);
int a;
for (a = 0; a < 224; a++) //224 max root directory entries in 14 sectors
{
if (rootDir[a].fileName[0] == 0)
break;
if ((byte)rootDir[a].fileName[0] != 0xE5)
{
if ((rootDir[a].attributes & 0x18) == 0x10) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, rootDir[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, rootDir[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, directory)) //the entry found is a match
{
free(rootDir);
*destination = rootDir[a];
return 0;
}
}
}
}
free(rootDir);
return 1; //no match found
}
dword retVal = 2;
dword iMadeClusterChain = getClusterChain(dd);
Fat12Entry *subDirectory = fat12_readClusterChain(dd, currDir);
if (!subDirectory)
return 5;
dword numberOfClusters = fat12_readClusterChainCount(dd, currDir);
int a;
for (a = 0; a < (numberOfClusters * 16); a++)
{
if (subDirectory[a].fileName[0] == 0)
break;
if ((byte)subDirectory[a].fileName[0] != 0xE5)
{
if ((subDirectory[a].attributes & 0x18) == 0x10) //this entry is a directory
{
char dirName[9];
char dirExt[4];
memcpy(dirName, subDirectory[a].fileName, 8);
dirName[8] = 0;
memcpy(dirExt, subDirectory[a].ext, 3);
dirExt[3] = 0;
rtrim(dirName);
rtrim(dirExt);
char dirWhole[14];
strcpy(dirWhole, dirName);
if (strlen(dirExt) > 0) //the directory has an extension
{
strcat(dirWhole, ".");
strcat(dirWhole, dirExt);
}
if (strcmp(dirWhole, directory)) //the entry found is a match
{
*destination = subDirectory[a];
retVal = 0;
break;
}
}
}
}
free(subDirectory);
if (iMadeClusterChain)
{
free(clusterChain);
clusterChain = 0;
}
return retVal;
}
Fat12Entry *fat12_readClusterChain(DiskDevice *dd, Fat12Entry *directory)
{
dword numberOfClusters = fat12_readClusterChainCount(dd, directory);
if (numberOfClusters == 0)
return 0;
byte *bp = malloc(numberOfClusters * 512);
Fat12Entry *retVal = (Fat12Entry *)bp;
dword cluster = directory->firstCluster;
while (cluster < 0xFF0)
{
vfs_readSector(dd, cluster + 31, bp, 1);
cluster = fat12_getNextCluster(cluster);
bp += 512;
}
return retVal;
}
dword fat12_readClusterChainCount(DiskDevice *dd, Fat12Entry *directory)
{
dword numberOfClusters = 0;
dword cluster = directory->firstCluster;
if (cluster == 0)
return 0;
while (cluster < 0xFF0)
{
cluster = fat12_getNextCluster(cluster);
numberOfClusters++;
}
return numberOfClusters;
}
dword fat12_getNextCluster(dword thisCluster)
{
dword nextCluster = *(word *)((dword)clusterChain + ((thisCluster * 3) >> 1));
if (thisCluster & 0x01) //this is an odd cluster
return nextCluster >> 4;
else //this is an even cluster
return nextCluster & 0x0FFF;
}
dword fat12_getFileSize(char *fileName, DiskDevice *dd)
{
Fat12Entry fe;
if (fat12_getFileHandle(fileName, dd, &fe))
return 0xFFFFFFFF;
return fe.fileSize;
}
dword getClusterChain(DiskDevice *dd)
{
if (!clusterChain)
{
clusterChain = malloc(9*512); //9 sectors for File Allocation Table (cluster chain)
vfs_readSector(dd, 1, clusterChain, 9); //sectors 1 through 9 contain the first FAT
return 1; //this call created the cluster chain
}
else
return 0; //this call did not create the cluster chain
}
-58
View File
@@ -1,58 +0,0 @@
// fat12.h
// Author: Josh Holtrop
// Created: 01/04/04
typedef struct {
char fileName[8];
char ext[3];
byte attributes;
dword createTime;
word createDate;
word accessDate;
word unused0;
word modifiedDate;
word modifiedTime;
word firstCluster;
dword fileSize;
} __attribute__((packed)) Fat12Entry;
typedef struct {
byte jump[3];
byte sysName[8];
word bytesPerSector;
byte sectorsPerCluster;
word reservedSectors;
byte FATcount;
word maxRootEntries;
word totalSectors1;
byte mediaDescriptor;
word sectorsPerFAT;
word sectorsPerTrack;
word headCount;
dword hiddenSectors;
dword totalSectors2;
byte driveNumber;
byte reserved1;
byte extBootSignature;
dword volumeSerial;
char volumeLabel[11];
char fileSystemID[8];
} __attribute__((packed)) Fat12BootSector;
byte *fat12_readFile(char *fileName, DiskDevice *dd);
dword fat12_getFileHandle(char *fileName, DiskDevice *dd, Fat12Entry *destination);
dword fat12_getDirectoryHandle(char *directory, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination);
Fat12Entry *fat12_readClusterChain(DiskDevice *dd, Fat12Entry *directory);
dword fat12_getFileHandleInDirectory(char *fileName, DiskDevice *dd, Fat12Entry *currDir, Fat12Entry *destination);
dword fat12_readClusterChainCount(DiskDevice *dd, Fat12Entry *directory);
dword fat12_getFileSize(char *fileName, DiskDevice *dd);
dword getClusterChain(DiskDevice *dd);
dword fat12_getNextCluster(dword thisCluster);
byte *clusterChain = 0;
-9
View File
@@ -1,9 +0,0 @@
//fdc.c
//Author: Josh Holtrop
//Date: 10/30/03
inline void fdc_sendDOR(byte dor)
{
outportb(FDC_DOR, dor);
}
-12
View File
@@ -1,12 +0,0 @@
//fdc.h
//Author: Josh Holtrop
//Date: 10/30/03
#define FDC_DOR 0x3f2
#define FDC_MSR 0x3f4
inline void fdc_sendDOR(byte dor);
-46
View File
@@ -1,46 +0,0 @@
//functions.h
//05/07/03 Josh Holtrop
//for HOS
//Modified: 10/30/03
extern dword _code;
extern dword _bss;
extern dword _end;
inline void outportb(unsigned int port, unsigned char value);
inline void outportw(unsigned int port, unsigned int value);
inline byte inportb(unsigned short port);
inline void enable_ints();
inline void disable_ints();
inline void restart();
inline void halt();
void remap_pics(int pic1, int pic2);
inline void pic1_mask(byte mask);
inline void pic2_mask(byte mask);
inline void eoi();
inline void eoi2();
inline dword kernel_size();
inline void init_timer();
char *strcat(char *dest, char *src);
void rtrim(char *str);
char *ucase(char *str);
char *lcase(char *str);
inline byte bcd2byte(byte bcd);
inline byte byte2bcd(byte bite);
byte rtc_readDay();
byte rtc_readMonth();
byte rtc_readYear();
byte rtc_readSecond();
byte rtc_readMinute();
byte rtc_readHour();
void rtc_setDay(byte dat);
void rtc_setMonth(byte month);
void rtc_setYear(byte year);
void rtc_setSecond(byte second);
void rtc_setMinute(byte minute);
void rtc_setHour(byte hour);
-1
View File
@@ -1 +0,0 @@
gcc -S kernel.c -masm=intel -fno-builtin
-1
View File
@@ -1 +0,0 @@
partcopy -f0 0 168000 flop.img
BIN
View File
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
clean:
- rm *~
+23
View File
@@ -0,0 +1,23 @@
#ifndef __HOS_KERNEL_H__
#define __HOS_KERNEL_H__ __HOS_KERNEL_H__
#include "multiboot.h"
#define VIRT_OFFSET 0xC0000000
#define MAX_MODULES 16
#define MAX_MMAP 16
typedef unsigned int u32_t;
typedef unsigned short u16_t;
typedef unsigned char u8_t;
/* returns true to callee if we should jump to a real mode module */
int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic);
void k_init();
void isr();
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef __HOS_MODULE_H__
#define __HOS_MODULE_H__ __HOS_MODULE_H__
#define MOD_REAL_MODE 1
#define MOD_KERNEL 2
typedef struct {
unsigned int mod_magic; // "HOSM" = 0x484F534D
unsigned int mod_type; // module type
void (*init) (); // address of void initialization function
unsigned int reserved;
} hos_module_header_t;
#endif
+144
View File
@@ -0,0 +1,144 @@
#ifndef __HOS_MULTIBOOT_H__
#define __HOS_MULTIBOOT_H__ __HOS_MULTIBOOT_H__
/* The magic number for the Multiboot header. */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MB_HEADER_ALIGN_MODULES 0x01
#define MB_HEADER_MEM_INFO 0x02
#define MB_HEADER_VIDEO_INFO 0x04
#define MB_HEADER_KLUDGE_OFFSETS 0x10000
/* The magic number passed by a Multiboot-compliant boot loader. */
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
#define MB_BOOTLOADER_MEM_INFO 0x01
#define MB_BOOTLOADER_BOOT_DEVICE 0x02
#define MB_BOOTLOADER_COMMAND_LINE 0x04
#define MB_BOOTLOADER_MODS 0x08
#define MB_BOOTLOADER_AOUT 0x10
#define MB_BOOTLOADER_ELF 0x20
#define MB_BOOTLOADER_MMAP 0x40
#define MB_BOOTLOADER_DRIVES 0x80
#define MB_BOOTLOADER_CONFIG 0x0100
#define MB_BOOTLOADER_APM 0x0200
#define MB_BOOTLOADER_GRAPHICS 0x0400
#define MB_DRIVE_MODE_CHS 0
#define MB_DRIVE_MODE_LBA 1
/* The Multiboot header. */
typedef struct
{
unsigned int magic;
unsigned int flags;
unsigned int checksum;
unsigned int header_addr;
unsigned int load_addr;
unsigned int load_end_addr;
unsigned int bss_end_addr;
unsigned int entry_addr;
} mb_header_t;
/* The symbol table for a.out. */
typedef struct
{
unsigned int tabsize;
unsigned int strsize;
unsigned int addr;
unsigned int reserved;
} mb_aout_symbol_table_t;
/* The section header table for ELF. */
typedef struct
{
unsigned int num;
unsigned int size;
unsigned int addr;
unsigned int shndx;
} mb_elf_section_header_table_t;
/* The Multiboot information. */
typedef struct
{
unsigned int flags;
unsigned int mem_lower; // present if flags[0] is set
unsigned int mem_upper;
unsigned int boot_device; // 1
unsigned int cmdline; // 2
unsigned int mods_count; // 3
unsigned int mods_addr;
union
{
mb_aout_symbol_table_t aout_sym; // 4
mb_elf_section_header_table_t elf_sec; // 5
};
unsigned int mmap_length; // 6
unsigned int mmap_addr;
unsigned int drives_length; // 7
unsigned int drives_addr;
unsigned int config_table; // 8
unsigned int bootloader_name; // 9
unsigned int apm_table; // 10
unsigned int vbe_control_info; // 11
unsigned int vbe_mode_info;
unsigned short vbe_mode;
unsigned short vbe_interface_seg;
unsigned short vbe_interface_off;
unsigned short vbe_interface_len;
} mb_info_t;
/* The module structure. */
typedef struct
{
unsigned int mod_start;
unsigned int mod_end;
unsigned int string;
unsigned int reserved;
} mb_module_t;
/* The memory map. Be careful that the offset 0 is base_addr_low, not size. */
typedef struct
{
unsigned int size; //offset -4
unsigned int base_addr_low; //offset 0
unsigned int base_addr_high;
unsigned int length_low;
unsigned int length_high;
unsigned int type;
} mb_mmap_t;
/* The drive structure */
typedef struct
{
unsigned int size;
unsigned char drive_number;
unsigned char drive_mode;
unsigned char drive_cylinders;
unsigned char drive_heads;
unsigned char drive_sectors;
unsigned short drive_ports[1];
} mb_drive_t;
/* APM table structure */
typedef struct
{
unsigned short version;
unsigned short cseg;
unsigned int offset;
unsigned short cseg_16;
unsigned short dseg;
unsigned short flags;
unsigned short cseg_len;
unsigned short cseg_16_len;
unsigned short dseg_len;
} mb_apm_t;
#endif
-51
View File
@@ -1,51 +0,0 @@
//k_defines.h
//03/17/03 Josh Holtrop
//Modified: 10/30/03
#define PIC1 0x20
#define PIC2 0xA0
#define PIC1_COMMAND PIC1
#define PIC1_DATA (PIC1+1)
#define PIC2_COMMAND PIC2
#define PIC2_DATA (PIC2+1)
#define PIC_EOI 0x20
#define ICW1_ICW4 0x01 /* ICW4 (not) needed */
#define ICW1_SINGLE 0x02 /* Single (cascade) mode */
#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */
#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */
#define ICW1_INIT 0x10 /* Initialization - required! */
#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */
#define ICW4_AUTO 0x02 /* Auto (normal) EOI */
#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
#define BLUE_TXT 0x01
#define RED_TXT 0x04
#define WHITE_TXT 0x07
#define CYAN_TXT 0x0B
#define YELLOW_TXT 0x0E
#define BRWHITE_TXT 0x0F
#define FREERAM_START 0x368000 // 0x368000 is first available byte (this is right after the initrd @ 2mb, 1440kb.
#define MAX_RAM 0x40000000 //1gb maximum RAM supported
#define PID_KERNEL 0x02 //kernel's PID
#define PID_VMM 0x03
#define PID_USER 0x10000 //user processes' start PID
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;
typedef struct {
dword lowdword;
dword highdword;
} __attribute__((packed)) qword;
-101
View File
@@ -1,101 +0,0 @@
;kernel.asm
;Author: Josh Holtrop
;Modified: 10/30/03
%define GDT_P 0x100000; ;1mb physical - Global Descriptor Table space
%define GDT_V GDT_P+0xC0000000
%define IDT_P 0x102000 ;1mb+8kb - Interrupt Descriptor Table space
%define IDT_V IDT_P+0xC0000000
%define PDBR_P 0x104000 ;1mb+16kb - Page Directory Base Register (first PD)
%define PDBR_V PDBR_P+0xC0000000
%define LOPT_P 0x105000 ;1mb+20kb - LOw Page Table for mapping first 4mb
%define LOPT_V LOPT_P+0xC0000000
%define KERNEL_P 0x106000 ;1mb+24kb - the kernel's physical address
%define KERNEL_V KERNEL_P+0xC0000000 ;3gb+1mb+24kb, the virtual address of the kernel
[global start]
[extern _isr]
[extern _k_init]
[extern _putc]
bits 32
;This is where the kernel begins execution
;At this point, the temporary gdt is set up to "map" 0xC000_0000 to 0x0.
;We must enable paging with the first 4mb mapped 1:1 virtual:physical
; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical.
;Then we can start using our "real" gdt, then unmap the lower 4mb.
start:
cli ;if they weren't already off
xor eax, eax
mov edi, PDBR_V
mov ecx, 1024 ;clear the PDBR
rep stosd
mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table (read/write, present)
mov edi, LOPT_V
mov ecx, 1024
mov eax, 0x03 ;starting physical address = 0x0 (read/write, present flags)
fill_lopt_loop: ;fill the page table
stosd
add eax, 4096 ;increment next phsyical address by 4kb
loop fill_lopt_loop
mov eax, PDBR_P
mov cr3, eax ;store the Page Directory Base Address
mov eax, cr0
or eax, 0x80000000 ;set page enable bit
mov cr0, eax ;now paging is active!
mov edi, GDT_V
mov esi, gdt
mov ecx, gdt_end-gdt
copy_gdt:
lodsb
stosb
loop copy_gdt
mov edi, IDT_V ;destination
mov esi, isr_0 ;address of isr0
mov edx, isr_1-isr_0 ;distance between isr labels
mov ecx, 50 ;number of isrlabels
fill_idt:
mov ebx, esi
mov ax, si
stosw ;0 offset 15:0
mov ax, KERNEL_CODE
stosw ;2 selector 15:0
mov ax, 0x8E00
stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0]
shr esi, 16
mov ax, si
stosw ;6 offset 31:16
mov esi, ebx
add esi, edx
loop fill_idt
mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
lgdt [gdtr] ;load gdt
jmp KERNEL_CODE:newgdtcontinue
newgdtcontinue:
mov ax, KERNEL_DATA
mov es, ax
mov ds, ax
mov gs, ax
mov fs, ax
mov ss, ax
mov esp, 0xc01ffffc ;stack just under 3gb+2mb, moves downward
lidt [idtr] ;load idt
call _k_init
haltit:
hlt ;halt processor when k_init is done
jmp haltit ;shouldn't get here...
%include "gdt.inc"
%include "idt.inc"
-144
View File
@@ -1,144 +0,0 @@
//kernel.c
//08/13/03 Josh Holtrop
//Holtrop's Operating System
//Version: 0.12
//Modified: 12/30/03
#include "k_defines.h" //#DEFINE's for kernel
#include "functions.h" //general functions
#include "video.h" //video functions
#include "mm.h" //physical memory management functions
#include "vmm.h" //virtual memory management & paging functions
#include "keyboard.h" //generic keyboard driver & functions
#include "mouse.h" //generic ps/2 mouse driver & functions
#include "fdc.h" //Floppy Disk Controller functions
#include "stdfont.h" //Standard font bitmask array
#include "kio.h"
#include "vfs.h"
#include "rd.h"
#include "fat12.h"
void isr(dword num);
void k_init();
/* These functions are defined in asmfuncs.asm */
extern dword write_cr0(dword cr0);
extern dword read_cr0();
extern dword write_cr3(dword cr3);
extern dword read_cr2();
extern dword read_cr3();
extern void writeCursorPosition(dword pos);
extern dword getCursorPosition();
extern void console_scroll();
extern void console_cls();
extern int puts(char *str);
extern int putDec(int number);
extern int putDecu(dword number);
extern void strcpy(char *dest, char *src);
extern void memcpy(void *dest, void *src, dword n);
extern dword strlen(char *str);
#include "fat12.c"
#include "rd.c"
#include "vfs.c"
#include "kio.c"
#include "fdc.c"
#include "mouse.c"
#include "keyboard.c"
#include "mm.c"
#include "vmm.c"
#include "functions.c"
#include "video.c"
dword timer = 0;
//Main kernel initialization method
void k_init()
{
// ===== Initialization
fdc_sendDOR(0x0C); //turn off floppy motor!!
console_cls();
video_init();
mm_init();
vmm_init();
remap_pics(0x20, 0x28);
init_timer();
mouse_init();
pic1_mask(0); //unmask IRQ's 0-7
pic2_mask(0); //unmask IRQ's 8-15
vfs_init();
enable_ints();
kbd_resetLEDs(); //after enabling interrupts!!
if (videoMode)
{
int p = video_mode.XResolution*video_mode.YResolution-1;
for (; p >= 0; p--)
video_psetp(p, 0x00000044);
video_drawConsole();
}
printf("HOS 0.13 - Kernel File Size: %u kb\tData Size: %u bytes\n", kernel_size()>>10, (dword)(&_end)-(dword)(&_code));
printf("Memory available to OS: %u MB (%u bytes)\n", mm_megabytes, mm_totalmem);
printf("Free memory: %u bytes (%u pages)\n", mm_freemem(), mm_freemem()>>12);
printf("%d/%d/%d\t%d:%d:%d\n", rtc_readMonth(), rtc_readDay(), rtc_readYear(), rtc_readHour(), rtc_readMinute(), rtc_readSecond());
printf("Root Directory: %s/\n", rootDevice->id);
/* int a;
byte *addr = 0;
for (a = 0; a < 5; a++)
{
byte *app = mm_palloc();
vmm_map1((dword)addr, (dword)app);
addr += 4096;
}
addr = vfs_readFile("/bin/hash.hos");
memcpy(0, addr, 4192);
asm("call 0");
free(addr);
*/
dword key = 0;
for (;;)
{
key = kbdWaitKey();
if ((key & 0xFF) > 2) //key is not a control key
putc(key);
}
}
// main Interrupt Service Routine - handles all interrupts unless caught by kernel.asm
void isr(dword num)
{
switch(num)
{
case 14:
printf("Page fault, CR2 = 0x%x\n", read_cr2());
halt();
break;
case 0x20: // IRQ0 - timer interrupt
timer++;
(*(byte *)(0xc00b8000))++;
eoi();
break;
case 0x21: // IRQ1 - keyboard interrupt
isr_keyboard(); //isr_keybard() takes care of calling eoi()
break;
case 0x2C: // IRQ12 - PS/2 mouse
isr_mouse();
eoi2();
break;
default:
printf("Interrupt %d (0x%x) Unhandled!!\n", num, num);
halt();
break;
}
}
+33
View File
@@ -0,0 +1,33 @@
# Makefile for HOS
# Josh Holtrop
# Created: 07/08/04
# Modified: 07/09/04
# Assembler Information:
NASM=nasm
NASM_FLAGS=-f aout
# C Information:
CC=gcc
CC_FLAGS=-fleading-underscore -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -I. -I../include -Wall
# Linker Information:
LD=ld
LD_FLAGS=-nodefaultlibs -nostdlib --no-demangle -T link.ld
all: Asm_Kernel C_Kernel
$(LD) $(LD_FLAGS) -Map boot.map boot.o kernel.o -o kernel.bin
Asm_Kernel:
$(NASM) $(NASM_FLAGS) -l boot.lst boot.asm -o boot.o
C_Kernel:
$(CC) $(CC_FLAGS) -c kernel.c -o kernel.o
#################################################
# Clean up the source directory of any binaries #
#################################################
clean:
- rm *.s *.S *.o *.bin *~ *.map *.lst
+196
View File
@@ -0,0 +1,196 @@
;boot.asm
;Author: Josh Holtrop
;Date: 07/08/04
;Modified: 07/10/04
%define MULTIBOOT_MAGIC 0x1BADB002
%define MULTIBOOT_FLAGS 0x00010003
%define VIRT_OFFSET 0xC0000000 ;3gb virtual address
%define PHYS_START 0x00100000 ;1mb physical address
%define VIRT_STACK_TOP 0xCFFFFFFC ;3gb+256mb virtual address
%define GDT_P PHYS_START ;1mb physical - Global Descriptor Table space
%define GDT_V GDT_P+VIRT_OFFSET
%define IDT_P PHYS_START+0x2000 ;1mb+8kb - Interrupt Descriptor Table space
%define IDT_V IDT_P+VIRT_OFFSET
%define PDBR_P PHYS_START+0x4000 ;1mb+16kb - Page Directory Base Register (first PD)
%define PDBR_V PDBR_P+VIRT_OFFSET
%define LOPT_P PHYS_START+0x5000 ;1mb+20kb - LOw Page Table for mapping first 4mb
%define LOPT_V LOPT_P+VIRT_OFFSET
%define PT_STACK_P PHYS_START+0x6000 ;1mb+24kb - page table for initial kernel stack pages (under 0xD0000000)
%define PT_STACK_V PT_STACK_P+VIRT_OFFSET
%define STACK_P PHYS_START+0x7000 ;1mb+28kb - initial 4kb kernel stack page
%define STACK_V STACK_P+VIRT_OFFSET
%define KERNEL_P PHYS_START+0x8000 ;1mb+32kb - the kernel's physical address
%define KERNEL_V KERNEL_P+VIRT_OFFSET ;3gb+1mb+32kb, the virtual address of the kernel
extern _k_init, _isr, _k_mbsave, _end
[bits 32]
[global _start]
_start:
multiboot_header:
dd MULTIBOOT_MAGIC ;magic
dd MULTIBOOT_FLAGS ;flags
dd -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS) ;checksum
dd multiboot_header-VIRT_OFFSET ;header_addr
dd _start-VIRT_OFFSET ;load_addr
dd 0 ;load_end_addr
dd _end-VIRT_OFFSET ;bss_end_addr
dd multiboot_entry-VIRT_OFFSET ;entry_addr
; dd 1 ;mode_type
; dd 80 ;width
; dd 25 ;height
; dd 0 ;depth
[global multiboot_entry]
multiboot_entry:
;This is where the kernel begins execution from the bootloader.
;At this point, a temporary gdt is set up to "map" 0xC000_0000 to 0x0.
cli ;should already be off...
lgdt [gdtrbs32-VIRT_OFFSET]
jmp KERNEL_CODE_BS32:segmented_start
segmented_start:
mov ax, KERNEL_DATA_BS32
mov ss, ax
mov ds, ax
mov es, ax
mov gs, ax
mov fs, ax
mov esp, STACK_V+0x1000 ;ok, now we can access our data
;aloop:
; inc dword [0xC00B8000]
; jmp aloop
;Then the multiboot info structures are saved to local data variables.
add ebx, VIRT_OFFSET
push eax
push ebx ;pointer to multiboot info structure
call _k_mbsave ;save multiboot info structures
add esp, 8
cmp eax, 0
jz pm_return
;go back to real mode to initialize video mode
mov ebx, pm_return
;Next we enable paging with the first 4mb mapped 1:1 virtual:physical
; and with the 4mb starting at 0xC000_0000 mapped to the first 4mb physical.
pm_return:
xor eax, eax
mov edi, PDBR_V
mov ecx, 1024 ;clear the PDBR
rep stosd
mov edi, PT_STACK_V
mov ecx, 1024 ;clear the PT_STACK
rep stosd
mov [PDBR_V], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table | (read/write, present)
mov [PDBR_V+0xC00], dword LOPT_P|0x03 ;store the physical address of the LOw Page Table | (read/write, present)
mov [PDBR_V+0xCFC], dword PT_STACK_P|0x03 ;store the physical address of the initial stack page page table | (read/write, present)
mov [PT_STACK_V+0xFFC], dword STACK_P|0x03 ;store the physical address of the initial stack page | (read/write, present)
mov edi, LOPT_V
mov ecx, 1024
mov eax, 0x03 ;starting physical address = 0x0 | (read/write, present flags)
fill_lopt_loop: ;fill the page table
stosd
add eax, 4096 ;increment next phsyical address by 4kb
loop fill_lopt_loop
mov eax, PDBR_P
mov cr3, eax ;store the Page Directory Base Address
mov eax, cr0
or eax, 0x80000000 ;set Page Enable bit
mov cr0, eax ;now paging is active!
mov edi, GDT_V
mov esi, gdt
mov ecx, gdt_end-gdt
rep movsb
mov edi, IDT_V ;destination
mov esi, isr_0 ;address of isr0
mov edx, isr_1-isr_0 ;distance between isr labels
mov ecx, 50 ;number of isrlabels
fill_idt:
mov ebx, esi
mov ax, si
stosw ;0 offset 15:0
mov ax, KERNEL_CODE
stosw ;2 selector 15:0
mov ax, 0x8E00
stosw ;4 [P][DPL][0][TYPE][0][0][0][0][0][0][0][0]
shr esi, 16
mov ax, si
stosw ;6 offset 31:16
mov esi, ebx
add esi, edx
loop fill_idt
mov word [IDT_V+0x30*8+4], 0xEE00 ;interrupt 0x30 has user priviledges
;Then we can start using our "real" gdt, then unmap the lower 4mb.
lgdt [gdtr] ;load gdt
jmp KERNEL_CODE:newgdtcontinue
newgdtcontinue:
mov ax, KERNEL_DATA
mov es, ax
mov ds, ax
mov gs, ax
mov fs, ax
mov ss, ax
mov esp, VIRT_STACK_TOP ;stack just under 3gb+256mb, moves downward
lidt [idtr] ;load idt
mov [PDBR_V], dword 0 ;unmap 0x0, we are running completely paged at 0xC000_0000
call _k_init ;C kernel initialization
idle_loop:
; sti
hlt
jmp idle_loop
;-------------------------------------------------------
gdtrbs32:
dw gdt_endbs32-gdtbs32-1
dd gdtbs32-VIRT_OFFSET
gdtbs32: ;null descriptor
dd 0
dd 0
;a base of 0x4000_0000, when added to 0xC000_0000 will produce 0x0000_0000 physical before paging in effect
KERNEL_CODE_BS32 equ $-gdtbs32
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x40 ;base 31:24
KERNEL_DATA_BS32 equ $-gdtbs32
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x92 ;access
db 0xcf ;flags / limit 19:16
db 0x40 ;base 31:24
gdt_endbs32:
%include "gdt.inc"
%include "idt.inc"
+17 -17
View File
@@ -1,11 +1,11 @@
;gdt.inc ;gdt.inc
;Author: Josh Holtrop ;Author: Josh Holtrop
;for HOS ;Date: 10/30/03
;Modified: 10/30/03 ;Modified: 03/02/04
gdtr: gdtr:
dw gdt_end-gdt-1 dw gdt_end-gdt-1
dd GDT_P dd GDT_V
gdt: gdt:
dd 0 dd 0
dd 0 dd 0
@@ -23,6 +23,20 @@ KERNEL_DATA equ $-gdt
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16 db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24 db 0x00 ;base 31:24
USER_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xFA ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
USER_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xF2 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
VESA_CODE equ $-gdt VESA_CODE equ $-gdt
dw 0xffff ;limit 15:0 dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0 dw 0x0000 ;base 15:0
@@ -51,20 +65,6 @@ VIDEO_GRAPHICS equ $-gdt
db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A]) db 0x92 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16 db 0x40 ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24 db 0x00 ;base 31:24
USER_CODE equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xFA ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
USER_DATA equ $-gdt
dw 0xffff ;limit 15:0
dw 0x0000 ;base 15:0
db 0x00 ;base 23:16
db 0xF2 ;access ([P][DPL][1][Executable][Direction/Conforming][Writable/Readable][A])
db 0xCF ;flags ([G][D/B][0][0]) / limit 19:16
db 0x00 ;base 31:24
gdt_end: gdt_end:
+7 -26
View File
@@ -1,7 +1,7 @@
;idt.inc ;idt.inc
;Author: Josh Holtrop ;Author: Josh Holtrop
;for HOS ;Date: 10/30/03
;Modified: 10/30/03 ;Modified: 07/06/04
idtr: idtr:
dw 50*8-1 ;size of idt dw 50*8-1 ;size of idt
@@ -67,40 +67,19 @@ isr_label 48
isr_label 49 isr_label 49
isr_main: isr_main:
cmp eax, 0x30
jz isr_syscall
pusha pusha
push ds push ds
push es push es
push eax push eax ;interrupt number
call _isr call _isr
pop eax
pop es
pop ds
popa
pop eax
iret
isr_syscall:
pop eax ;syscall function number
pusha
push ds
push es
push ebx
call _putc
add esp, 4 add esp, 4
pop es pop es
pop ds pop ds
popa popa
pop eax ;original saved eax
iret iret
@@ -109,3 +88,5 @@ isr_syscall:
+76
View File
@@ -0,0 +1,76 @@
#include "kernel.h"
#include "multiboot.h"
#include "module.h"
mb_info_t mb_info_block;
mb_mmap_t mb_mmap[MAX_MMAP];
mb_module_t mb_modules[MAX_MODULES];
mb_apm_t mb_apm_table;
char mb_cmdline[256];
/* This function runs in segmented memory - 0xC000_0000 is mapped to 0x0 but 0x0
itself is an invalid linear address. Therefore, the multiboot information addresses
must be manually adjusted by VIRT_OFFSET to become valid linear addresses. */
int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic)
{
if (mb_magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
char *msg = "Bad multiboot magic identifier!";
char *dest = (char *) 0xC00B8000;
while (*msg)
{
*dest++ = *msg++;
*dest++ = 0x04; //red error message
}
for (;;) ;
}
mb_info_block = *mbinfo;
if (mb_info_block.flags & MB_BOOTLOADER_COMMAND_LINE)
{
mb_info_block.cmdline += VIRT_OFFSET;
memcpy(mb_cmdline, mb_info_block.cmdline, 256);
mb_cmdline[255] = 0;
}
if (mb_info_block.flags & MB_BOOTLOADER_MODS)
{
mb_info_block.mods_addr += VIRT_OFFSET;
int i;
for (i = 0; i < mb_info_block.mods_count && i < MAX_MODULES; i++)
{
mb_modules[i] = ((mb_module_t *)mb_info_block.mods_addr)[i];
}
}
if (mb_info_block.flags & MB_BOOTLOADER_MMAP)
{
mb_info_block.mmap_addr += VIRT_OFFSET - 4; //-4 to get to size field, not base_addr_low field
mb_mmap_t *mmap = (mb_mmap_t *)mb_info_block.mmap_addr;
int i, sz = 0;
for (i = 0; sz < mb_info_block.mmap_length && i < MAX_MMAP; i++)
{
sz += mmap->size;
mb_mmap[i] = *mmap;
mmap = (mb_mmap_t *)(((u32_t) mmap) + mmap->size);
}
}
if (mb_info_block.flags & MB_BOOTLOADER_APM)
{
mb_info_block.apm_table += VIRT_OFFSET;
mb_apm_table = *(mb_apm_t *)mb_info_block.apm_table;
}
return 0;
}
void k_init()
{
for (;;)
{
(*(char*)0xC00B8000)++;
}
}
void isr()
{
for (;;) ;
}
+8 -4
View File
@@ -1,8 +1,8 @@
OUTPUT_FORMAT("binary") OUTPUT_FORMAT("binary")
ENTRY(start) ENTRY(_start)
SECTIONS SECTIONS
{ {
.text 0xC0106000 : { .text 0xC0108000 : {
code = .; _code = .; __code = .; code = .; _code = .; __code = .;
*(.text) *(.text)
. = ALIGN(4096); . = ALIGN(4096);
@@ -10,10 +10,14 @@ SECTIONS
.data : { .data : {
data = .; _data = .; __data = .; data = .; _data = .; __data = .;
*(.data) *(.data)
/* . = ALIGN(4096); */
}
.rodata : {
rodata = .; _rodata = .; __rodata = .;
*(.rodata)
. = ALIGN(4096); . = ALIGN(4096);
} }
.bss : .bss : {
{
bss = .; _bss = .; __bss = .; bss = .; _bss = .; __bss = .;
*(.bss) *(.bss)
. = ALIGN(4096); . = ALIGN(4096);
-254
View File
@@ -1,254 +0,0 @@
//Keyboard.c
// Created: 04/17/03 Josh Holtrop
// Modified: 10/30/03
//for HOS
#define KBD_BUFFER_LENGTH 64
byte kbdFlags = 0; //holds current keyboard flags - caps/num/scroll/shift/ctrl/alt
byte kbdAscii = 0; //holds ASCII value of a key pressed
byte kbdScan = 0; //holds the keyboard scan code of a key pressed
dword kbdBuffer[KBD_BUFFER_LENGTH]; //a buffer for all keypresses
int kbdBufferStart = 0; //position of next key in buffer
int kbdBufferLen = 0; //number of keys left in the buffer
byte kbdExt = 0; //# of extended key codes left to input
byte kbdExt2 = 0; //# of 2nd-set-extended key codes left to input
byte ackReason = 0; //used to record the reason why we would get an acknowledge byte (0xFA)
//these arrays convert a keyboard scan code to an ASCII character value
//nul esc bksp tab lctl lsft rsft lalt caps F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 numScrlNumPad------- unknown---- F11 F12 unknown....
const byte SCAN2ASCII[128] = "\000\0331234567890-=\010\011qwertyuiop[]\n\001asdfghjkl;'`\001\\zxcvbnm,./\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001-\001\001\001+\001\001\001\001\001\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
const byte SCAN2ASCIISHIFT[128] = "\000\033!@#$%^&*()_+\010\011QWERTYUIOP{}\n\001ASDFGHJKL:\"~\001|ZXCVBNM<>?\001*\001 \001\001\001\001\001\001\001\001\001\001\001\001\001789-456+1230.\002\002\002\001\001\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002\002";
//====FUNCTIONS:
// The Keyboard Interrupt Service Routine
void isr_keyboard()
{
kbdScan = inportb(0x60);
//printf("\nKEYBOARD INTERRUPT: 0x%x", kbdScan);
byte inState = inportb(0x61);
outportb(0x61, inState|0x80);
outportb(0x61, inState);
//printf("IRQ 1: %x\n", kbdScan);
if (kbdScan == 0xFA) //250 //ACKnowledge
{
//printf("KBD_ACK 0x%x!\n", ackReason);
if (ackReason == 0xED) //reset LEDs
{
outportb(0x60, (kbdFlags & 0x07));
}
ackReason = 0;
}
if (kbdScan == 224) //extended key
{
kbdExt = 1;
eoi();
return;
}
if (kbdScan == 225) //2nd-set-extended key
{
kbdExt2 = 2;
eoi();
return;
}
//====handle control keys::
kbdAscii = 2;
switch (kbdScan) //control keys
{
case KBD_SCAN_LSHIFT:
kbdFlags |= KBD_SHIFT;
kbdAscii = 1;
break;
case KBD_SCAN_RSHIFT:
kbdFlags |= KBD_SHIFT;
kbdAscii = 1;
break;
case KBD_SCAN_LCTRL:
kbdFlags |= KBD_CTRL;
kbdAscii = 1;
break;
case KBD_SCAN_LALT:
kbdFlags |= KBD_ALT;
kbdAscii = 1;
break;
case KBD_SCAN_LSHIFT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_SHIFT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_RSHIFT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_SHIFT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_LCTRL + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_CTRL ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_LALT + KBD_SCAN_RELEASED:
kbdFlags &= (KBD_ALT ^ 0xFF);
kbdAscii = 1;
break;
case KBD_SCAN_CAPS+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_CAPS;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
case KBD_SCAN_SCROLL+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_SCROLL;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
case KBD_SCAN_NUM+KBD_SCAN_RELEASED:
kbdFlags ^= KBD_NUM;
kbdAscii = 1;
kbd_resetLEDs(); //update LEDs
break;
}
if (kbdAscii == 1)
{
if (kbdExt > 0)
kbdExt--;
eoi();
return;
}
//====determine ASCII value of key::
if (kbdExt > 0) //extended key, kbdScan holds extended key
{
kbdExt--;
kbdAscii = 1;
switch (kbdScan)
{
case KBD_SCANE_ENTER:
kbdAscii = '\n'; break;
case 53: // '/' character (divide on numpad)
kbdAscii = '/'; break;
}
}
else if (kbdExt2 > 0) //extended key 2
{
kbdExt2--;
// if (kbdScan == 69) // (pause|break)
// kbdAscii = 2; //flag ascii value of 1 means control character (pausebreak)
// else
kbdAscii = 2; //flag ascii value of 2 means ignore key (or unknown value)
}
else //not an extended key
{
// if letter key
if (((kbdScan >= 16) && (kbdScan <= 25)) || ((kbdScan >= 30) && (kbdScan <= 38)) || ((kbdScan >= 44) && (kbdScan <= 50)))
{
// if caps and shift are different (either one pressed, not both)
if (((kbdFlags & KBD_SHIFT) != 0) & ((kbdFlags & KBD_CAPS) != 0))
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
else if (((kbdFlags & KBD_SHIFT) == 0) & ((kbdFlags & KBD_CAPS) == 0))
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
}
// if numpad key
else if ((kbdScan >= 71) && (kbdScan <= 83))
{
// if numlock on
if (kbdFlags & KBD_NUM)
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
}
// other key
else
{
if ((kbdFlags & KBD_SHIFT) != 0)
kbdAscii = SCAN2ASCIISHIFT[kbdScan & 0x7F];
else
kbdAscii = SCAN2ASCII[kbdScan & 0x7F];
}
}
//====do something with key::
// printf("kbdScan == %d\nkbdAscii == %d\nkbdFlags == %d\n", kbdScan, kbdAscii, kbdFlags);
if ((kbdScan == 83) && (kbdFlags & KBD_CTRL) && (kbdFlags & KBD_ALT))
{
printf("Initiating reboot.");
restart();
}
if (kbdAscii == 2) //unknown key / ignore key
{
eoi();
return;
}
if (kbdScan < KBD_SCAN_RELEASED) //a key was pressed, save it
{
if (kbdBufferLen >= KBD_BUFFER_LENGTH) //no key slots available
{
eoi();
return;
}
else
{
kbdBuffer[(kbdBufferStart+kbdBufferLen++)%KBD_BUFFER_LENGTH] = (dword) ((kbdFlags << 16) | (kbdScan << 8) | kbdAscii);
// printf("S:%d\tL:%d\tR:%x\n", kbdBufferStart, kbdBufferLen, kbdBuffer[kbdBufferStart]);
}
}
eoi();
}
//Switches the case of an ASCII character
/*inline byte (byte asciiCode)
{
if ((asciiCode >= 'A') & (asciiCode <= 'Z'))
return (asciiCode + ('a' - 'A'));
if ((asciiCode >= 'a') & (asciiCode <= 'z'))
return (asciiCode - ('a' - 'A'));
return asciiCode;
}*/
//Gets a key from the buffer, returns 0 if no keys available, returns immediately
dword kbdGetKey()
{
if (kbdBufferLen == 0) //buffer empty
return 0;
dword retVal = kbdBuffer[kbdBufferStart];
kbdBufferStart++;
kbdBufferLen--;
if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
}
//Gets a key from the buffer, if no keys available, waits for one to be entered
dword kbdWaitKey()
{
for (;;)
{
if (kbdBufferLen != 0) //buffer empty
break;
}
dword retVal = kbdBuffer[kbdBufferStart];
kbdBufferStart++;
kbdBufferLen--;
if (kbdBufferStart >= KBD_BUFFER_LENGTH)
kbdBufferStart = 0;
return retVal;
}
//Resets the keyboard LEDs to reflect the current state of the num lock, caps lock, and scroll lock bits
inline void kbd_resetLEDs()
{
outportb(0x60, 0xED);
//outportb(0x60, (kbdFlags & 0x07));
ackReason = 0xED;
}
-47
View File
@@ -1,47 +0,0 @@
//Keyboard.h
// Created: 04/17/03 Josh Holtrop
// Modified: 05/07/03
//for HOS
#define KBD_SCROLL 0x01
#define KBD_NUM 0x02
#define KBD_CAPS 0x04
#define KBD_SHIFT 0x10
#define KBD_CTRL 0x20
#define KBD_ALT 0x40
#define KBD_SCAN_RELEASED 128
#define KBD_SCAN_LCTRL 29
#define KBD_SCAN_LSHIFT 42
#define KBD_SCAN_RSHIFT 54
#define KBD_SCAN_LALT 56
#define KBD_SCAN_SCROLL 70
#define KBD_SCAN_CAPS 58
#define KBD_SCAN_NUM 69
#define KBD_SCANE_PRINTSCREEN 55
#define KBD_SCANE_INS 82
#define KBD_SCANE_HOME 71
#define KBD_SCANE_PGUP 73
#define KBD_SCANE_DEL 83
#define KBD_SCANE_END 79
#define KBD_SCANE_PGDN 81
#define KBD_SCANE_ENTER 28
#define KBD_SCANE_NULL 42
//====PROTOTYPES:
void isr_keyboard();
inline void kbd_resetLEDs();
inline byte kbd_ascii(dword keycode);
inline byte kbd_scancode(dword keycode);
inline byte kbd_flags(dword keycode);
inline byte switchCase(byte asciiCode);
dword kbdGetKey();
dword kbdWaitKey();
-133
View File
@@ -1,133 +0,0 @@
//kio.c
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 12/25/03
// This is the main output routine, it uses a format string and a variable
// number of arguments to print formatted text
void printf(char *fmt, ...)
{
dword *params = ((dword *)(&fmt)) + 1; //points to the first paramater
int i;
int special = 0;
for (i = 0; ; i++)
{
if (special)
{
special = 0;
switch (fmt[i])
{
case 0:
return;
case '%':
putc('%');
break;
case 's': case 'S':
puts((char *)*params);
params++;
break;
case 'c': case 'C':
putc(*params);
params++;
break;
case 'd': case 'D':
putDec(*params);
params++;
break;
case 'u': case 'U':
putDecu(*params);
params++;
break;
case 'x': case 'X':
putHex(*params);
params++;
break;
}
}
else
{
switch (fmt[i])
{
case '%':
special = 1;
break;
case 0:
return;
default:
putc(fmt[i]);
}
}
}
}
// This function draws a single character
void putc(dword chr)
{
char charac = (char)chr;
word *vidmem = (word *)0xC00B8000;
if (charac == '\n')
{
if (cursorPosition % 80)
cursorPosition = cursorPosition + 80 - (cursorPosition % 80);
else
cursorPosition += 80;
}
else if (charac == '\t')
{
if (cursorPosition % 8)
cursorPosition = cursorPosition + 8 - (cursorPosition % 8);
else
cursorPosition += 8;
}
else
{
if (videoMode)
{
console_memory[cursorPosition] = charac | 0x0700;
video_drawConsoleChar(cursorPosition);
}
else
{
console_memory[cursorPosition] = charac | 0x0700;
vidmem[cursorPosition] = charac | 0x0700;
}
cursorPosition++;
}
if (cursorPosition >= 2000)
{
console_scroll();
cursorPosition = 2000-80;
if (videoMode)
video_drawConsole();
}
if (!videoMode)
writeCursorPosition(cursorPosition);
}
// This function displays a number in hexadecimal
int putHex(dword number)
{
int hitNum = 0;
int i;
for (i = 7; i >= 0; i--)
{
dword val = (number >> (i*4)) & 0xF;
if ((val != 0) || (i == 0))
hitNum = 1;
if (hitNum)
{
val = val + '0';
if (val > '9')
val = val + ('A' - '9' - 1);
putc(val);
}
}
}
-15
View File
@@ -1,15 +0,0 @@
//kio.h
// Author: Josh Holtrop
// Created: 12/25/03
// Modified: 12/25/03
void printf(char *fmt, ...);
void putc(dword chr);
int putHex(dword number);
dword cursorPosition = 0; //Caches the current cursor position
-1
View File
@@ -1 +0,0 @@
ld -nodefaultlibs -nostdlib -T link.ld -o kernel.bin -Map .\lst\LDout.doc ks.o kernel.o asmfuncs.o
+9
View File
@@ -0,0 +1,9 @@
timeout 10
default 0
title HOS 0.15
root (fd0)
kernel /kernel.bin
-121
View File
@@ -1,121 +0,0 @@
// mm.c
// Author: Josh Holtrop
// Created: 09/01/03
// Modified: 12/28/03
//The total amount of physical memory available (bytes)
#define BITMAP_SIZE 0x20000
dword mm_totalmem = 0;
dword mm_megabytes;
byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
//0x20000*(8 bits/byte)=0x100000 pages in 4gb total
//This function initializes the memory manager's linked list, filling it with the
// memory areas returned by bios interrupt 0x8E20
void mm_init()
{
dword memmap_entries = *(dword *)0xC009040A;
memmap_entry *maps = (memmap_entry *) 0xC0092000;
dword a;
for (a = 0; a < BITMAP_SIZE; a++)
{
page_bitmap[a] = 0xFF; //all pages used
}
for (a = 0; a < memmap_entries; a++)
{
if (maps[a].attributes == 1) // (1) mem free to OS
{
mm_totalmem += maps[a].limit.lowdword;
if ((maps[a].base.lowdword + maps[a].limit.lowdword) >= (FREERAM_START+4096)) //goes past where we start freeram
{
if (maps[a].base.lowdword < FREERAM_START)
{
mm_pfreen(FREERAM_START, (maps[a].limit.lowdword - (FREERAM_START - maps[a].base.lowdword)) >> 12);
}
else
{
mm_pfreen(maps[a].base.lowdword, maps[a].limit.lowdword >> 12); //set the appropriate bits as "free" in the page bitmap
}
}
}
}
if (mm_totalmem % 0x100000)
mm_megabytes = (mm_totalmem >> 20) + 1;
else
mm_megabytes = mm_totalmem >> 20;
}
// This function frees a certain number of pages starting at the address
// specified in base for a length of pages pages
void mm_pfreen(dword base, dword pages)
{
dword a;
dword max = base + (pages << 12);
for (a = base; a < max; a += 4096)
{
mm_pfree(a);
}
}
// This function frees a single page
void mm_pfree(dword base)
{
// dword pageNumber = base >> 12; // >>12 == /4096
dword byteNumber = base >> 15; //pageNumber >> 3; //pageNumber/8
dword bitNumber = (base >> 12) % 8; //pageNumber % 8;
page_bitmap[byteNumber] = page_bitmap[byteNumber] & ((0x01 << bitNumber) ^ 0xFF);
}
// This function allocates a single page, returning its physical address
void *mm_palloc()
{
dword bite;
for (bite = 0; bite < BITMAP_SIZE; bite++)
{
if (page_bitmap[bite] != 0xFF) //there is an available page within this 8-page region
{
int bit;
for (bit = 0; bit < 8; bit++)
{
if (!(page_bitmap[bite] & (1 << bit))) //this bite/bit combination is available
{
page_bitmap[bite] = page_bitmap[bite] | (1 << bit); //set page as used
return (void *)((bite << 15) | (bit << 12));
}
}
}
}
return 0; //no free page
}
// This function reports the number of bytes of free physical memory
dword mm_freemem()
{
dword a;
dword pages = 0;
for (a = 0; a < BITMAP_SIZE; a++)
{
int bit;
for (bit = 0; bit < 8; bit++)
{
if (!(page_bitmap[a] & (1 << bit)))
pages++;
}
}
return pages << 12;
}
-21
View File
@@ -1,21 +0,0 @@
typedef struct {
qword base;
qword limit;
dword attributes;
} __attribute__((packed)) memmap_entry;
void mm_init();
void mm_pfreen(dword base, dword pages);
void mm_pfree(dword base);
void *mm_palloc();
dword mm_freemem();
-60
View File
@@ -1,60 +0,0 @@
// mouse.c
// 10/03/03
// Author: Josh Holtrop
//This method initializes the ps/2 mouse
void mouse_init()
{
outportb(0x64, 0x20); //tell keyboard controller we are going to read keyboard controller command byte
byte temp = inportb(0x60); //read keyboard controller command byte
outportb(0x64, 0x60); //tell keyboard controller we are going to write keyboard controller command byte
outportb(0x60, 0x03 | (temp&0x40)); //write keyboard controller command byte: enable mouse/keyboard ints, include original XLATE bit from temp (bit6)
outportb(0x64, 0xA8); //enable mouse port
outportb(0x64, 0xD4); //send command to mouse, not kbd
outportb(0x60, 0xF4); //enable data reporting
mouse_x = video_mode.XResolution >> 1;
mouse_y = video_mode.YResolution >> 1;
//outportb(0x64, 0xD4);
//outportb(0x60, 0xE7); //scaling 2:1
}
//This method is called when a mouse interrupt occurs
void isr_mouse()
{
byte inb = inportb(0x60); //read mouse byte
if ((inb == 0xFA) && (mouse_bytesRead < 1)) //ACK
return;
mouse_inbuffer[mouse_bytesRead] = inb;
mouse_bytesRead++;
if (mouse_bytesRead == 3) //complete packet received
{
mouse_bytesRead = 0;
int adjx = (char) mouse_inbuffer[1];
int adjy = (char) mouse_inbuffer[2];
mouse_x += adjx;
mouse_y -= adjy; //-= because screen y coordinates are opposite mouse y coordinates
if (mouse_x < 0)
mouse_x = 0;
if (mouse_x >= video_mode.XResolution)
mouse_x = video_mode.XResolution - 1;
if (mouse_y < 0)
mouse_y = 0;
if (mouse_y >= video_mode.YResolution)
mouse_y = video_mode.YResolution - 1;
if (mouse_inbuffer[0] & 0x01) //left button
video_pset(mouse_x, mouse_y, 0x00FF8800);
else
video_pset(mouse_x, mouse_y, 0x00FFFFFF);
}
}
-17
View File
@@ -1,17 +0,0 @@
// mouse.h
// 10/03/03
// Author: Josh Holtrop
int mouse_x;
int mouse_y;
int mouse_bytesRead = 0;
byte mouse_inbuffer[16];
void mouse_init();
void isr_mouse();
-14
View File
@@ -1,14 +0,0 @@
// rd.c
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
byte *rd_readSector(DiskDevice *rd, dword sector, byte *dest)
{
memcpy(dest, (void *)(rd->location + (sector * 512)), 512);
return dest;
}
-9
View File
@@ -1,9 +0,0 @@
// rd.h
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
byte *rd_readSector(DiskDevice *rd, dword sector, byte *dest);
View File
Whitespace-only changes.
View File
Whitespace-only changes.
-228
View File
@@ -1,228 +0,0 @@
%include "bootdef.inc"
[bits 16]
org 0x7c00
jmp short start
; --------------------------------------------------
; data portion of the "DOS BOOT RECORD"
; ----------------------------------------------------------------------
brINT13Flag DB 90H ; 0002h - 0EH for INT13 AH=42 READ
brOEM DB 'MSDOS5.0' ; 0003h - OEM ID - Windows 95B
brBPS DW 512 ; 000Bh - Bytes per sector
brSPC DB 1 ; 000Dh - Sector per cluster
brSc_b4_fat DW 1 ; 000Eh - Reserved sectors
brFATs DB 2 ; 0010h - FAT copies
brRootEntries DW 0E0H ; 0011h - Root directory entries
brSectorCount DW 2880 ; 0013h - Sectors in volume, < 32MB
brMedia DB 240 ; 0015h - Media descriptor
brSPF DW 9 ; 0016h - Sectors per FAT
brSc_p_trk DW 18 ; 0018h - Sectors per head/track
brHPC DW 2 ; 001Ah - Heads per cylinder
brSc_b4_prt DD 0 ; 001Ch - Hidden sectors
brSectors DD 0 ; 0020h - Total number of sectors
brDrive DB 0 ; 0024h - Physical drive no.
DB 0 ; 0025h - Reserved (FAT32)
DB 29H ; 0026h - Extended boot record sig (FAT32)
brSerialNum DD 404418EAH ; 0027h - Volume serial number
brLabel DB 'Holtrops OS' ; 002Bh - Volume label
brFSID DB 'FAT12 ' ; 0036h - File System ID
;------------------------------------------------------------------------
start:
jmp 0:jmphere ;ensure that cs=0 and ip=0x7c00...
jmphere:
;dl=drive number, save it!
xor ax, ax
mov ds, ax
mov [brDrive], dl
cli
mov ss, ax
mov sp, 0x7Bfe ;right under boot sector
sti
mov ax, 0xb800
mov ds, ax
mov es, ax
xor di, di
mov ax, 0x0700
mov cx, 2000
cls:
stosw
loop cls
enable_a20:
in al, 0x64
test al, 2
jnz enable_a20
mov al, 0xD1
out 0x64, al
ea20_2: in al, 0x64
and ax, byte 2
jnz ea20_2
mov al, 0xDF
out 0x60, al
unreal:
xor ax, ax
mov es, ax
mov ds, ax
lgdt [gdtr] ;load gdt
cli
push es
push ds ;save segment values
mov ebx, cr0
inc bl
mov cr0, ebx ;pmode!
mov ax, KERNEL_DATA
mov es, ax
mov ds, ax ;load segment limits
dec bl
mov cr0, ebx ;back to real mode!
pop ds
pop es ;segments back, with 4gb limits!
sti
;now lets read in the FAT and root directory so we can search for the stage2 file...
mov ax, 0x0209 ;FAT1
mov cx, 0x0002
xor dh, dh
mov dl, [brDrive]
mov bx, BOOT_FAT_SEG
mov es, bx
xor bx, bx
int 0x13
mov ax, 0x020E ;root directory
mov cx, 0x0002 ;cyl/sect
mov dh, 0x01 ;head
mov dl, [brDrive] ;drive
mov bx, BOOT_ROOT_SEG
mov es, bx
xor bx, bx
int 0x13
;k now read root directory
mov bx, BOOT_ROOT_SEG
mov ds, bx
xor si, si ;k now ds:si points to beginning of root directory
mov es, si
mov cx, 224 ;max root entries
loop_compare:
mov di, stage2
push cx
push si ;save pointer to root dir entry
mov cx, 11
loop_name:
cmpsb
loopz loop_name
jnz goon ;cx didn't get to zero, bad file
pop si
pop cx
jmp found_file ;good file, ds:si points to start of root directory entry
goon:
pop si
pop cx
add si, 32
loop loop_compare
error:
jmp $ ;halt! no kernel file found!
found_file: ;ds:si points to root dir entry
xor ax, ax
mov gs, ax
mov ax, BOOT_STAGE2_SEG
mov es, ax
mov ax, [ds:si+26]
mov bx, BOOT_FAT_SEG
mov ds, bx ;ds points to beginning of FAT
xor di, di
readstage2_loop:
cmp ax, 0xff7
jg readstage2_done
inc di
push ax
call getCHSfromCluster
mov ax, 0x0201
mov dl, [gs:BOOT_DRIVE]
xor bx, bx
int 0x13
mov bx, es
add bx, 0x0020
mov es, bx
pop ax ;current logical cluster #
mov cx, ax ;cx=logical cluster
mov dx, 3
mul dx
shr ax, 1 ;ax=logical cluster * 3 / 2
mov si, ax
test cl, 1 ;is bit0 set?
jnz odd_cluster
even_cluster:
lodsw
and ax, 0x0fff
jmp got_cluster
odd_cluster:
lodsw
shr ax, 4
got_cluster:
jmp readstage2_loop
readstage2_done:
jmp 0:BOOT_STAGE2_ADD
;------------------------------------------------------
getCHSfromCluster:
;input: ax=lba of sector on floppy (0-2879)
add ax, 31 ;convert logical cluster# to lba#
xor dx, dx ;lba->chs
mov bx, 18
div bx
inc dx
mov cl, dl ;sector# (1-18)
xor dx, dx
mov bx, 2
div bx
mov ch, al ;cylinder# (0-79)
mov dh, dl ;head# (0-1)
ret
;-------------------------------------------------------
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
dd 0
dd 0
KERNEL_DATA equ $-gdt
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf ;cf
db 0x00
gdt_end:
stage2: db "STAGE2 BIN"
times 510-($-$$) db 0
db 0x55, 0xaa
-971
View File
@@ -1,971 +0,0 @@
%include "bootdef.inc"
%define VESA_MODEINFO_SEG 0x0120
%define VESA_MODELIST_SEG 0x0140
%define GOOD_MODELIST_SEG 0x0160
[bits 16]
org BOOT_STAGE2_ADD
;k now read root directory
mov bx, BOOT_ROOT_SEG
mov ds, bx
xor si, si ;k now ds:si points to beginning of root directory
mov es, si
mov cx, 224 ;max root entries
loop_compare:
mov di, kernel
push cx
push si ;save pointer to root dir entry
mov cx, 11
loop_name:
cmpsb
loopz loop_name
jnz goon ;cx didn't get to zero, bad file
pop si
pop cx
jmp found_file ;good file, ds:si points to start of root directory entry
goon:
pop si
add si, 32
pop cx
loop loop_compare
error:
jmp $ ;halt! no kernel file found!
found_file: ;ds:si points to root dir entry of kernel file
xor ax, ax
mov gs, ax
mov ax, [ds:si+26]
mov bx, BOOT_FAT_SEG
mov ds, bx ;ds points to beginning of FAT
mov edi, BOOT_KERNEL_ADD
readkernel_loop:
cmp ax, 0xff7
jg readkernel_done
push ax
call getCHSfromCluster
mov ax, 0x0201
mov dl, [gs:BOOT_DRIVE]
mov bx, BOOT_KERNEL_SEG
mov es, bx
xor bx, bx
int 0x13
mov cx, 256
xor ax, ax
mov es, ax
mov esi, BOOT_KERNEL_SEG*16
copykernel_loop:
mov ax, [es:esi]
mov [es:edi], ax
inc esi
inc esi
inc edi
inc edi
loop copykernel_loop
pop ax ;current logical cluster #
mov cx, ax ;cx=logical cluster
mov dx, 3
mul dx
shr ax, 1 ;ax=logical cluster * 3 / 2
mov si, ax
test cl, 1 ;is bit0 set?
jnz odd_cluster
even_cluster:
lodsw
and ax, 0x0fff
jmp got_cluster
odd_cluster:
lodsw
shr ax, 4
got_cluster:
jmp readkernel_loop
;------------------------------------------------------
readkernel_done: ;-------------put more real mode init stuff here!
;----ask to load RD from floppy
mov ax, 0xb800
mov es, ax
xor ax, ax
mov ds, ax
xor di, di
mov cx, 2000
mov ax, 0x0700
cls_loop:
stosw
loop cls_loop
mov dx, 0x3d4 ;move cursor off screen...
mov al, 0x0e
out dx, al
inc dx
mov al, 0xff
out dx, al
dec dx
mov al, 0x0f
out dx, al
inc dx
out dx, al
xor di, di
mov si, txt_welcome
mov ah, 0x1f
call puts
mov di, 160
mov si, txt_rd1
mov ah, 7
call puts
mov si, txt_rd2
mov di, 160*2
call puts
mov di, 160*3
mov si, txt_input
call puts
get_rd:
xor ax, ax
int 0x16
cmp al, '1'
jz got_rd
cmp al, '2'
jnz get_rd
got_rd:
stosb
sub al, '1'
push ds
mov bx, BOOT_DATA_SEG ;segment for data to send kernel
mov ds, bx
mov [ds:BOOT_HASRD], al
pop ds ;ds=0
cmp al, 0 ;dont load rd
jnz yes_rd
jmp no_rd
yes_rd:
mov cx, 80
mov edi, 0xb8000+160*4
filler_loop: ;draw a red bar
mov word [ds:edi], 0x0400+177
inc edi
inc edi
loop filler_loop
mov cx, 80 ;80 cylinders to read
xor si, si ;start at cylinder 0
mov edi, BOOT_RD_ADD ;ram disk address
read_cylinder:
push cx
mov bx, 0x0100 ;read sectors from head 0
mov es, bx
xor bx, bx ;es:bx = data buffer for read
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si ;what cyl. we are on is now in cx
mov ch, cl ;ch = cyl. number
mov cl, 1 ;cl = sector number 1-63
xor dx, dx ;dh = head number
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13
mov bx, 0x0100 ;now read sectors from head 1
mov es, bx
mov bx, 9216 ;es:bx = data buffer for read
mov ax, 0x0212 ;ah = int 0x13 function 2, al = number of sectors to read
mov cx, si ;what cyl. we are on is now in cx
mov ch, cl ;ch = cyl. number
mov cl, 1 ;cl = sector number 1-63
mov dh, 1 ;dh = head number
mov dl, [gs:BOOT_DRIVE] ;dl = drive number
int 0x13
mov ebx, 0xb8000
add bx, si
shl bl, 1
mov word [ds:ebx+160*4], 0x0200+219
push si
mov esi, 0x1000
mov cx, 0x2400
copydisk_loop:
mov ax, [ds:esi]
inc esi
inc esi
mov [ds:edi], ax
inc edi
inc edi
loop copydisk_loop
pop si ;what cylinder# we are on...
inc si
pop cx
loop read_cylinder
;------------------------------------------------------
no_rd:
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_MEMMAP ;store memmap info in es:di for kernel
xor edx, edx
mov ax, 0x0100
mov ds, ax
xor ebx, ebx
getmemmap_loop:
push es
push di
push edx
mov ax, 0x0100 ;get memory map
mov es, ax
xor di, di
mov eax, 0x0000E820
mov ecx, 0x00000014
;mov ebx, 0x00000000
mov edx, 0x534D4150 ;'SMAP'
int 0x15
jc getmemmap_carry
cmp eax, 0x534D4150 ;eax should be 'SMAP' on return...
jnz getmemmap_error
cmp ebx, 0
jz getmemmap_done
pop edx ;now, copy memmap entry to es:di on the stack
pop di
pop es
xor si, si
mov cx, 20
getmemmap_copymem_loop:
lodsb
stosb
loop getmemmap_copymem_loop
inc edx
jmp getmemmap_loop
getmemmap_error:
mov ax, 0xb800
mov es, ax
mov di, 160*24
xor ax, ax
mov ds, ax
mov si, txt_memerror
mov ah, 0x04
call puts
hlt
jmp $
getmemmap_carry:
dec edx
getmemmap_done:
pop edx
pop di
pop es
xor si, si
mov cx, 20
getmemmap_done_copymem_loop:
lodsb
stosb
loop getmemmap_done_copymem_loop
inc edx
mov di, BOOT_MEMENTRIES
mov [es:di], edx ;save # of memmap entries for kernel
;on to vesa info...
xor ax, ax
mov gs, ax
mov ds, ax
mov ax, 0xb800
mov es, ax
mov di, 160
mov cx, 2000-80
mov ax, 0x0700
cls_vesa_loop:
stosw
loop cls_vesa_loop
mov si, txt_vesa
mov di, 160*1
mov ah, 7
call puts
push di
mov ax, 0x0100
mov es, ax
xor di, di
mov dword [es:di], "2EBV"
mov ax, 0x4F00
int 0x10
pop di
cmp ax, 0x004F
jz vesa_good
mov si, txt_novesa
mov ax, 0xb800
mov es, ax
mov ah, 7
call puts
mov ax, BOOT_DATA_SEG
mov ds, ax
mov word [ds:BOOT_VESA], 0
jmp vesa_done
vesa_good:
mov ax, 0xb800
mov es, ax
mov ax, 0x0100
mov ds, ax
xor si, si
mov bx, [4]
mov al, bh
call puthex
mov al, '.'
stosb
mov al, 7
stosb
mov al, bl
call puthex
add di, 4
cmp bh, 2
jge vesa_good2
xor ax, ax
mov ds, ax
mov si, txt_vesaold
mov ah, 7
call puts
mov ax, BOOT_DATA_SEG
mov ds, ax
mov word [ds:BOOT_VESA], 0
jmp vesa_done
vesa_good2:
mov ebx, [6] ;something like 0x00000E60
mov edx, [14]
mov si, bx
shr ebx, 16
mov ds, bx ;ds:si points to null-terminated OEM identification string
mov ah, 2
push si
call puts
pop si
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_VESA_OEM
vesa_copyoem:
lodsb
stosb
or al, al
jnz vesa_copyoem
mov ax, 0x0100
mov ds, ax
xor si, si
mov di, BOOT_VESA_VBE
mov cx, 512
vesa_copyvbe:
lodsb
stosb
loop vesa_copyvbe
mov si, dx
shr edx, 16
mov ds, dx ;ds:si points to video mode list
mov ax, VESA_MODELIST_SEG
mov es, ax
xor di, di
vesa_copymodes:
lodsw
stosw
cmp ax, 0xffff
jnz vesa_copymodes
mov ax, GOOD_MODELIST_SEG
mov es, ax
xor di, di
mov cx, 256
mov ax, 0xffff
clear_good_mode_list_loop:
stosw
loop clear_good_mode_list_loop
mov ax, VESA_MODELIST_SEG
mov ds, ax
xor si, si ;ds:si points to video mode list where we can edit it :)
mov ax, GOOD_MODELIST_SEG
mov es, ax
xor di, di
xor dx, dx ;dx=what good mode # we are on
vesa_readmodeinfo_loop:
lodsw
cmp ax, 0xffff
jz vesa_endofmodes
push ax ;save mode#
call checkmode
cmp ax, 0
jz vesa_readmodeinfo_good
pop ax
jmp vesa_readmodeinfo_loop
vesa_readmodeinfo_good:
pop ax ;restore mode#
stosw
call vesa_showmodeinfo
inc dx
jmp vesa_readmodeinfo_loop
vesa_endofmodes: ;here we have a list of good modes at GOOD_MODELIST_SEG:0
xor ax, ax
mov ds, ax
mov si, txt_consolemode
mov ax, 0xb800
mov es, ax
mov di, 160*2
mov ah, 7
call puts
mov di, 160*3
mov cx, dx
mov al, 'b'
vesa_displaylabels:
stosb
push ax
mov al, 7
stosb
mov al, '.'
stosb
mov al, 7
stosb
pop ax
inc al
add di, 160-4
loop vesa_displaylabels ;done drawing screen of VESA choices, now ask for one
;valid options are 'a' through (al-1)
mov bl, al
xor ax, ax
mov ds, ax
mov di, 160*24
mov si, txt_input
mov ah, 14
call puts
vesa_getchoice:
xor ax, ax
int 0x16
cmp al, 'a'
jl vesa_getchoice
cmp al, bl
jge vesa_getchoice
stosb
push ax
mov al, 14
stosb
pop ax
xor ah, ah
sub ax, 'a'
cmp ax, 0
jz vesa_consolemode_only
mov cx, ax ;cx holds good mode# (1=first good vesa mode)
dec cx
mov ax, GOOD_MODELIST_SEG
mov ds, ax
shl cx, 1
mov si, cx ;ds:si points to word containing selected mode#
lodsw
mov cx, ax
mov dx, ax ;cx and dx hold mode#
mov ax, VESA_MODEINFO_SEG
mov es, ax
xor di, di
mov ax, 0x4F01
int 0x10
call checkvesa
mov ax, VESA_MODEINFO_SEG
mov ds, ax
xor si, si
mov ax, BOOT_DATA_SEG
mov es, ax
mov di, BOOT_VESA_INFO
mov cx, 256
vesa_copymodeinfo_loop:
lodsb
stosb
loop vesa_copymodeinfo_loop ;store ModeInfoBlock for current
mov [es:BOOT_VESA], dx ;store mode# for kernel
; mov ax, 0xb800
; mov es, ax
; xor di, di
; mov al, dh
; call puthex2
; mov al, dl
; call puthex2
mov bx, dx
or bx, 0x4000 ;set "use LFB" bit of mode#
mov ax, 0x4F02
int 0x10 ;switch to graphics mode!!!
call checkvesa
jmp vesa_done
vesa_consolemode_only:
mov ax, BOOT_DATA_SEG
mov es, ax
mov word [es:BOOT_VESA], 0
jmp vesa_done
;------------------------------------------------------
vesa_showmodeinfo:
pusha
push es
push ds
mov ax, VESA_MODEINFO_SEG
mov ds, ax
xor si, si
mov ax, 0xb800
mov es, ax
mov cx, dx
mov ax, 160
mul dx ;ax=160*mod#
add ax, 160*3+6 ;offset first line of modes and room on left for label
mov di, ax
mov ax, [ds:18]
call console_putDec
add di, 10
mov al, 'x'
call console_putChar
inc di
inc di
mov ax, [ds:20]
call console_putDec
add di, 10
mov al, 'x'
call console_putChar
inc di
inc di
xor ah, ah
mov al, [ds:25]
call console_putDec
add di, 8
mov al, [ds:0]
test al, 0x80
jz vesa_showmodeinfo_done
mov al, 'L'
call console_putChar
mov al, 'F'
call console_putChar
mov al, 'B'
call console_putChar
inc di
inc di
mov ebx, [ds:40]
mov eax, ebx
shr eax, 24
call puthex2
mov eax, ebx
shr eax, 16
call puthex2
mov al, bh
call puthex2
mov al, bl
call puthex2
vesa_showmodeinfo_done:
pop ds
pop es
popa
ret
;------------------------------------------------------
checkmode:
push bx
push cx
push dx
push es
push ds
push di
push si
mov cx, ax ;cx=modenumber
mov ax, VESA_MODEINFO_SEG
mov es, ax
xor di, di
mov ax, 0x4F01
int 0x10
call checkvesa
xor di, di ;es:di -> ModeInfoBlock struc
mov ax, [es:di] ;ModeAttributes
test al, 1 ;mode supported
jz vesa_modenogood
test al, 8 ;color mode
jz vesa_modenogood
test al, 0x10 ;graphics mode
jz vesa_modenogood
test al, 0x80 ;Linear Frame Buffer supported
jz vesa_modenogood
mov al, [es:di+25] ;BitsPerPixel
cmp al, 16
jz vesa_bppok
cmp al, 24
jz vesa_bppok
cmp al, 32
jnz vesa_modenogood
vesa_bppok:
mov ax, [es:di+18] ;XResolution
mov bx, [es:di+20] ;YResolution
cmp ax, 640 ;640x480
jnz res_goon1
cmp bx, 480
jnz vesa_modenogood
jmp vesa_modegood
res_goon1:
cmp ax, 800
jnz res_goon2
cmp bx, 600
jnz vesa_modenogood
jmp vesa_modegood
res_goon2:
cmp ax, 1024
jnz res_goon3
cmp bx, 768
jnz vesa_modenogood
jmp vesa_modegood
res_goon3:
cmp ax, 1280
jnz res_goon4
cmp bx, 1024
jz vesa_modegood
cmp bx, 960
jz vesa_modegood
jmp vesa_modenogood
res_goon4:
cmp ax, 1600
jnz vesa_modenogood
cmp bx, 1200
jnz vesa_modenogood
vesa_modegood:
pop si
pop di
pop ds
pop es
pop dx
pop cx
pop bx
xor ax, ax
ret
vesa_modenogood:
pop si
pop di
pop ds
pop es
pop dx
pop cx
pop bx
mov ax, 0xffff
ret
;------------------------------------------------------
vesa_done:
; xor ax, ax ;wait for keypress...
; int 0x16
jmp go_pm
;------------------------------------------------------
puts:
lodsb
or al, al
jz puts_done
stosb
mov al, ah
stosb
jmp puts
puts_done:
ret
;------------------------------------------------------
checkvesa:
cmp ax, 0x004F
jnz vesaerror
ret
vesaerror:
mov ax, 0xb800
mov es, ax
xor ax, ax
mov ds, ax
mov si, txt_vesaerror
mov di, 160*24
mov ah, 4
call puts
cli
hlt
;-------Function console_putDec
;input:
; AX = number to display
;output:
; number written in decimal to es:di
console_putDec:
pusha
xor dx, dx
xor bh, bh ;no characters written yet
mov cx, 10000
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon1
call console_putChar
mov bh, 1
.goon1:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 1000
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon11
call console_putChar
mov bh, 1
jmp .goon2
.goon11:
cmp bh, 0
je .goon2
call console_putChar
.goon2:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 100
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon21
call console_putChar
mov bh, 1
jmp .goon3
.goon21:
cmp bh, 0
je .goon3
call console_putChar
.goon3:
mov ax, dx ;load remainder to ax
xor dx, dx
mov cx, 10
div cx ;ax=quotiont, dx=remainder
add ax, '0'
cmp ax, '0'
je .goon31
call console_putChar
mov bh, 1
jmp .goon4
.goon31:
cmp bh, 0
je .goon4
call console_putChar
.goon4: ;here dx contains last remainder
mov ax, dx
add ax, '0'
call console_putChar
popa
ret
;------------------------------------------------------
console_putChar:
stosb
mov al, 7
stosb
ret
;------------------------------------------------------
puthex:
;es:di points to video memory
;al holds hex value
push ax
mov ah, al
shr ax, 4
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex_goon1
add al, 'A'-'9'-1
puthex_goon1:
cmp al, '0'
jz puthex_skipzero
stosb
mov al, 7
stosb
puthex_skipzero:
pop ax
push ax
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex_goon2
add al, 'A'-'9'-1
puthex_goon2:
stosb
mov al, 7
stosb
pop ax
ret
;------------------------------------------------------
puthex2:
;es:di points to video memory, always displays 2 characters!
;al holds hex value
push ax
mov ah, al
shr ax, 4
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex2_goon1
add al, 'A'-'9'-1
puthex2_goon1:
stosb
mov al, 7
stosb
pop ax
push ax
and al, 0x0F
add al, '0'
cmp al, '9'
jle puthex2_goon2
add al, 'A'-'9'-1
puthex2_goon2:
stosb
mov al, 7
stosb
pop ax
ret
;------------------------------------------------------
txt_welcome: db " Welcome to HOS v", VERSION, "! ", 0
txt_rd1: db "1. Do not load an initial ram disk", 0
txt_rd2: db "2. Load initial ram disk from floppy", 0
txt_input: db "Enter your selection: ", 0
txt_vesa: db "VESA version: ", 0
txt_vesaerror: db "VESA function call error! Halting system!", 0
txt_novesa: db "VESA not found. Starting in console mode...", 0
txt_vesaold: db "VESA version 2.0 required. Starting in console mode...", 0
txt_consolemode: db "a. Console mode only.", 0
txt_memerror: db "Extended Memory Map information unavailable! Halting system...", 0
;------------------------------------------------------
getCHSfromCluster:
;input: ax=lba of sector on floppy (0-2879)
add ax, 31 ;convert logical cluster# to lba#
xor dx, dx ;lba->chs
mov bx, 18
div bx
inc dx
mov cl, dl ;sector# (1-18)
xor dx, dx
mov bx, 2
div bx
mov ch, al ;cylinder# (0-79)
mov dh, dl ;head# (0-1)
ret
;-------------------------------------------------------
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
dd 0
dd 0
KERNEL_CODE equ $-gdt
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x00 ;base 31:24
KERNEL_DATA equ $-gdt
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf
db 0x00
gdt_end:
;-------------------------------------------------------
gdtr32:
dw gdt_end32-gdt32-1
dd gdt32
gdt32:
dd 0
dd 0
;a base of 0x4000_0000, when added to 0xC000_0000 will produce 0x0000_0000 physical before paging in effect
KERNEL_CODE32 equ $-gdt32
db 0xff ;limit 7:0
db 0xff ;limit 15:8
db 0x00 ;base 7:0
db 0x00 ;base 15:8
db 0x00 ;base 23:16
db 0x9a ;access
db 0xcf ;flags / limit 19:16
db 0x40 ;base 31:24
KERNEL_DATA32 equ $-gdt32
db 0xff ;segment 16 = 4gb data
db 0xff
db 0x00
db 0x00
db 0x00
db 0x92
db 0xcf
db 0x40
gdt_end32:
;------------------------------------------------------
go_pm:
xor ax, ax
mov ds, ax
lgdt [gdtr]
cli
mov eax, cr0
inc eax
mov cr0, eax
jmp KERNEL_CODE:pmode
bits 32
pmode:
lgdt [gdtr32]
jmp KERNEL_CODE32:pmode_offsetted+0xC0000000
pmode_offsetted:
mov ax, KERNEL_DATA32
mov es, ax
mov ds, ax
mov fs, ax
mov gs, ax
jmp KERNEL_CODE:BOOT_KERNEL_ADD+0xC0000000
kernel: db "KERNEL BIN", 0
-258
View File
@@ -1,258 +0,0 @@
const byte stdfont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xE0, 0xC0, 0x80,
0x00, 0x08, 0x18, 0x38, 0x78, 0x38, 0x18, 0x08,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0x20,
0x00, 0xA0, 0xA0, 0xA0, 0xA0, 0x00, 0xA0, 0xA0,
0x00, 0x78, 0xA8, 0xA8, 0x78, 0x28, 0x28, 0x68,
0x00, 0x78, 0x80, 0x70, 0x88, 0x70, 0x08, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0xA8, 0x70, 0xF8,
0x00, 0x20, 0x70, 0xA8, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x20, 0x20, 0x20, 0xA8, 0x70, 0x20,
0x00, 0x00, 0x20, 0x10, 0xF8, 0x10, 0x20, 0x00,
0x00, 0x00, 0x20, 0x40, 0xF8, 0x40, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x60, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x70, 0xF8, 0xF8, 0x00, 0x00,
0x00, 0x00, 0xF8, 0xF8, 0x70, 0x20, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, 0x20,
0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x50, 0xF8, 0x50, 0x50, 0x50, 0xF8, 0x50,
0x00, 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20,
0x00, 0x00, 0x08, 0x90, 0x20, 0x48, 0x80, 0x00,
0x00, 0x20, 0x50, 0x50, 0x20, 0x58, 0x90, 0x68,
0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20,
0x00, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40,
0x00, 0x00, 0xA8, 0x70, 0xF8, 0x70, 0xA8, 0x00,
0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40,
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60,
0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x20, 0x60, 0xA0, 0x20, 0x20, 0x20, 0x20,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x70, 0x88, 0x08, 0x10, 0x08, 0x88, 0x70,
0x00, 0x30, 0x50, 0x90, 0x90, 0xF8, 0x10, 0x10,
0x00, 0xF8, 0x80, 0x80, 0xF8, 0x08, 0x88, 0x70,
0x00, 0x38, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40,
0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70,
0x00, 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x40,
0x00, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10,
0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00,
0x00, 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80,
0x00, 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20,
0x00, 0x70, 0x88, 0x88, 0xB8, 0xB0, 0x80, 0x78,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0xC8, 0xE8, 0xB8, 0x98, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x88, 0x88, 0xA8, 0x98, 0x70,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88,
0x00, 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x88, 0x50, 0x20, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20,
0x00, 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8,
0x00, 0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70,
0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x08, 0x00,
0x00, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0,
0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x00, 0x70, 0x88, 0x80, 0x88, 0x70,
0x00, 0x08, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x30, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x70,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x20, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x90, 0x60,
0x00, 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90,
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x00, 0xD0, 0xA8, 0xA8, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x38,
0x00, 0x00, 0x00, 0x70, 0x48, 0x40, 0x40, 0x40,
0x00, 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0,
0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20,
0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0xA8, 0x50,
0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88,
0x00, 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0xF0,
0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8,
0x00, 0x30, 0x40, 0x40, 0x80, 0x40, 0x40, 0x30,
0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0xC0, 0x20, 0x20, 0x10, 0x20, 0x20, 0xC0,
0x00, 0x00, 0x68, 0x90, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0xF8, 0x88, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0xF8, 0x48, 0x40, 0x40, 0x40, 0x40, 0xE0,
0x00, 0xF0, 0x50, 0x50, 0x50, 0x50, 0x78, 0x88,
0x00, 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8,
0x00, 0xA8, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x70, 0x88, 0x08, 0x30, 0x08, 0x88, 0x70,
0x00, 0x88, 0x98, 0xA8, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0xA8, 0xC8, 0x98, 0xA8, 0xA8, 0xC8, 0x88,
0x00, 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88,
0x00, 0xF8, 0x50, 0x50, 0x50, 0x50, 0x50, 0x90,
0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80,
0x00, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70,
0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x70, 0x20, 0xF8, 0xA8, 0xF8, 0x20, 0x70,
0x00, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x08, 0x38,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0xC0, 0x40, 0x40, 0x78, 0x48, 0x48, 0x78,
0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xA8, 0xE8,
0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0,
0x00, 0xF0, 0x88, 0x08, 0x78, 0x08, 0x88, 0xF0,
0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0xA8, 0x90,
0x00, 0x78, 0x88, 0x88, 0x78, 0x28, 0x48, 0x88,
0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x88, 0x78,
0x00, 0x00, 0xF8, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF0, 0x88, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x40, 0x40, 0xE0,
0x00, 0x00, 0x78, 0x50, 0x50, 0x50, 0x70, 0x88,
0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x88, 0x70,
0x00, 0x00, 0xA8, 0x70, 0x20, 0x70, 0xA8, 0xA8,
0x00, 0x00, 0x00, 0xF0, 0x88, 0x30, 0x88, 0x70,
0x00, 0x00, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x88,
0x00, 0x50, 0x20, 0x88, 0x98, 0xA8, 0xC8, 0x88,
0x00, 0x00, 0x88, 0x90, 0xA0, 0xE0, 0x90, 0x88,
0x00, 0x00, 0xF8, 0x48, 0x48, 0x48, 0x48, 0xC8,
0x00, 0x00, 0x88, 0xD8, 0xA8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88,
0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x88,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x50, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x88, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x90, 0x00, 0xF0, 0x80, 0xE0, 0x80, 0xF0,
0x00, 0x00, 0x70, 0x48, 0x70, 0x48, 0x48, 0xF0,
0x00, 0x88, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x88, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x70, 0x50, 0x70, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88,
0x00, 0x88, 0x70, 0x88, 0x88, 0x88, 0x88, 0x70,
0x00, 0x88, 0x00, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x88, 0xF8, 0x80, 0xE0, 0x80, 0x80, 0xF8,
0x00, 0x40, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x10, 0x20, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x20, 0x50, 0x70, 0x88, 0xF8, 0x80, 0x78,
0x00, 0x40, 0x20, 0x70, 0x08, 0x78, 0x88, 0x78,
0x00, 0x20, 0x50, 0x00, 0x20, 0x20, 0x20, 0x20,
0x00, 0x20, 0x10, 0x88, 0x88, 0x88, 0x88, 0x78,
0x00, 0x00, 0x00, 0x70, 0x80, 0x80, 0x70, 0x20,
0x00, 0x70, 0x88, 0x40, 0xF0, 0x40, 0x40, 0xF8,
0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80,
0x00, 0x00, 0x70, 0x88, 0x80, 0x80, 0x88, 0x70,
0x00, 0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20,
0x00, 0x00, 0x88, 0x88, 0x50, 0x20, 0x40, 0x80,
0x00, 0x00, 0x70, 0x20, 0xF8, 0xF8, 0x20, 0x70,
0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88,
0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0xF8, 0x08,
0x00, 0x00, 0x88, 0x88, 0x88, 0xF8, 0x08, 0x38,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8,
0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0xF8, 0x08,
0x00, 0x00, 0xC0, 0x40, 0x70, 0x48, 0x48, 0x70,
0x00, 0x00, 0x88, 0x88, 0xC8, 0xA8, 0xA8, 0xE8,
0x00, 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0xF0,
0x00, 0x00, 0x70, 0x88, 0x38, 0x08, 0x88, 0x70,
0x00, 0x00, 0x90, 0xA8, 0xA8, 0xE8, 0xA8, 0x90,
0x00, 0x00, 0x38, 0x48, 0x48, 0x38, 0x28, 0x48,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-91
View File
@@ -1,91 +0,0 @@
// vfs.c
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
void vfs_init()
{
firstDiskDevice = malloc(sizeof(DiskDevice));
firstDiskDevice->type = VFS_DISK_FD;
firstDiskDevice->fileSystem = VFS_FS_FAT12;
firstDiskDevice->location = VFS_LOC_FD0;
firstDiskDevice->link = 0;
strcpy(firstDiskDevice->id, "fd0");
rootDevice = firstDiskDevice;
if (*(byte *)0xC0090000) // the user chose to load an initial ram disk from the floppy
{
DiskDevice *rd = malloc(sizeof(DiskDevice));
firstDiskDevice->link = (dword)rd;
rd->type = VFS_DISK_RD;
rd->fileSystem = VFS_FS_FAT12;
rd->location = 0xC0200000;
rd->link = 0;
strcpy(rd->id, "rd0");
rootDevice = rd;
}
}
byte *vfs_readFile(char *fileName)
{
DiskDevice *dd;
dword fileStartPosition;
if (fileName[0] == '/')
{
dd = rootDevice;
fileStartPosition = 1;
}
else
{
if (strlen(fileName) < 5) //not a long enough file name
return 0;
if (!((fileName[3] == ':') && (fileName[4] == '/'))) //if we aren't using the root directory, then there must be a 3 character device explicitly specified
return 0; // followed by a colon and then a slash
char device[4];
memcpy(device, fileName, 3); //copy the 3 digit device id to device
device[3] = 0; //null-terminating character for device string
dd = vfs_getDiskDeviceByID(device);
if (!dd) //the specified device was not found
return 0;
fileStartPosition = 5;
}
switch (dd->fileSystem)
{
case VFS_FS_FAT12:
return fat12_readFile(fileName+fileStartPosition, dd);
}
return 0;
}
byte *vfs_readSector(DiskDevice *dd, dword sector, byte *dest, dword sectors)
{
byte *origDest = dest;
switch (dd->type)
{
case VFS_DISK_RD:
for (; sectors > 0; sectors--, dest += 512, sector++)
rd_readSector(dd, sector, dest);
return origDest;
}
return 0;
}
DiskDevice *vfs_getDiskDeviceByID(char *id)
{
DiskDevice *dd = firstDiskDevice;
for (;;)
{
if (strcmp(dd->id, id))
return dd;
dd = (DiskDevice *)dd->link;
if (!dd)
break;
}
return 0;
}
-33
View File
@@ -1,33 +0,0 @@
// vfs.h
// Author: Josh Holtrop
// Created: 12/31/03
// Modified: 01/04/04
#define VFS_DISK_RD 1
#define VFS_DISK_FD 2
#define VFS_DISK_HD 3
#define VFS_FS_FAT12 1
#define VFS_LOC_FD0 1
typedef struct {
dword type;
dword fileSystem;
dword location;
dword link;
char id[4];
} __attribute__((packed)) DiskDevice;
void vfs_init();
byte *vfs_readFile(char *fileName);
byte *vfs_readSector(DiskDevice *dd, dword sector, byte *dest, dword sectors);
DiskDevice *vfs_getDiskDeviceByID(char *id);
DiskDevice *rootDevice = 0;
DiskDevice *firstDiskDevice = 0;
-176
View File
@@ -1,176 +0,0 @@
//video.c
// 08/13/03 Josh Holtrop
// Modified: 11/12/03
//Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
void video_init()
{
videoMode = *(word *)0xC0090002;
if (!videoMode) //we are in console mode
return;
video_mode = *(ModeInfoBlock *) 0xC0090306;
switch(video_mode.BitsPerPixel)
{
case 16:
video_psetp = &video_psetp16;
break;
case 24:
video_psetp = &video_psetp24;
break;
case 32:
video_psetp = &video_psetp32;
}
}
//Renders a character using stdfont[] as a bitmask
void video_renderChar(int x, int y, int character, dword color)
{
int charpos = (character & 0xFF) * 8;
int row;
int col;
for (row = 0; row < 8; row++)
{
for (col = 0; col < 5; col++)
{
if ((stdfont[charpos+row] >> (col+3)) & 0x01)
video_pset(x+(5-col), y+row, color);
}
}
}
//Draws a horizontal line
void video_horiz(int y, int x1, int x2, dword color)
{
if (x1 > x2)
{
int tmp = x2;
x2 = x1;
x1 = tmp; //x2 >= x1 now
}
if (x2 < 0)
return;
if (x1 > video_mode.XResolution)
return;
if (x1 < 0)
x1 = 0;
if (x2 > video_mode.XResolution)
x2 = video_mode.XResolution;
int pixel = y*video_mode.XResolution+x1;
for (; x1 <= x2; x1++)
{
video_psetp(pixel++, color);
}
}
//Draws a vertical line
void video_vert(int x, int y1, int y2, dword color)
{
if (y1 > y2)
{
int tmp = y2;
y2 = y1;
y1 = tmp; //y2 >= y1 now
}
if (y2 < 0)
return;
if (y1 > video_mode.YResolution)
return;
if (y1 < 0)
y1 = 0;
if (y2 > video_mode.YResolution)
y2 = video_mode.YResolution;
int pixel = y1*video_mode.XResolution+x;
for (; y1 <= y2; y1++)
{
video_psetp(pixel, color);
pixel+=video_mode.XResolution;
}
}
//Draws a rectangle
void video_rect(int x1, int y1, int x2, int y2, dword color)
{
video_horiz(y1, x1, x2, color);
video_horiz(y2, x1, x2, color);
video_vert(x1, y1, y2, color);
video_vert(x2, y1, y2, color);
}
//Draws a filled rectangle
void video_rectf(int x1, int y1, int x2, int y2, dword color)
{
if (y2 < y1)
{
int tmp = y2;
y2 = y1;
y1 = tmp;
}
for (; y1 <= y2; y1++)
video_horiz(y1, x1, x2, color);
}
//Draws a single pixel
inline void video_pset(int x, int y, dword color)
{
if ((x < 0) || (x > video_mode.XResolution) || (y < 0) || (y > video_mode.YResolution))
return;
video_psetp(y*video_mode.XResolution+x, color);
}
//Draws a pixel at the specified pixel position
void video_psetp16(int pixel, dword color)
{
vid_ptr16[pixel] = ((color&0xFF)>>3) | ((((color>>8)&0xFF)>>2)<<5) | ((((color>>16)&0xFF)>>3)<<11);
}
//Draws a pixel at the specified pixel position
void video_psetp24(int pixel, dword color)
{
vid_ptr24[pixel*3] = color & 0xFF;
vid_ptr24[pixel*3+1] = (color>>8) & 0xFF;
vid_ptr24[pixel*3+2] = (color>>16) & 0xFF;
}
//Draws a pixel at the specified pixel position
void video_psetp32(int pixel, dword color)
{
vid_ptr32[pixel] = color;
}
//Dummy function to not draw anything if there is no graphical mode enabled
void video_psetpnull(int pixel, dword color) {}
// This function draws a simple "console" window in graphical mode to display text
void video_drawConsole()
{
video_rectf(9, 9, 490, 260, 0);
video_rect(8, 8, 491, 261, 0x00777777);
int x, y;
for (x = 0; x < 80; x++)
{
for (y = 0; y < 25; y++)
{
video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0x00FFFFFF);
}
}
}
// This function draws a "console" character to the graphical video screen
void video_drawConsoleChar(dword position)
{
int x = position % 80;
int y = position / 80;
video_renderChar(x*6+10, y*10+10, console_memory[y*80+x], 0x00FFFFFF);
}
-72
View File
@@ -1,72 +0,0 @@
//video.h
// 08/18/03 Josh Holtrop
// Modified: 12/28/03
void video_init();
void video_horiz(int y, int x1, int x2, dword color);
void video_vert(int x, int y1, int y2, dword color);
void video_rect(int x1, int y1, int x2, int y2, dword color);
void video_rectf(int x1, int y1, int x2, int y2, dword color);
inline void video_pset(int x, int y, dword color);
void video_psetp16(int pixel, dword color);
void video_psetp24(int pixel, dword color);
void video_psetp32(int pixel, dword color);
void video_psetpnull(int pixel, dword color);
void video_renderChar(int x, int y, int character, dword color);
void video_drawConsole();
void video_drawConsoleChar(dword position);
typedef struct{
word ModeAttributes;
byte WinAAttributes;
byte WinBAttributes;
word WinGranularity;
word WinSize;
word WinASegment;
word WinBSegment;
dword WinFuncPtr;
word BytesPerScanLine;
word XResolution;
word YResolution;
byte XCharSize;
byte YCharSize;
byte NumberOfPlanes;
byte BitsPerPixel;
byte NumberOfBanks;
byte MemoryModel;
byte BankSize;
byte NumberOfImagePages;
byte Reserved1;
byte RedMaskSize;
byte RedFieldPosition;
byte GreenMaskSize;
byte GreenFieldPosition;
byte BlueMaskSize;
byte BlueFieldPosition;
byte RsvdMaskSize;
byte RsvdFieldPosition;
byte DirectColorModeInfo;
dword PhysBasePtr;
dword OffScreenMemOffset;
word OffScreenMemSize;
byte Reserved[206];
} ModeInfoBlock;
ModeInfoBlock video_mode;
dword videoMode = 0; //what video mode # we are in, 0 for console mode
word *vid_ptr16 = (word *)0xF0000000;
byte *vid_ptr24 = (byte *)0xF0000000;
dword *vid_ptr32 = (dword *)0xF0000000;
word console_memory[2000]; //holds a copy of the console's memory
void (*video_psetp)(int, dword) = video_psetpnull; //function pointer to set a pixel
-354
View File
@@ -1,354 +0,0 @@
// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 12/30/03
// This is the initialization procedure for the Virtual Memory Manager
// It sets up the final page directory/page table setup and maps video memory, if present
void vmm_init()
{
dword *pageTables = (dword *)0xC0104000; //this is the location of the page directory
pageTables[0x3FF] = 0x104000|0x03; //the last page directory entry points to the page directory itself
pageTables[0] = 0;
invlpg(0);
if (videoMode) //we are in a graphical mode
{
dword vidPages = video_mode.XResolution * video_mode.YResolution * (video_mode.BitsPerPixel >> 3);
if (vidPages % 4096)
vidPages = (vidPages >> 12) + 1;
else
vidPages = (vidPages >> 12);
vmm_mapn(0xF0000000, video_mode.PhysBasePtr, vidPages);
}
dword firstHeapEntryBlock = (dword)mm_palloc();
vmm_map1((dword)firstHeapEntry, firstHeapEntryBlock);
HeapEntryBlock *heb = (HeapEntryBlock *)firstHeapEntry;
vmm_heb_init(heb);
heb->entry[0].base = (dword)firstHeapEntry; //start of kernel's heap memory
heb->entry[0].size = 4096; //the first HeapEntryBlock is 1 page long
heb->entry[0].attributes = VMM_HE_HEB; //this is a HeapEntryBlock
heb->entry[1].base = (dword)firstHeapEntry+4096; //this is the start of the rest of the kernel's heap memory
heb->entry[1].size = 0x10000000-4096; //the rest of the kernel's heap memory: 256mb - 4kb
heb->entry[1].attributes = VMM_HE_HOLE; //this is a hold - an unmapped section of heap memory
}
// This function initialzes a Heap Entry Block to unused entries linked together
void vmm_heb_init(HeapEntryBlock *heb)
{
int a;
for (a = 0; a < 256; a++)
{
heb->entry[a].base = 0;
heb->entry[a].size = 0;
heb->entry[a].attributes = VMM_HE_UNUSED;
heb->entry[a].link = (dword)&(heb->entry[a+1]);
}
heb->entry[255].link = 0;
}
// This function maps a virtual address to a physical address using the page directory / page table
void vmm_map1(dword virt, dword physical)
{
dword pde = virt >> 22;
dword pte = (virt & 0x003FF000) >> 12;
dword *pageTables = (dword *)0xC0104000; //this is the location of the page directory
if (!(pageTables[pde] & 0x01)) //the page directory entry does not exist, we must allocate a page for it
{
dword *newpagetable = mm_palloc();
pageTables[pde] = ((dword)newpagetable) | 0x03;
invlpg(virt);
dword *newpteptr = (dword *)(0xFFC00000 | (pde << 12)); //points to first dword of newly allocated page table
int a;
for (a = 0; a < 1024; a++)
{
newpteptr[a] = 0;
}
}
dword *pteptr = (dword *)(0xFFC00000 | (pde << 12) | (pte << 2));
*pteptr = physical | 0x03;
invlpg(virt);
}
// This function maps a variable number of pages in a row
void vmm_mapn(dword virt, dword physical, dword n)
{
for (; n > 0; n--)
{
vmm_map1(virt, physical);
virt += 4096;
physical += 4096;
}
}
// This function removes the virtual address's entry in the page directory / page table
void vmm_unmap1(dword virt)
{
dword *pteptr = (dword *)(0xFFC00000 | ((virt & 0xFFC00000) >> 10) | ((virt & 0x003FF000) >> 10));
*pteptr = 0;
invlpg(virt);
}
// This function removes multiple pages' entries
void vmm_unmapn(dword virt, dword n)
{
for (; n > 0; n--)
{
vmm_unmap1(virt);
virt += 4096;
}
}
// Virtual Memory allocator function
void *malloc(dword bytes)
{
if (bytes % VMM_MALLOC_GRANULARITY)
bytes = bytes + VMM_MALLOC_GRANULARITY - (bytes % VMM_MALLOC_GRANULARITY);
void *attempt = vmm_getFreeChunk(bytes);
if (attempt)
return attempt;
if(vmm_moreCore(bytes))
return 0; //we could not get any more heap memory
return vmm_getFreeChunk(bytes);
}
// This function returns a pointer if a free chunk of memory exists
void *vmm_getFreeChunk(dword bytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_FREE)
{
if (he->size > bytes)
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_USED;
he->base += bytes;
he->size -= bytes;
return (void *)(nhe->base);
}
if (he->size == bytes)
{
he->attributes = VMM_HE_USED;
return (void *)(he->base);
}
}
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function coalesces any two adjacent heap entries into one entry
void vmm_coalesceHeapEntry(HeapEntry *he)
{
if (!(he->attributes == VMM_HE_FREE || he->attributes == VMM_HE_HOLE))
return;
if (he->size == 0)
{
he->attributes = VMM_HE_UNUSED;
return;
}
HeapEntry *hec = firstHeapEntry;
for (;;)
{
if (hec->attributes == he->attributes)
{
if ((hec->base + hec->size) == he->base) //hec ends where he begins
{
he->base = hec->base;
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
if ((he->base + he->size) == hec->base) //he ends where hec begins
{
he->size += hec->size;
hec->attributes = VMM_HE_UNUSED;
}
}
hec = (HeapEntry *)hec->link;
if (!hec)
break;
}
}
// This function retrieves more physical memory for the heap
int vmm_moreCore(dword bytes)
{
dword pages = (bytes >> 12) + 1;
bytes = pages << 12;
HeapEntry *he = vmm_getFirstHoleHeapEntry(bytes);
dword virt = he->base;
for (; pages > 0; pages--)
{
dword phys = (dword)mm_palloc();
if (!phys)
return 1;
vmm_map1(virt, phys);
virt += 4096;
}
if (he->size == bytes)
{
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
}
else
{
HeapEntry *nhe = vmm_nextHeapEntry();
nhe->base = he->base;
nhe->size = bytes;
nhe->attributes = VMM_HE_FREE;
he->base += bytes;
he->size -= bytes;
vmm_coalesceHeapEntry(nhe);
}
return 0;
}
// This function returns the next available heap entry, creates more entries if we are running low
HeapEntry *vmm_nextHeapEntry()
{
if (vmm_heapEntriesLeft() < 10)
vmm_addHeapEntryBlock();
return vmm_getFirstUnusedHeapEntry();
}
// This function creates a new block (page) of heap entries (256)
void vmm_addHeapEntryBlock()
{
HeapEntry *he = vmm_getFirstHoleHeapEntry(4096);
HeapEntry *newBlock = vmm_getFirstUnusedHeapEntry();
dword heb = (dword)mm_palloc();
vmm_map1(he->base, heb);
vmm_heb_init((HeapEntryBlock *)he->base);
HeapEntry *lhe = vmm_getLastHeapEntry();
if (he->size == 4096)
{
he->attributes = VMM_HE_HEB;
lhe->link = (dword)he->base;
}
else
{
newBlock->base = he->base;
newBlock->size = 4096;
newBlock->attributes = VMM_HE_HEB;
he->base += 4096;
he->size -= 4096;
lhe->link = (dword)newBlock->base;
}
return;
}
// This function returns the last heap entry in the linked list, useful for setting
// its link field to point to the first entry of a newly allocated list
HeapEntry *vmm_getLastHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->link == 0)
return he;
he = (HeapEntry *)he->link;
}
}
// This function returns the first heap entry corresponding to a memory "hole"
HeapEntry *vmm_getFirstHoleHeapEntry(dword minBytes)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if ((he->attributes == VMM_HE_HOLE) && (he->size >= minBytes))
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the first heap entry that is not being used
HeapEntry *vmm_getFirstUnusedHeapEntry()
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
// This function returns the number of heap entries available for use
dword vmm_heapEntriesLeft()
{
HeapEntry *he = firstHeapEntry;
dword entries = 0;
for (;;)
{
if (he->attributes == VMM_HE_UNUSED)
entries++;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return entries;
}
// This function "frees" an area of memory previously allocated with malloc()
int free(void *ptr)
{
HeapEntry *he = vmm_getHeapEntryByBase((dword)ptr);
if (!he)
return 1; //a heap entry starting at the given address was not found
he->attributes = VMM_HE_FREE;
vmm_coalesceHeapEntry(he);
return 0;
}
// This function scans the heap entry linked list for an entry that begins at the given address
HeapEntry *vmm_getHeapEntryByBase(dword base)
{
HeapEntry *he = firstHeapEntry;
for (;;)
{
if (he->base == base)
return he;
he = (HeapEntry *)he->link;
if (!he)
break;
}
return 0;
}
-55
View File
@@ -1,55 +0,0 @@
// vmm.h
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 12/30/03
#define VMM_HE_UNUSED 0 //available entry
#define VMM_HE_FREE 1 //free section of memory
#define VMM_HE_USED 2 //used section of memory
#define VMM_HE_HOLE 3 //a "hole" (unmapped) section of virtual memory
#define VMM_HE_HEB 4 //HeapEntryBlock
#define VMM_MALLOC_GRANULARITY 4 //granularity for all memory requests
typedef struct {
dword base; //virtual base address
dword size; //size in bytes
dword attributes; //free/used/hole
dword link; //link to next HeapEntry
} __attribute__((packed)) HeapEntry;
typedef struct {
HeapEntry entry[256]; //256 HeapEntry objects = 4kb (1 page)
} __attribute__((packed)) HeapEntryBlock;
void vmm_init();
void *malloc(dword bytes);
int free(void *ptr);
void vmm_map1(dword virt, dword physical);
void vmm_mapn(dword virt, dword physical, dword n);
void vmm_unmap1(dword virt);
void vmm_unmapn(dword virt, dword n);
void vmm_heb_init(HeapEntryBlock *heb);
void *vmm_getFreeChunk(dword bytes);
HeapEntry *vmm_nextHeapEntry();
dword vmm_heapEntriesLeft();
HeapEntry *vmm_getLastHeapEntry();
HeapEntry *vmm_getFirstUnusedHeapEntry();
HeapEntry *vmm_getFirstHoleHeapEntry(dword minBytes);
void vmm_addHeapEntryBlock();
int vmm_moreCore(dword bytes);
void vmm_coalesceHeapEntry(HeapEntry *he);
HeapEntry *vmm_getHeapEntryByBase(dword base);
HeapEntry *firstHeapEntry = (HeapEntry *)0xD0000000; //this is where heap memory starts