Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
72 changed files
with
31,270 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
SOURCES_C=$(patsubst %.c,%.o,$(wildcard kernel/*.c)) | ||
SOURCES_ASM=$(patsubst %.asm,%.o,$(wildcard kernel/*.asm)) | ||
|
||
|
||
CC=cc | ||
LD=ld | ||
REDZONE=-mno-red-zone | ||
CFLAGS=-nostdlib -nostdinc -fno-builtin -m32 -c | ||
LDFLAGS=-Tlink.ld -m elf_i386 | ||
ASFLAGS=-felf | ||
|
||
OBJ = $(SOURCES_ASM) $(SOURCES_C) | ||
|
||
all: $(OBJ) link | ||
|
||
clean: | ||
-rm kernel/*.o kernel.bin | ||
|
||
link: | ||
$(LD) $(LDFLAGS) -o kernel.bin $(OBJ) | ||
|
||
kernel/%.o:kernel/%.c | ||
$(CC) $(CFLAGS) $< -o $@ | ||
|
||
kernel/%.o:kernel/%.asm | ||
nasm $(ASFLAGS) $< -o $@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
menuentry "SOSO DISK" { | ||
set root=(hd0,1) | ||
multiboot /boot/kernel | ||
module /boot/initrd.img | ||
boot | ||
} | ||
|
||
menuentry "SOSO CD" { | ||
set root=(cd) | ||
multiboot /boot/kernel | ||
module /boot/initrd.img | ||
boot | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
#include "common.h" | ||
#include "screen.h" | ||
#include "alloc.h" | ||
#include "vmm.h" | ||
#include "process.h" | ||
#include "debugprint.h" | ||
|
||
#define KMALLOC_MINSIZE 16 | ||
|
||
extern uint32 *gKernelPageDirectory; | ||
|
||
static char *gKernelHeap = NULL; | ||
static uint32 gKernelHeapUsed = 0; | ||
|
||
|
||
void initializeKernelHeap() | ||
{ | ||
gKernelHeap = (char *) KERN_HEAP_BEGIN; | ||
|
||
ksbrkPage(1); | ||
} | ||
|
||
void *ksbrkPage(int n) | ||
{ | ||
struct MallocHeader *chunk; | ||
char *p_addr; | ||
int i; | ||
|
||
if ((gKernelHeap + (n * PAGESIZE_4M)) > (char *) KERN_HEAP_END) { | ||
Screen_PrintF("ERROR: ksbrk(): no virtual memory left for kernel heap !\n"); | ||
return (char *) -1; | ||
} | ||
|
||
chunk = (struct MallocHeader *) gKernelHeap; | ||
|
||
for (i = 0; i < n; i++) | ||
{ | ||
p_addr = getPageFrame4M(); | ||
|
||
//Screen_PrintF("DEBUG: ksbrkPage(): got 4M on physical %x\n", p_addr); | ||
|
||
if ((int)(p_addr) < 0) | ||
{ | ||
PANIC("PANIC: ksbrkPage(): no free page frame available !"); | ||
return (char *) -1; | ||
} | ||
|
||
addPageToPd(gKernelPageDirectory, gKernelHeap, p_addr, /*0*/PG_USER); //PG_USER for now to allow user programs to read kernel heap | ||
|
||
gKernelHeap += PAGESIZE_4M; | ||
} | ||
|
||
chunk->size = PAGESIZE_4M * n; | ||
chunk->used = 0; | ||
|
||
return chunk; | ||
} | ||
|
||
void *kmalloc(uint32 size) | ||
{ | ||
if (size==0) | ||
return 0; | ||
|
||
unsigned long realsize; | ||
struct MallocHeader *chunk, *other; | ||
|
||
if ((realsize = sizeof(struct MallocHeader) + size) < KMALLOC_MINSIZE) | ||
{ | ||
realsize = KMALLOC_MINSIZE; | ||
} | ||
|
||
chunk = (struct MallocHeader *) KERN_HEAP_BEGIN; | ||
while (chunk->used || chunk->size < realsize) | ||
{ | ||
if (chunk->size == 0) | ||
{ | ||
Screen_PrintF("\nPANIC: kmalloc(): corrupted chunk on %x with null size (heap %x) !\nSystem halted\n", chunk, gKernelHeap); | ||
|
||
PANIC("kmalloc()"); | ||
|
||
return 0; | ||
} | ||
|
||
chunk = (struct MallocHeader *)((char *)chunk + chunk->size); | ||
|
||
if (chunk == (struct MallocHeader *) gKernelHeap) | ||
{ | ||
if ((int)(ksbrkPage((realsize / PAGESIZE_4M) + 1)) < 0) | ||
{ | ||
PANIC("kmalloc(): no memory left for kernel !\nSystem halted\n"); | ||
|
||
return 0; | ||
} | ||
} | ||
else if (chunk > (struct MallocHeader *) gKernelHeap) | ||
{ | ||
Screen_PrintF("\nPANIC: kmalloc(): chunk on %x while heap limit is on %x !\nSystem halted\n", chunk, gKernelHeap); | ||
|
||
PANIC("kmalloc()"); | ||
|
||
return 0; | ||
} | ||
} | ||
|
||
|
||
if (chunk->size - realsize < KMALLOC_MINSIZE) | ||
{ | ||
chunk->used = 1; | ||
} | ||
else | ||
{ | ||
other = (struct MallocHeader *)((char *) chunk + realsize); | ||
other->size = chunk->size - realsize; | ||
other->used = 0; | ||
|
||
chunk->size = realsize; | ||
chunk->used = 1; | ||
} | ||
|
||
gKernelHeapUsed += realsize; | ||
|
||
return (char *) chunk + sizeof(struct MallocHeader); | ||
} | ||
|
||
void kfree(void *v_addr) | ||
{ | ||
if (v_addr==(void*)0) | ||
return; | ||
|
||
struct MallocHeader *chunk, *other; | ||
|
||
chunk = (struct MallocHeader *)((uint32)v_addr - sizeof(struct MallocHeader)); | ||
chunk->used = 0; | ||
|
||
gKernelHeapUsed -= chunk->size; | ||
|
||
//Merge free block with next free block | ||
while ((other = (struct MallocHeader *)((char *)chunk + chunk->size)) | ||
&& other < (struct MallocHeader *)gKernelHeap | ||
&& other->used == 0) | ||
{ | ||
chunk->size += other->size; | ||
} | ||
} | ||
|
||
static void sbrkPage(Process* process, int pageCount) | ||
{ | ||
if (pageCount > 0) | ||
{ | ||
for (int i = 0; i < pageCount; ++i) | ||
{ | ||
char * p_addr = getPageFrame4M(); | ||
|
||
if ((int)(p_addr) < 0) | ||
{ | ||
PANIC("sbrkPage(): no free page frame available !"); | ||
return; | ||
} | ||
|
||
addPageToPd(process->pd, process->heapNextUnallocatedPageBegin, p_addr, PG_USER); | ||
|
||
process->heapNextUnallocatedPageBegin += PAGESIZE_4M; | ||
} | ||
} | ||
else if (pageCount < 0) | ||
{ | ||
pageCount *= -1; | ||
|
||
for (int i = 0; i < pageCount; ++i) | ||
{ | ||
if (process->heapNextUnallocatedPageBegin - PAGESIZE_4M >= process->heapBegin) | ||
{ | ||
process->heapNextUnallocatedPageBegin -= PAGESIZE_4M; | ||
|
||
//This also releases the page frame | ||
removePageFromPd(process->pd, process->heapNextUnallocatedPageBegin); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void initializeProcessHeap(Process* process) | ||
{ | ||
process->heapBegin = (char*) USER_OFFSET; | ||
process->heapEnd = process->heapBegin; | ||
process->heapNextUnallocatedPageBegin = process->heapBegin; | ||
|
||
//Userland programs (their code, data,..) start from USER_OFFSET | ||
//So we should leave some space for them by moving heap pointer. | ||
//As a result userspace malloc functions start from a forward point (+ USER_EXE_IMAGE). | ||
|
||
sbrk(process, USER_EXE_IMAGE); | ||
} | ||
|
||
void *sbrk(Process* process, int nBytes) | ||
{ | ||
//Screen_PrintF("sbrk:1: pid:%d nBytes:%d\n", process->pid, nBytes); | ||
|
||
char* previousBreak = process->heapEnd; | ||
|
||
if (nBytes > 0) | ||
{ | ||
int remainingInThePage = process->heapNextUnallocatedPageBegin - process->heapEnd; | ||
|
||
//Screen_PrintF("sbrk:2: remainingInThePage:%d\n", remainingInThePage); | ||
|
||
if (nBytes > remainingInThePage) | ||
{ | ||
int bytesNeededInNewPages = nBytes - remainingInThePage; | ||
int neededNewPageCount = (bytesNeededInNewPages / PAGESIZE_4M) + 1; | ||
|
||
//Screen_PrintF("sbrk:3: neededNewPageCount:%d\n", neededNewPageCount); | ||
|
||
uint32 freePages = getFreePageCount(); | ||
if ((uint32)neededNewPageCount + 1 > freePages) | ||
{ | ||
return (void*)-1; | ||
} | ||
|
||
sbrkPage(process, neededNewPageCount); | ||
} | ||
} | ||
else if (nBytes < 0) | ||
{ | ||
char* currentPageBegin = process->heapNextUnallocatedPageBegin - PAGESIZE_4M; | ||
|
||
int remainingInThePage = process->heapEnd - currentPageBegin; | ||
|
||
//Screen_PrintF("sbrk:4: remainingInThePage:%d\n", remainingInThePage); | ||
|
||
if (-nBytes > remainingInThePage) | ||
{ | ||
int bytesInPreviousPages = -nBytes - remainingInThePage; | ||
int neededNewPageCount = (bytesInPreviousPages / PAGESIZE_4M) + 1; | ||
|
||
//Screen_PrintF("sbrk:5: neededNewPageCount:%d\n", neededNewPageCount); | ||
|
||
sbrkPage(process, -neededNewPageCount); | ||
} | ||
} | ||
|
||
process->heapEnd += nBytes; | ||
|
||
return previousBreak; | ||
} | ||
|
||
uint32 getKernelHeapUsed() | ||
{ | ||
return gKernelHeapUsed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef ALLOC_H | ||
#define ALLOC_H | ||
|
||
#include "common.h" | ||
#include "process.h" | ||
|
||
void initializeKernelHeap(); | ||
void *ksbrkPage(int n); | ||
void *kmalloc(uint32 size); | ||
void kfree(void *v_addr); | ||
|
||
void initializeProcessHeap(Process* process); | ||
void *sbrk(Process* process, int nBytes); | ||
|
||
uint32 getKernelHeapUsed(); | ||
|
||
struct MallocHeader | ||
{ | ||
unsigned long size:31; | ||
unsigned long used:1; | ||
} __attribute__ ((packed)); | ||
|
||
typedef struct MallocHeader MallocHeader; | ||
|
||
#endif // ALLOC_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
MBOOT_PAGE_ALIGN equ 1<<0 | ||
MBOOT_MEM_INFO equ 1<<1 | ||
MBOOT_HEADER_MAGIC equ 0x1BADB002 | ||
MBOOT_HEADER_FLAGS equ MBOOT_PAGE_ALIGN | MBOOT_MEM_INFO | ||
MBOOT_CHECKSUM equ -(MBOOT_HEADER_MAGIC + MBOOT_HEADER_FLAGS) | ||
|
||
|
||
[BITS 32] | ||
|
||
|
||
section .multiboot | ||
align 4 | ||
dd MBOOT_HEADER_MAGIC | ||
dd MBOOT_HEADER_FLAGS | ||
dd MBOOT_CHECKSUM | ||
|
||
|
||
section .bss | ||
align 16 | ||
stack_bottom: | ||
resb 16384 ; 16 KiB | ||
stack_top: | ||
|
||
[GLOBAL _start] ; this is the entry point. we tell linker script to set start address of kernel elf file. | ||
[EXTERN kmain] | ||
|
||
section .text | ||
|
||
_start: | ||
mov esp, stack_top | ||
|
||
; push multiboot parameter to kmain() | ||
push ebx | ||
|
||
; ...and run! | ||
cli | ||
call kmain | ||
|
||
;never reach here | ||
cli | ||
hlt |
Oops, something went wrong.