Import backup from 2004-07-15

This commit is contained in:
Josh Holtrop 2004-07-15 22:00:00 -04:00
parent dfb71cc759
commit d4aadbea38
11 changed files with 390 additions and 22 deletions

BIN
hos.flp

Binary file not shown.

View File

@ -16,7 +16,7 @@ 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 asmfuncs.o mm.o -o kernel.bin
$(LD) $(LD_FLAGS) -Map kernel.map boot.o kernel.o asmfuncs.o mm.o vmm.o -o kernel.bin
Asm_Kernel:
$(NASM) $(NASM_FLAGS) -l boot.lst boot.asm -o boot.o
@ -25,11 +25,12 @@ Asm_Kernel:
C_Kernel:
$(CC) $(CC_FLAGS) -c kernel.c -o kernel.o
$(CC) $(CC_FLAGS) -c mm/mm.c -o mm.o
$(CC) $(CC_FLAGS) -c mm/vmm.c -o vmm.o
#################################################
# Clean up the source directory of any binaries #
#################################################
clean:
- rm -r *.o *.bin *~ *.map *.lst
- rm *.o *.bin *.map *.lst *~

View File

@ -97,6 +97,7 @@ pm_return:
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 [PDBR_V+0xFFC], dword PDBR_P|0x03 ;store the physical address of the page directory (identity map) | (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

View File

@ -5,9 +5,16 @@
#define VIRT_OFFSET 0xC0000000
#define PHYS_LOAD 0x00108000
#define HEAP_START 0xD0000000
#define HEAP_LENGTH 0x20000000
#define CONSOLE_MEMORY 0xC00B8000
#define MAX_MODULES 16
#define MAX_MMAP 16
#define NULL 0
typedef unsigned long long u64_t;
typedef unsigned int u32_t;
typedef unsigned short u16_t;

View File

@ -4,12 +4,14 @@
#include "module.h"
#include "asmfuncs.h"
#include "mm/mm.h"
#include "mm/vmm.h"
mb_info_t mb_info_block;
mb_mmap_t mb_mmap[MAX_MMAP];
u32_t mmap_entries;
mb_module_t mb_modules[MAX_MODULES];
mb_apm_t mb_apm_table;
byte real_mode_module;
char mb_cmdline[256];
/* This function runs in segmented memory - 0xC000_0000 is mapped to 0x0 but 0x0
@ -17,11 +19,11 @@ char mb_cmdline[256];
must be manually adjusted by VIRT_OFFSET to become valid linear addresses. */
int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic)
{
int retVal = 0;
real_mode_module = 0;
if (mb_magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
char *msg = "Bad multiboot magic identifier!";
char *dest = (char *) 0xC00B8000;
char *dest = (char *) CONSOLE_MEMORY;
while (*msg)
{
*dest++ = *msg++;
@ -47,7 +49,7 @@ int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic)
mb_modules[i].mod_end += VIRT_OFFSET;
hos_module_header_t *mod = (hos_module_header_t *)mb_modules[i].mod_start;
if (mod->mod_type == MOD_REAL_MODE)
retVal = 1;
real_mode_module = 1;
}
}
if (mb_info_block.flags & MB_BOOTLOADER_MMAP)
@ -68,24 +70,34 @@ int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic)
mb_info_block.apm_table += VIRT_OFFSET;
mb_apm_table = *(mb_apm_t *)mb_info_block.apm_table;
}
return retVal;
return real_mode_module;
}
/* Main kernel initialization routine */
void k_init()
{
mm_init();
// vmm_init();
vmm_init();
if (real_mode_module)
{
(*(char*)(CONSOLE_MEMORY+40))++;
}
// u32_t *ptr = malloc(sizeof(u32_t));
// *ptr = 42;
// while (*ptr == 42);
// dev_init();
for (;;)
{
(*(char*)0xC00B8000)++;
(*(char*)CONSOLE_MEMORY)++;
}
}
void isr(u32_t num)
{
for (;;) ;
for (;;)
{
(*(char*)(CONSOLE_MEMORY+158))++;
}
switch (num)
{

View File

@ -5,6 +5,14 @@
#include "hos_defines.h"
#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
} __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);

View File

@ -8,15 +8,16 @@
#include "multiboot.h"
#include "hos_defines.h"
u32_t mm_totalmem;
u32_t mm_megabytes;
u32_t mm_freepages;
u32_t mm_first_free_byte;
extern mb_info_t mb_info_block;
extern mb_mmap_t mb_mmap[MAX_MMAP];
extern u32_t mmap_entries;
extern mb_module_t mb_modules[MAX_MODULES];
byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
u32_t mm_totalmem;
u32_t mm_megabytes;
u32_t mm_freepages;
u32_t mm_first_free_byte;
byte page_bitmap[MM_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
@ -24,7 +25,7 @@ byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used,
void mm_init()
{
u32_t a;
for (a = 0; a < BITMAP_SIZE; a++) //mark all pages used
for (a = 0; a < MM_BITMAP_SIZE; a++) //mark all pages used
{
page_bitmap[a] = 0xFF;
}
@ -107,10 +108,10 @@ void mm_preserve(u32_t base)
// This function allocates a single page, returning its physical address
void *mm_palloc()
u32_t mm_palloc()
{
u32_t bite;
for (bite = mm_first_free_byte; bite < BITMAP_SIZE; bite++)
for (bite = mm_first_free_byte; bite < MM_BITMAP_SIZE; bite++)
{
if (page_bitmap[bite] != 0xFF) //there is an available page within this 8-page region
{
@ -122,7 +123,7 @@ void *mm_palloc()
mm_first_free_byte = bite; //start searching from here next time
mm_freepages--;
page_bitmap[bite] = page_bitmap[bite] | (1 << bit); //set page as used
return (void *)((bite << 15) | (bit << 12));
return ((bite << 15) | (bit << 12));
}
}
}
@ -132,12 +133,18 @@ void *mm_palloc()
// This function reports the number of bytes of free physical memory
u32_t mm_freemem()
u32_t mm_getFreeMem()
{
return mm_freepages << 12;
}
u32_t mm_getFreePages()
{
return mm_freepages;
}
u32_t mm_getTotalMem()
{
return mm_totalmem;

View File

@ -9,15 +9,16 @@
#include "kernel.h"
//The total amount of physical memory available (bytes, 1 bit per page)
#define BITMAP_SIZE 0x20000
#define MM_BITMAP_SIZE 0x20000
void mm_init();
void mm_pfreen(u32_t base, u32_t pages);
void mm_pfree(u32_t base);
void mm_preserven(u32_t base, u32_t pages);
void mm_preserve(u32_t base);
void *mm_palloc();
u32_t mm_freemem();
u32_t mm_palloc();
u32_t mm_getFreeMem();
u32_t mm_getFreePages();
u32_t mm_getTotalMem();
u32_t mm_getTotalMegs();

192
kernel/mm/vmm.c Normal file
View File

@ -0,0 +1,192 @@
// vmm.c
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03
// Modified: 07/13/04
#include "hos_defines.h"
#include "mm/vmm.h"
#include "asmfuncs.h"
#include "mm/mm.h"
extern mb_info_t mb_info_block;
extern mb_module_t mb_modules[MAX_MODULES];
extern u32_t mm_freepages;
HeapEntryQueue_t heapEntryQueues[VMM_HE_TYPES]; //sorted, linked queue of HeapEntry objects
HeapEntryBlock_t initialHEB; //block for initial 256 HeapEntry objects
// This is the initialization procedure for the Virtual Memory Manager
// It sets up the heap for dynamic memory allocation and virtual page allocation
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);
}
/* Allocate a physical page and map the virtual address to it, return physical address allocated or NULL */
u32_t vmm_map(void *virt)
{
u32_t phys = mm_palloc();
if (!phys);
return NULL;
vmm_map1((u32_t)virt, phys);
return phys;
}
// 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)
{
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
{
u32_t newpagetable = mm_palloc();
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;
}
*(unsigned int *)(0xFFC00000 | (pde << 12) | (pte << 2)) = (physical & 0xFFFFF000) | 0x03;
invlpg_(virt);
}
// This function maps a variable number of pages in a row
void vmm_mapn(unsigned int virt, unsigned int physical, unsigned int n)
{
while (n > 0)
{
vmm_map1(virt, physical);
virt += 4096;
physical += 4096;
n--;
}
}
// This function removes the virtual address's entry in the page directory / page table
void vmm_unmap1(unsigned int virt)
{
*(unsigned int *)(0xFFC00000 | ((virt & 0xFFC00000) >> 10) | ((virt & 0x003FF000) >> 10)) = 0;
invlpg_(virt);
}
// This function removes multiple pages' entries
void vmm_unmapn(unsigned int virt, unsigned int n)
{
while (n > 0)
{
vmm_unmap1(virt);
virt += 4096;
n--;
}
}
int vmm_map_range(void *virt_start, void *virt_end, u32_t phys_start)
{
if (virt_end < virt_start)
return 1; //invalid region
while (virt_start < virt_end)
{
vmm_map1((u32_t)virt_start, phys_start);
virt_start += 4096;
phys_start += 4096;
}
return 0;
}
// This function allocates and zeros memory for the given number of objects,
// given the size of each object
/*
void *calloc(unsigned int number, unsigned int size)
{
void *mem = malloc(number * size);
if (!mem)
return NULL; //could not get memory
memset(mem, 0, number * size);
return mem;
}*/
// This function initialzes a Heap Entry Block to entries linked together
void vmm_heb_init(HeapEntryBlock_t *heb)
{
int a;
for (a = 0; a < 255; a++)
heb->entry[a].next = &heb->entry[a+1];
heb->entry[255].next = NULL;
}
// This function adds a HeapEntry structure list to the appropriate place in the queue
void vmm_addToQueue(u32_t queue, HeapEntry_t *he)
{
if (heapEntryQueues[queue].start == NULL) //queue is empty
{
heapEntryQueues[queue].start = he;
heapEntryQueues[queue].count = vmm_countHeapEntries(he);
return;
}
// TODO
}
// This function returns how many HeapEntry objects are in a queue starting from the object given
int vmm_countHeapEntries(HeapEntry_t *he)
{
int count = 0;
while (he)
{
count++;
he = (HeapEntry_t *)he->link;
}
return count;
}
// This function follows a chain of HeapEntry objects and returns a pointer to the last one
HeapEntry_t *vmm_followChain(HeapEntry_t *he)
{
while (he->link)
he = (HeapEntry_t *)he->link;
return he;
}
// This function breaks an unused chunk from its queue and returns a pointer to it
HeapEntry_t *vmm_getUnusedChunk()
{
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);
vmm_addToQueue(VMM_HE_UNUSED, newHEB);
heapEntryQueues[VMM_HE_UNUSED].count -= 256;
}
HeapEntry_t *he = heapEntryQueues[VMM_HE_UNUSED].start;
heapEntryQueues[VMM_HE_UNUSED].start = he->link;
heapEntryQueues[VMM_HE_UNUSED].count--;
return he;
}

52
kernel/mm/vmm.h Normal file
View File

@ -0,0 +1,52 @@
// vmm.h
// Author: Josh Holtrop
// Date: 09/30/03
// Rewritten from scratch: 12/23/03, 07/13/04
// Modified: 07/15/04
#ifndef __HOS_VMM__
#define __HOS_VMM__ __HOS_VMM__
#include "hos_defines.h"
#include "multiboot.h"
#define VMM_HE_TYPES 4 //4 types of heap entries
#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/wilderness) section of virtual memory
#define VMM_MALLOC_GRANULARITY 4 //a power of 2, granularity for all memory requests
#define VMM_MALLOC_GRAN_MASK VMM_MALLOC_GRANULARITY-1 //mask for determining how much of a request is past granularity
typedef struct {
void *base; //virtual base address
u32_t length; //size in bytes
void *next; //link to next HeapEntry
u32_t padding;
} __attribute__((packed)) HeapEntry_t;
typedef struct {
HeapEntry_t entry[256]; //256 HeapEntry objects = 4kb (1 page)
} __attribute__((packed)) HeapEntryBlock_t;
typedef struct {
int count;
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);
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);
void vmm_heb_init(HeapEntryBlock_t *heb);
//void *calloc(unsigned int number, unsigned int size);
#endif

87
readme.txt Normal file
View File

@ -0,0 +1,87 @@
HOS - Holtrop's Operating System
--------------------------------
HOS is (in the process of becoming) a 32-bit, protected mode, graphical, multitasking operating system.
It was written by me, Josh Holtrop, with help from a few others along the way.
Goals: (A = accomplished, P = in progress, T = todo)
----------------------------------------------------
(A) Custom bootloader to load kernel from FAT-formatted boot media, options for video mode/ram disk
(A) Multiboot compliance - kernel can be loaded by GRUB
(A) 32-bit protected mode environment
(A) VESA Support for graphics modes
(A) PS/2 keyboard & mouse drivers
(A) Utilize x86's paging architecture for virtual memory management
(P) VFS abstraction layer for a single file system
(P) ram disk driver
(P) devfs file system driver
(T) ext2 file system support
(T) vfat file system support
(T) Multitasking support
(T) Console Manager
(T) HASH command shell
(T) Window Manager
(T) Various other utilities/applications
(T) Hard Drive (ATA) driver
(T) cdrom (ATAPI) driver
Change Log
----------
0.15
07/10/04 - Multiboot support added, loadable by GRUB
0.14
05/21/04 - C++ support in kernel, can use classes & templates
04/04/04 - video_line function for diagonal lines
03/16/04 - new VFS design with support for a loop device
03/01/04 - Thanks to Ben Meyer for helping me get a Makefile working and building on linux to work!
0.13
01/26/04 - functions added to read/write CMOS clock date and time
01/19/04 - fixed bug GDTR/IDTR pointing to physical rather than linear table base address
01/07/04 - fixed bug not reading sectors correctly from floppy
12/28/03 - fixed bug not storing eax on interrupt
12/25/03 - fixed bug in mm_palloc()
12/25/03 - incorporated output functions as regular functions rather than as part of a linked library
12/23/03 - re-written physical memory manager using bitmap instead of stack
12/22/03 - kernel relocated to 3gb linear / 1mb+24kb physical to allow for app. address space
0.12
12/21/03 - sample bmp loader tested, works (tests loading a kernel of size ~ 932kb)
12/20/03 - GDT/IDT now located at 1mb physical, before kernel
10/30/03 - turns floppy motor off
10/30/03 - keyboard LEDs working
10/29/03 - paging functions working
10/15/03 - physical memory management page allocators working
0.11
10/09/03 - PS/2 mouse driver
0.10
09/11/03 - Rewritten C and assembly kernel with VESA GUI mode support, keyboard driver
0.05
05/14/03 - HGUI24/HGUI32 commands finished for testing GUI on both 24bpp and 32bpp graphics cards
05/14/03 - first web release!
0.04
03/09/03 - added VM shortcut command
03/09/03 - press up to fill retrieve last inputted command for Nate Scholten
03/08/03 - press clear to clear console input
03/07/03 - added "shortcut" commands PC, IC, ? for Nate Scholten
03/06/03 - added PROMPTC, INPUTC commands
0.03
12/30/02 - Command Line Interface working, accepting basic commands
0.02
12/11/02 - Assembly bootsector can load stage2 ("console")
0.01
12/01/02 - Real mode assembly bootsector boots from floppy disk successfully