diff --git a/kernel/functions.h b/kernel/functions.h new file mode 100644 index 0000000..025c6be --- /dev/null +++ b/kernel/functions.h @@ -0,0 +1,94 @@ +//functions.h +//05/07/03 Josh Holtrop +//for HOS +//Modified: 02/26/04 + +#ifndef __HOS_FUNCTIONS__ +#define __HOS_FUNCTIONS__ __HOS_FUNCTIONS__ + +#include "hos_defines.h" +#include "sys/io.h" + +extern dword _code; +extern dword _bss; +extern dword _end; + +//Enables (SeTs) Interrupt Flag on the processor +static inline void enable_ints() +{ + asm("sti"); +} + +//Disables (CLears) Interrupt Flag on the processor +static inline void disable_ints() +{ + asm("cli"); +} + +//Restarts the computer +static 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 +static inline void halt() +{ + asm("cli"); + asm("hlt"); + while (1) ; +} + +//Initializes 8253 Programmable Interrupt Timer +static inline void timer_init() +{ + //set timer : 2e9c = 100hz + outportb(0x43, 0x34); + outportb(0x40, 0x9c); //lsb + outportb(0x40, 0x2e); //msb +} + +//Returns the size of the kernel (code & data) +// - this does include the bss section +// - this should be 4kb aligned per the linker script +// - this is the amount of RAM the kernel code, data, & bss take +static inline dword kernel_size_used() +{ + return (dword)(&_end)-(dword)(&_code); +} + +//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 +static inline dword kernel_size() +{ + return (dword)(&_bss)-(dword)(&_code); +} + +//converts a binary-coded-decimal byte to its decimal equivalent +static inline byte bcd2byte(byte bcd) +{ + return (10 * ((bcd & 0xF0) >> 4)) + (bcd & 0x0F); +} + +//converts a binary-coded-decimal byte to its decimal equivalent +static inline byte byte2bcd(byte bite) +{ + return ((bite / 10) << 4) | (bite % 10); +} + +#endif + + diff --git a/kernel/kernel.c b/kernel/kernel.c index b8f4e5d..8aa347f 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -3,6 +3,7 @@ #include "multiboot.h" #include "module.h" #include "asmfuncs.h" +#include "functions.h" #include "mm/mm.h" #include "mm/vmm.h" @@ -13,6 +14,7 @@ mb_module_t mb_modules[MAX_MODULES]; mb_apm_t mb_apm_table; byte real_mode_module; char mb_cmdline[256]; +int criticalCounter; /* 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 @@ -104,3 +106,16 @@ void isr(u32_t num) } } +void k_enter_critical() // functions for implementing "atomic actions" +{ + disable_ints(); + criticalCounter++; +} + +void k_leave_critical() +{ + criticalCounter--; + if (!criticalCounter) + enable_ints(); +} + diff --git a/kernel/kernel.h b/kernel/kernel.h index 67a6163..271a531 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -6,19 +6,19 @@ #include "multiboot.h" typedef struct { - void *vid_addr; //address of LFB, 0 if console mode - u32_t width; //width in pixels or columns if vid_mem == 0 - u32_t height; //height in pixels or columns if vid_mem == 0 - u32_t vid_mem; //amount of memory for video buffer - u32_t bpp; //bits per pixel - 16/24/32 + void *vid_addr; // address of LFB, 0 if console mode + u32_t width; // width in pixels or columns if vid_mem == 0 + u32_t height; // height in pixels or columns if vid_mem == 0 + u32_t vid_mem; // amount of memory for video buffer + u32_t bpp; // bits per pixel - 16/24/32 } __attribute__ ((packed)) real_mode_param_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(); +void k_enter_critical(); // functions for implementing "atomic actions" +void k_leave_critical(); #endif diff --git a/kernel/mm/vmm.c b/kernel/mm/vmm.c index 021f4bb..15ba8a4 100644 --- a/kernel/mm/vmm.c +++ b/kernel/mm/vmm.c @@ -5,6 +5,7 @@ // Modified: 07/13/04 #include "hos_defines.h" +#include "kernel.h" #include "mm/vmm.h" #include "asmfuncs.h" #include "mm/mm.h" @@ -24,7 +25,13 @@ void vmm_init() int i; for (i = 0; i < mb_info_block.mods_count; i++) //page in the kernel modules vmm_map_range((void*)mb_modules[i].mod_start, (void*)mb_modules[i].mod_end- 1, mb_modules[i].mod_start - VIRT_OFFSET); - + vmm_heb_init(initialHEB); + vmm_addToQueue(VMM_HE_UNUSED, initialHEB[0]); + HeapEntry_t *wilderness = vmm_stripUnusedEntry(); + wilderness->base = HEAP_START; + wilderness->length = HEAP_LENGTH; + wilderneww->next = 0; + vmm_addToQueue(VMM_HE_HOLE, wilderness); } @@ -40,32 +47,33 @@ u32_t vmm_map(void *virt) // This function maps a virtual address to a physical address using the page directory / page table -void vmm_map1(unsigned int virt, unsigned int physical) +int vmm_map1(unsigned int virt, unsigned int physical) { unsigned int pde = virt >> 22; unsigned int pte = (virt & 0x003FF000) >> 12; unsigned int *pageTables = (unsigned int *)0xFFFFF000; //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 + if (!(pageTables[pde] & 0x01)) //the page directory entry is not present, we must allocate a page table { - u32_t newpagetable = mm_palloc(); + u32_t newpagetable; + if (!(newpagetable = mm_palloc()) + return 1; //out of physical memory pageTables[pde] = newpagetable | 0x03; invlpg_(virt); //in case it was cached, so we can fill page table safely - unsigned int *newpteptr = (unsigned int *)(0xFFC00000 | (pde << 12)); //points to first unsigned int of newly allocated page table - int a; - for (a = 0; a < 1024; a++) - *newpteptr++ = 0; + memsetd((void*)(0xFFC00000 | (pde << 12)), 0, 1024); //zero out new page table } *(unsigned int *)(0xFFC00000 | (pde << 12) | (pte << 2)) = (physical & 0xFFFFF000) | 0x03; invlpg_(virt); + return 0; } // This function maps a variable number of pages in a row -void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n) +int vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n) { while (n > 0) { - vmm_map1(virt, physical); + if (vmm_map1(virt, physical)) + return 1; // error mapping page virt += 4096; physical += 4096; n--; @@ -96,10 +104,11 @@ void vmm_unmapn(unsigned int virt, unsigned int n) int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start) { if (virt_end < virt_start) - return 1; //invalid region + return 1; // invalid region while (virt_start < virt_end) { - vmm_map1((u32_t)virt_start, phys_start); + if (vmm_map1((u32_t)virt_start, phys_start)) + return 2; // out of memory virt_start += 4096; phys_start += 4096; } @@ -107,6 +116,20 @@ int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start) } +void *kmalloc(u32_t size) +{ + k_enter_critical(); + k_leave_critical(); +} + + +void *vmm_palloc() +{ + k_enter_critical(); + k_leave_critical(); +} + + // This function allocates and zeros memory for the given number of objects, // given the size of each object /* @@ -158,7 +181,6 @@ int vmm_countHeapEntries(HeapEntry_t *he) } - // This function follows a chain of HeapEntry objects and returns a pointer to the last one HeapEntry_t *vmm_followChain(HeapEntry_t *he) { @@ -169,18 +191,24 @@ HeapEntry_t *vmm_followChain(HeapEntry_t *he) // This function breaks an unused chunk from its queue and returns a pointer to it -HeapEntry_t *vmm_getUnusedChunk() +HeapEntry_t *vmm_getUnusedEntry() { if (heapEntryQueues[VMM_HE_UNUSED].count < 5) { - heapEntryQueues[VMM_HE_UNUSED].count += 256;//not good idea - HeapEntryBlock_t *newHEB = vmm_palloc(); //INFINITE LOOP? - vmm_mcb_init(newHEB); + HeapEntry_t *wilderness = vmm_followChain( + HeapEntryBlock_t *newHEB; + vmm_heb_init(newHEB); vmm_addToQueue(VMM_HE_UNUSED, newHEB); - heapEntryQueues[VMM_HE_UNUSED].count -= 256; } + return vmm_stripUnusedEntry(); +} + + +// Return pointer to an unused HeapEntry object, ASSUMES THERE IS ONE PRESENT IN QUEUE +HeapEntry_t *vmm_stripUnusedEntry() +{ HeapEntry_t *he = heapEntryQueues[VMM_HE_UNUSED].start; - heapEntryQueues[VMM_HE_UNUSED].start = he->link; + heapEntryQueues[VMM_HE_UNUSED].start = he->next; heapEntryQueues[VMM_HE_UNUSED].count--; return he; } diff --git a/kernel/mm/vmm.h b/kernel/mm/vmm.h index 1481c3d..13fec1c 100644 --- a/kernel/mm/vmm.h +++ b/kernel/mm/vmm.h @@ -27,7 +27,6 @@ typedef struct { u32_t padding; } __attribute__((packed)) HeapEntry_t; - typedef struct { HeapEntry_t entry[256]; //256 HeapEntry objects = 4kb (1 page) } __attribute__((packed)) HeapEntryBlock_t; @@ -37,10 +36,11 @@ typedef struct { HeapEntry_t *start; } HeapEntryQueue_t; + void vmm_init(); u32_t vmm_map(void *virt); -void vmm_map1(unsigned int virt, unsigned int physical); -void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n); +int vmm_map1(unsigned int virt, unsigned int physical); +int vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n); void vmm_unmap1(unsigned int virt); void vmm_unmapn(unsigned int virt, unsigned int n); int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start); diff --git a/kernel/sys/cmos.cpp b/kernel/sys/cmos.cpp new file mode 100644 index 0000000..827f32a --- /dev/null +++ b/kernel/sys/cmos.cpp @@ -0,0 +1,42 @@ +// cmos.c +// Author: Josh Holtrop +// Created: 02/26/04 +// Implements various CMOS function calls + +#include "hos_defines.h" +#include "sys/cmos.h" +#include "sys/io.h" + +//Returns the cmos type of floppy disk drive 0 (0 = not present) +unsigned char cmos_getfd0() +{ + outportb(0x70, 0x10); + return (inportb(0x71) >> 4); +} + + +//Returns the cmos type of floppy disk drive 1 (0 = not present) +unsigned char cmos_getfd1() +{ + outportb(0x70, 0x10); + return (inportb(0x71) & 0x0F); +} + + +//Returns the cmos type of hard disk drive 0 (0 = not present) +unsigned char cmos_gethd0() +{ + outportb(0x70, 0x12); + return (inportb(0x71) >> 4); +} + + +//Returns the cmos type of hard disk drive 1 (0 = not present) +unsigned char cmos_gethd1() +{ + outportb(0x70, 0x12); + return (inportb(0x71) & 0x0F); +} + + + diff --git a/kernel/sys/cmos.h b/kernel/sys/cmos.h new file mode 100644 index 0000000..cf5ce52 --- /dev/null +++ b/kernel/sys/cmos.h @@ -0,0 +1,18 @@ +// cmos.h +// Author: Josh Holtrop +// Created: 02/26/04 +// Implements various CMOS function calls + +#include "hos_defines.h" + +#ifndef __HOS_CMOS__ +#define __HOS_CMOS__ __HOS_CMOS__ + +unsigned char cmos_getfd0(); +unsigned char cmos_getfd1(); +unsigned char cmos_gethd0(); +unsigned char cmos_gethd1(); + +#endif + + diff --git a/kernel/sys/io.cpp b/kernel/sys/io.cpp new file mode 100644 index 0000000..3993d10 --- /dev/null +++ b/kernel/sys/io.cpp @@ -0,0 +1,8 @@ +// io.c +// Author: Josh Holtrop +// Created: 02/26/04 +// Implements basic port input/output functions + +#include "sys/io.h" + + diff --git a/kernel/sys/io.h b/kernel/sys/io.h new file mode 100644 index 0000000..b77bef1 --- /dev/null +++ b/kernel/sys/io.h @@ -0,0 +1,40 @@ +// io.h +// Author: Josh Holtrop +// Created: 02/26/04 +// Implements basic port input/output functions + +#ifndef __HOS_IO__ +#define __HOS_IO__ __HOS_IO__ + +#include "hos_defines.h" + +//void outportb(unsigned int port, unsigned char value); +//inline void outportw(unsigned int port, unsigned int value); +//inline unsigned char inportb(unsigned short port); + +//Writes a byte out to a port +static 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 +static 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 +static inline unsigned char inportb(unsigned short port) +{ + unsigned char ret_val; + + asm volatile("inb %w1,%b0" + : "=a"(ret_val) + : "d"(port)); + return ret_val; +} + +#endif + + diff --git a/kernel/sys/pic.cpp b/kernel/sys/pic.cpp new file mode 100644 index 0000000..310ff60 --- /dev/null +++ b/kernel/sys/pic.cpp @@ -0,0 +1,30 @@ +// pic.c +// Author: Josh Holtrop +// Created: 02/26/04 + +#include "hos_defines.h" +#include "pic.h" +#include "sys/io.h" + +//Re-maps the Programmable Interrupr Controllers so IRQ0->pic1 base address, IRG8->pic2 base address +void pic_remap(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 +} + + diff --git a/kernel/sys/pic.h b/kernel/sys/pic.h new file mode 100644 index 0000000..c363732 --- /dev/null +++ b/kernel/sys/pic.h @@ -0,0 +1,65 @@ +// pic.h +// Author: Josh Holtrop +// Created: 02/26/04 + +#ifndef __HOS_PIC__ +#define __HOS_PIC__ __HOS_PIC__ + +#include "hos_defines.h" +#include "sys/io.h" + +#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) */ + +void pic_remap(int pic1, int pic2); +//inline void pic_mask1(byte mask); +//inline void pic_mask2(byte mask); +//inline void pic_eoi(); +//inline void pic_eoi2(); + +//Masks interrupts on first Programmable Interrupt Controller +static inline void pic_mask1(byte mask) +{ + outportb(PIC1_DATA, mask); //0x21, maskfield *OCW1* +} + +//Masks interrupts on second Programmable Interrupt Controller +static inline void pic_mask2(byte mask) +{ + outportb(PIC2_DATA, mask); //0xA1, maskfield *OCW1* +} + + +//Signals an End Of Interrupt signal to the first PIC +static inline void pic_eoi() +{ + outportb(0x20, 0x20); +} + +//Signals an End Of Interrupt signal to both the second and first PIC unit +static inline void pic_eoi2() +{ + outportb(0xA0, 0x20); + outportb(0x20, 0x20); +} + +#endif + + diff --git a/kernel/sys/rtc.cpp b/kernel/sys/rtc.cpp new file mode 100644 index 0000000..d0cd1ad --- /dev/null +++ b/kernel/sys/rtc.cpp @@ -0,0 +1,83 @@ +// rtc.c +// Author: Josh Holtrop +// Created: 02/26/04 +// Implements Real-Time Clock function calls +// These functions are for reading and writing various values stored on the CMOS Real Time Clock +// Parameters / return values are in BCD format + +#include "hos_defines.h" +#include "sys/rtc.h" +#include "sys/io.h" + +unsigned char rtc_readDay() +{ + outportb(0x70, 7); + return inportb(0x71); +} + +unsigned char rtc_readMonth() +{ + outportb(0x70, 8); + return inportb(0x71); +} + +unsigned char rtc_readYear() +{ + outportb(0x70, 9); + return inportb(0x71); +} + +unsigned char rtc_readSecond() +{ + outportb(0x70, 0); + return inportb(0x71); +} + +unsigned char rtc_readMinute() +{ + outportb(0x70, 2); + return inportb(0x71); +} + +unsigned char rtc_readHour() +{ + outportb(0x70, 4); + return inportb(0x71); +} + +void rtc_setDay(unsigned char day) +{ + outportb(0x70, 7); + outportb(0x71, day); +} + +void rtc_setMonth(unsigned char month) +{ + outportb(0x70, 8); + outportb(0x71, month); +} + +void rtc_setYear(unsigned char year) +{ + outportb(0x70, 9); + outportb(0x71, year); +} + +void rtc_setSecond(unsigned char second) +{ + outportb(0x70, 0); + outportb(0x71, second); +} + +void rtc_setMinute(unsigned char minute) +{ + outportb(0x70, 2); + outportb(0x71, minute); +} + +void rtc_setHour(unsigned char hour) +{ + outportb(0x70, 4); + outportb(0x71, hour); +} + diff --git a/kernel/sys/rtc.h b/kernel/sys/rtc.h new file mode 100644 index 0000000..3c589de --- /dev/null +++ b/kernel/sys/rtc.h @@ -0,0 +1,28 @@ +// rtc.h +// Author: Josh Holtrop +// Created: 02/26/04 +// Implements Real-Time Clock function calls +// These functions are for reading and writing various values stored on the CMOS Real Time Clock +// Parameters / return values are in BCD format + +#ifndef __HOS_RTC__ +#define __HOS_RTC__ __HOS_RTC__ + +#include "hos_defines.h" + +unsigned char rtc_readDay(); +unsigned char rtc_readMonth(); +unsigned char rtc_readYear(); +unsigned char rtc_readSecond(); +unsigned char rtc_readMinute(); +unsigned char rtc_readHour(); +void rtc_setDay(unsigned char dat); +void rtc_setMonth(unsigned char month); +void rtc_setYear(unsigned char year); +void rtc_setSecond(unsigned char second); +void rtc_setMinute(unsigned char minute); +void rtc_setHour(unsigned char hour); + +#endif + +