Import backup from 2004-08-02

This commit is contained in:
Josh Holtrop 2004-08-02 22:00:00 -04:00
parent 07e8a0f4cf
commit a50c2a1233
21 changed files with 766 additions and 37 deletions

View File

@ -11,7 +11,7 @@ ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata1: enabled=0 ata1: enabled=0
ata2: enabled=0 ata2: enabled=0
ata3: enabled=0 ata3: enabled=0
parport1: enabled=1, file="" parport1: enabled=1, file="parallel.out"
com1: enabled=1, dev="" com1: enabled=1, dev=""
usb1: enabled=1, ioaddr=0xff80, irq=10 usb1: enabled=1, ioaddr=0xff80, irq=10
# no sb16 # no sb16

View File

@ -14,7 +14,7 @@ all:
clean: clean:
- make -C kernel clean - make -C kernel clean
- make -C rmmod clean - make -C rmmod clean
- rm *~ hos.flp - rm *~ *.out hos.flp \#*
grub: grub:

View File

@ -16,7 +16,9 @@ LD=ld
LD_FLAGS=-nodefaultlibs -nostdlib --no-demangle -T link.ld LD_FLAGS=-nodefaultlibs -nostdlib --no-demangle -T link.ld
all: Asm_Kernel C_Kernel all: Asm_Kernel C_Kernel
$(LD) $(LD_FLAGS) -Map kernel.map boot.o kernel.o asmfuncs.o mm.o vmm.o -o kernel.bin $(LD) $(LD_FLAGS) -Map kernel.map boot.o \
kernel.o asmfuncs.o mm.o vmm.o parallel.o \
conv.o kout.o -o kernel.bin
Asm_Kernel: Asm_Kernel:
$(NASM) $(NASM_FLAGS) -l boot.lst boot.asm -o boot.o $(NASM) $(NASM_FLAGS) -l boot.lst boot.asm -o boot.o
@ -26,11 +28,14 @@ C_Kernel:
$(CC) $(CC_FLAGS) -c kernel.c -o kernel.o $(CC) $(CC_FLAGS) -c kernel.c -o kernel.o
$(CC) $(CC_FLAGS) -c mm/mm.c -o mm.o $(CC) $(CC_FLAGS) -c mm/mm.c -o mm.o
$(CC) $(CC_FLAGS) -c mm/vmm.c -o vmm.o $(CC) $(CC_FLAGS) -c mm/vmm.c -o vmm.o
$(CC) $(CC_FLAGS) -c char/parallel.c -o parallel.o
$(CC) $(CC_FLAGS) -c lang/conv.c -o conv.o
$(CC) $(CC_FLAGS) -c kout.c -o kout.o
################################################# #################################################
# Clean up the source directory of any binaries # # Clean up the source directory of any binaries #
################################################# #################################################
clean: clean:
- rm *.o *.bin *.map *.lst *~ - rm *.o *.bin *.map *.lst *.out *~

44
kernel/char/console.c Normal file
View File

@ -0,0 +1,44 @@
// console.c
// Author: Josh Holtrop
// Date: 08/02/04
#include "char/console.h"
#include "hos_defines.h"
#include "fs/devices.h"
console_t *consoles[256];
int console_new(minor_t minor)
{
if (consoles[minor])
return -1; // minor already taken
if ( consoles[minor] = kmalloc(sizeof(console_t)) )
{
consoles[minor]->cursorPosition = 0;
consoles[minor]->width = 80;
consoles[minor]->height = 25;
consoles[minor]->attribute = 0x07;
if (consoles[minor]->buffer = kmalloc(4000))
{
memsetw(consoles[minor]->buffer, 0, 2000);
}
else
{
kfree (consoles[minor]);
consoles[minor] = 0;
return -3; // couldn't allocate memory
}
return 0;
}
else
return -2; // couldn't allocate memory
}
void console_outb(minor_t id, int c)
{
if (!consoles[minor])
return;
}

24
kernel/char/console.h Normal file
View File

@ -0,0 +1,24 @@
// console.h
// Author: Josh Holtrop
// Date: 08/02/04
#ifndef __HOS_CONSOLE__
#define __HOS_CONSOLE__ __HOS_CONSOLE__
#include "hos_defines.h"
#include "fs/devices.h"
typedef struct
{
u32_t cursorPosition;
u16_t width;
u16_t height;
u8_t attribute;
u16_t *buffer;
} console_t;
int console_new(minor_t minor);
void console_outb(minor_t id, int c);
#endif

247
kernel/char/keyboard.c Normal file
View File

@ -0,0 +1,247 @@
// keyboard.c
// Author: Josh Holtrop
// Created: 04/17/03
// Modified: 08/02/04
#include "hos_defines.h"
#include "char/keyboard.h"
#include "sys/io.h"
#include "sys/pic.h"
#include "functions.h"
#include "kio.h"
#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[129] = "\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[129] = "\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;
pic_eoi();
return;
}
if (kbdScan == 225) //2nd-set-extended key
{
kbdExt2 = 2;
pic_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--;
pic_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
{
pic_eoi();
return;
}
if (kbdScan < KBD_SCAN_RELEASED) //a key was pressed, save it
{
if (kbdBufferLen >= KBD_BUFFER_LENGTH) //no key slots available
{
pic_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]);
}
}
pic_eoi();
}
//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
void kbd_resetLEDs()
{
outportb(0x60, 0xED);
ackReason = 0xED;
}

49
kernel/char/keyboard.h Normal file
View File

@ -0,0 +1,49 @@
// keyboard.h
// Author: Josh Holtrop
// Created: 04/17/03
// Modified: 08/02/04
#include "hos_defines.h"
#ifndef __HOS_KEYBOARD__
#define __HOS_KEYBOARD__ __HOS_KEYBOARD__
#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();
void kbd_resetLEDs();
u32_t kbdGetKey();
u32_t kbdWaitKey();
#endif

52
kernel/char/mouse.c Normal file
View File

@ -0,0 +1,52 @@
// mouse.c
// Author: Josh Holtrop
// Date: 10/03/03
// Modified: 08/02/04
#include "hos_defines.h"
#include "char/mouse.h"
#include "video/video.h"
#include "sys/io.h"
int mouse_bytesRead;
byte mouse_inbuffer[MOUSE_BUFFER_LENGTH];
//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_bytesRead = 0;
//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];
// TODO: do something with adjx, adjy...
}
}

15
kernel/char/mouse.h Normal file
View File

@ -0,0 +1,15 @@
// mouse.h
// Author: Josh Holtrop
// Date: 10/03/03
// Modified: 08/02/04
#ifndef __HOS_MOUSE__
#define __HOS_MOUSE__ __HOS_MOUSE__
#define MOUSE_BUFFER_LENGTH 16
void mouse_init();
void isr_mouse();
#endif

15
kernel/char/parallel.c Normal file
View File

@ -0,0 +1,15 @@
// parallel.c
// Author: Josh Holtrop
// Date: 08/02/04
#include "hos_defines.h"
#include "functions.h"
#include "parallel.h"
void outparb(int c)
{
outportb(0x37a, 0xc);
outportb(0x378, c);
outportb(0x37a, 0x1);
}

13
kernel/char/parallel.h Normal file
View File

@ -0,0 +1,13 @@
// parallel.h
// Author: Josh Holtrop
// Date: 08/02/04
#ifndef __HOS_PARALLEL__
#define __HOS_PARALLEL__ __HOS_PARALLEL__
#include "hos_defines.h"
void outparb(int c);
#endif

View File

@ -1,3 +1,7 @@
// devices.c
// Author: Josh Holtrop
// Date: 08/02/04
#include "fs/devices.h" #include "fs/devices.h"
#include "kernel.h" #include "kernel.h"

View File

@ -1,3 +1,6 @@
// devices.h
// Author: Josh Holtrop
// Date: 08/02/04
#ifndef __HOS_DEVICES_H__ #ifndef __HOS_DEVICES_H__

View File

@ -2,6 +2,7 @@
#ifndef __HOS_DEFINES_H__ #ifndef __HOS_DEFINES_H__
#define __HOS_DEFINES_H__ __HOS_DEFINES_H__ #define __HOS_DEFINES_H__ __HOS_DEFINES_H__
#define PARALLEL_DEBUG
#define VIRT_OFFSET 0xC0000000 #define VIRT_OFFSET 0xC0000000
#define PHYS_LOAD 0x00108000 #define PHYS_LOAD 0x00108000

View File

@ -2,10 +2,13 @@
#include "kernel.h" #include "kernel.h"
#include "multiboot.h" #include "multiboot.h"
#include "module.h" #include "module.h"
#include "asmfuncs.h" #include "lang/asmfuncs.h"
#include "functions.h" #include "functions.h"
#include "mm/mm.h" #include "mm/mm.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "char/parallel.h"
#include "kout.h"
#include "lang/conv.h"
mb_info_t mb_info_block; mb_info_t mb_info_block;
mb_mmap_t mb_mmap[MAX_MMAP]; mb_mmap_t mb_mmap[MAX_MMAP];
@ -16,6 +19,8 @@ byte real_mode_module;
char mb_cmdline[256]; char mb_cmdline[256];
int criticalCounter; int criticalCounter;
extern u32_t mm_freepages;
/* This function runs in segmented memory - 0xC000_0000 is mapped to 0x0 but 0x0 /* 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 itself is an invalid linear address. Therefore, the multiboot information addresses
must be manually adjusted by VIRT_OFFSET to become valid linear addresses. */ must be manually adjusted by VIRT_OFFSET to become valid linear addresses. */
@ -56,14 +61,14 @@ int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic)
} }
if (mb_info_block.flags & MB_BOOTLOADER_MMAP) 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_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; mb_mmap_t *mmap = (mb_mmap_t *)mb_info_block.mmap_addr;
int i, sz = 0; int i, sz = 0;
for (i = 0; sz < mb_info_block.mmap_length && i < MAX_MMAP; i++) for (i = 0; sz < mb_info_block.mmap_length && i < MAX_MMAP; i++)
{ {
sz += mmap->size; sz += mmap->size + 4;
mb_mmap[i] = *mmap; mb_mmap[i] = *mmap;
mmap = (mb_mmap_t *)(((u32_t) mmap) + mmap->size); mmap = (mb_mmap_t *)(((u32_t) mmap) + mmap->size + 4);
mmap_entries++; mmap_entries++;
} }
} }
@ -78,27 +83,50 @@ int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic)
/* Main kernel initialization routine */ /* Main kernel initialization routine */
void k_init() void k_init()
{ {
kprintf("k_init()\n");
k_enter_critical(); k_enter_critical();
mm_init(); mm_init();
vmm_init(); vmm_init();
if (real_mode_module) if (real_mode_module)
{ {
(*(char*)(CONSOLE_MEMORY+40))++; kprintf("Real mode module present\n");
} }
u32_t *ptr = kmalloc(sizeof(u32_t)); u32_t alloc_size = 1;
BOCHS_DEBUG(50, (u32_t)ptr); void *addresses[32];
*ptr = 42; memsetd(addresses, 0, 32);
while (*ptr == 42); void *address;
kfree(ptr); int i;
for (i = -5; i < 5; i++)
{
kprintf("Counting down... %d\t0x%x\t%u\n", i, i, i);
}
for (i = 0; i < 32; i++)
{
kprintf("\e[31mAllocating %u (0x%x) bytes\e[0m,\tmm_freepages = %u...\n", alloc_size, alloc_size, mm_freepages);
address = kmalloc(alloc_size);
if (!address)
break;
addresses[i] = address;
alloc_size <<= 1;
}
for (i = 0; i < 32; i++)
{
if (!addresses[i])
break;
kprintf("\e[32mFreeing 0x%x\e[0m,\tmm_freepages = %u...\n", addresses[i], mm_freepages);
kfree(addresses[i]);
}
// dev_init(); // dev_init();
BOCHS_DEBUG(0, 0xdeadbeef); kprintf("End of k_init()\n");
criticalCounter--; criticalCounter--;
} }
void isr(u32_t num) void isr(u32_t num)
{ {
criticalCounter++; criticalCounter++;
BOCHS_DEBUG(158, 0xbeef1234); kprintf("Interrupt #%d!\n", num);
halt();
switch (num) switch (num)
{ {
@ -120,10 +148,3 @@ void k_leave_critical()
enable_ints(); enable_ints();
} }
void BOCHS_DEBUG(u32_t pos, u32_t param)
{
for (;;)
{
(*(char*)(0xC00B8000+pos))++;
}
}

122
kernel/kout.c Normal file
View File

@ -0,0 +1,122 @@
// kout.c
// Author: Josh Holtrop
// Date: 08/02/04
#include "hos_defines.h"
#include "char/parallel.h"
#include "kout.h"
#include "lang/conv.h"
char buffer[64];
// print a character
void putc(int c)
{
#ifdef PARALLEL_DEBUG
outparb(c);
#endif
}
// print a formatted string
void kprintf(char *fmt, ...)
{
u32_t *params = ((u32_t *)(&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': case 'i': case 'I':
putDec(*params);
params++;
break;
case 'u': case 'U':
putDecu(*params);
params++;
break;
case 'x': case 'X':
putHex(*params);
params++;
break;
case 'b': case 'B':
kio_putBCD(*params);
params++;
break;
}
}
else
{
switch (fmt[i])
{
case '%':
special = 1;
break;
case 0:
return;
default:
putc(fmt[i]);
}
}
}
}
// This function prints a raw string
void puts(char *str)
{
while (*str)
{
putc(*str++);
}
}
// This function prints a signed, decimal integer
void putDec(int num)
{
itoa(num, buffer);
puts(buffer);
}
// This function prints an unsigned, decimal integer
void putDecu(u32_t num)
{
utoa(num, buffer);
puts(buffer);
}
// This function displays a number in hexadecimal
void putHex(u32_t num)
{
itox(num, buffer);
puts(buffer);
}
// This function prints a two-digit binary-coded-decimal value
void kio_putBCD(u32_t bcd)
{
bcdtoa(bcd, buffer);
}

19
kernel/kout.h Normal file
View File

@ -0,0 +1,19 @@
// kout.h
// Author: Josh Holtrop
// Date: 08/02/04
#ifndef __HOS_KOUT__
#define __HOS_KOUT__ __HOS_KOUT__
#include "hos_defines.h"
void printf(char *fmt, ...);
void putHex(u32_t number);
void kio_putBCD(u32_t bcd);
void putc(int c);
void puts(char *str);
void putDec(int num);
void putDecu(u32_t num);
#endif

83
kernel/lang/conv.c Normal file
View File

@ -0,0 +1,83 @@
// conv.h
// Author: Josh Holtrop
// Date: 08/02/04
#include "conv.h"
#include "hos_defines.h"
// BCD to string
// returns number of characters generated before null terminator
int bcdtoa(u32_t bcd, char *buf)
{
*buf++ = ((bcd & 0xF0) >> 4) + '0';
*buf++ = (bcd & 0xF) + '0';
*buf = 0;
return 2;
}
// convert integer to hexadecimal string
int itox(u32_t num, char *buf)
{
int s, i = 0;
for (s = 28; s >= 0; s -= 4)
{
u32_t val = (num >> s) & 0xF;
if (i || val || (!s))
{
val = (val > 9) ? (val + 'A' - 10) : (val + '0');
buf[i++] = val;
}
}
buf[i] = 0;
return i - 1;
}
// convert signed integer to decimal string
int itoa(int num, char *buf)
{
// 4,294,967,296
int hitNum = 0, i = 0, mod, val;
if (num < 0)
{
buf[i++] = '-';
num = -num;
}
for (mod = 1000000000; mod >= 1; mod /= 10)
{
val = num / mod;
num %= mod;
if (val || (mod == 1))
hitNum = 1;
if (hitNum)
{
buf[i++] = val + '0';
}
}
buf[i] = 0;
return i - 1;
}
// convert an unsigned integer to decimal string
int utoa(u32_t num, char *buf)
{
// 4,294,967,296
int hitNum = 0, i = 0, mod, val;
for (mod = 1000000000; mod >= 1; mod /= 10)
{
val = num / mod;
num %= mod;
if (val || (mod == 1))
hitNum = 1;
if (hitNum)
{
buf[i++] = val + '0';
}
}
buf[i] = 0;
return i - 1;
}

16
kernel/lang/conv.h Normal file
View File

@ -0,0 +1,16 @@
// conv.h
// Author: Josh Holtrop
// Date: 08/02/04
#ifndef __HOS_CONV__
#define __HOS_CONV__ __HOS_CONV__
#include "hos_defines.h"
int bcdtoa(u32_t bcd, char *buf);
int itox(u32_t num, char *buf);
int itoa(int num, char *buf);
int utoa(u32_t num, char *buf);
#endif

View File

@ -7,7 +7,7 @@
#include "hos_defines.h" #include "hos_defines.h"
#include "kernel.h" #include "kernel.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "asmfuncs.h" #include "lang/asmfuncs.h"
#include "mm/mm.h" #include "mm/mm.h"
int vmm_map(void *virt); int vmm_map(void *virt);
@ -31,7 +31,7 @@ extern mb_info_t mb_info_block;
extern mb_module_t mb_modules[MAX_MODULES]; extern mb_module_t mb_modules[MAX_MODULES];
extern u32_t mm_freepages; extern u32_t mm_freepages;
HeapEntryQueue_t heapEntryQueues[VMM_HE_TYPES]; // linked queue of HeapEntry objects HeapEntryQueue_t heapEntryQueues[VMM_HE_TYPES]; // linked queues of HeapEntry objects
HeapEntry_t heapEntryHeadNodes[VMM_HE_TYPES]; // head nodes for linked queues HeapEntry_t heapEntryHeadNodes[VMM_HE_TYPES]; // head nodes for linked queues
HeapEntry_t heapEntryTailNodes[VMM_HE_TYPES]; // tail nodes for linked queues HeapEntry_t heapEntryTailNodes[VMM_HE_TYPES]; // tail nodes for linked queues
HeapEntryBlock_t initialHEB; // block for initial 256 HeapEntry objects HeapEntryBlock_t initialHEB; // block for initial 256 HeapEntry objects
@ -62,10 +62,9 @@ void vmm_init()
/* Allocate a physical page and map the virtual address to it, return physical address allocated or NULL */ /* Allocate a physical page and map the virtual address to it, return physical address allocated or NULL */
int vmm_map(void *virt) int vmm_map(void *virt)
{ {
if (mm_freepages < 10); if (mm_freepages < 10)
return -1; return -1;
vmm_map1((u32_t)virt, mm_palloc()); return vmm_map1((u32_t)virt, mm_palloc());
return 0;
} }
@ -79,7 +78,7 @@ int vmm_map1(u32_t virt, u32_t physical)
{ {
u32_t newpagetable; u32_t newpagetable;
if (!(newpagetable = mm_palloc())) if (!(newpagetable = mm_palloc()))
return 1; //out of physical memory return -1; //out of physical memory
pageTables[pde] = newpagetable | 0x03; pageTables[pde] = newpagetable | 0x03;
invlpg_(virt); //in case it was cached, so we can fill page table safely invlpg_(virt); //in case it was cached, so we can fill page table safely
memsetd((void*)(0xFFC00000 | (pde << 12)), 0, 1024); //zero out new page table memsetd((void*)(0xFFC00000 | (pde << 12)), 0, 1024); //zero out new page table
@ -194,7 +193,7 @@ void *vmm_palloc()
k_enter_critical(); k_enter_critical();
HeapEntry_t *he = heapEntryQueues[VMM_HE_HOLE].head->next; HeapEntry_t *he = heapEntryQueues[VMM_HE_HOLE].head->next;
HeapEntry_t *wilderness = he; HeapEntry_t *wilderness = he;
while (he) while (he->next)
{ {
if (he->length == 4096) if (he->length == 4096)
{ {
@ -229,15 +228,11 @@ int vmm_pfree(void *addr)
{ {
k_enter_critical(); k_enter_critical();
HeapEntry_t *he = heapEntryQueues[VMM_HE_USED].head->next; HeapEntry_t *he = heapEntryQueues[VMM_HE_USED].head->next;
while (he) while (he->next)
{ {
if (he->base == addr) //found the page to free if (he->base == addr) //found the page to free
{ {
((HeapEntry_t *)he->prev)->next = he->next; vmm_removeHeapEntry(VMM_HE_USED, he);
((HeapEntry_t *)he->next)->prev = he->prev;
heapEntryQueues[VMM_HE_USED].count--;
he->next = NULL;
he->prev = NULL;
vmm_unmap1((u32_t)he->base); vmm_unmap1((u32_t)he->base);
vmm_addToQueue(VMM_HE_HOLE, &heapEntryHeadNodes[VMM_HE_HOLE], he); vmm_addToQueue(VMM_HE_HOLE, &heapEntryHeadNodes[VMM_HE_HOLE], he);
k_leave_critical(); k_leave_critical();
@ -377,7 +372,8 @@ int vmm_coalesceEntry(u32_t queue, HeapEntry_t *newHE)
} }
else if ((newHE->base + newHE->length) == existing->base) else if ((newHE->base + newHE->length) == existing->base)
{ {
existing->base -= newHE->length; existing->base = newHE->base;
existing->length += newHE->length;
return 0; return 0;
} }
existing = (HeapEntry_t *)existing->next; existing = (HeapEntry_t *)existing->next;