Skip to content

Commit

Permalink
Compilando. Primeiros passos para fazer o multitask.
Browse files Browse the repository at this point in the history
  • Loading branch information
psychomantys committed Mar 18, 2013
1 parent 678349f commit d5198be
Show file tree
Hide file tree
Showing 11 changed files with 494 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/kernel/arch/i386/isa_specific_code.cpp
Expand Up @@ -67,16 +67,19 @@ extern "C" {
extern "C" {
macro_get_reg_func(eax)
macro_get_reg_func(ebx)
macro_get_reg_func(ebp)
macro_get_reg_func(cr0)
macro_get_reg_func(cr1)
macro_get_reg_func(cr2)
macro_get_reg_func(cr3)

macro_set_reg_func(eax)
macro_set_reg_func(ebx)
macro_set_reg_func(ebp)
macro_set_reg_func(cr0)
macro_set_reg_func(cr1)
macro_set_reg_func(cr2)
macro_set_reg_func(cr3)
}


4 changes: 4 additions & 0 deletions src/kernel/arch/i386/isa_specific_code.hpp
Expand Up @@ -37,8 +37,11 @@ extern "C" {
void GDT_flush( const volatile struct GDT_ptr &new_gdt );
void IDT_load( const volatile struct IDT_ptr &new_idt );

uint32_t read_eip();

void get_register_eax(volatile uint32_t &ret);
void get_register_ebx(volatile uint32_t &ret);
void get_register_ebp(volatile uint32_t &ret);

void get_register_cr0( volatile uint32_t &ret);
void get_register_cr1( volatile uint32_t &ret);
Expand All @@ -47,6 +50,7 @@ extern "C" {

void set_register_eax(volatile uint32_t ret);
void set_register_ebx(volatile uint32_t ret);
void set_register_ebp(volatile uint32_t ret);

void set_register_cr0( volatile uint32_t ret);
void set_register_cr1( volatile uint32_t ret);
Expand Down
1 change: 0 additions & 1 deletion src/kernel/arch/i386/isa_specific_code.s
Expand Up @@ -58,7 +58,6 @@ halt_machine:




.globl disable_interrupts
disable_interrupts:
pushl %ebp
Expand Down
5 changes: 5 additions & 0 deletions src/kernel/arch/i386/start.s
Expand Up @@ -25,6 +25,10 @@ mboot:
.long rodata
.long start

initial_esp:
.globl initial_esp
.zero 4

multiboot_magic:
.globl multiboot_magic
.zero 4
Expand All @@ -38,6 +42,7 @@ start:

movl %eax, multiboot_magic
movl %ebx, multiboot_addr
movl %esp, initial_esp

call _at_global_begin
call main
Expand Down
72 changes: 72 additions & 0 deletions src/kernel/arch/i386/task.s
@@ -0,0 +1,72 @@

.global read_eip
read_eip:
pop %eax
jmp *%eax

/*
.globl copy_page_physical
copy_page_physical:
pushl %ebp ; According to __cdecl, we must preserve the contents of EBX.
pushf ; push EFLAGS, so we can pop it and reenable interrupts
; later, if they were enabled anyway.
cli ; Disable interrupts, so we aren't interrupted.
; Load these in BEFORE we disable paging!
movl 12(%esp), %ebx ; Source address
movl 16(%esp), %ecx ; Destination address
movl %cr0, %edx ; Get the control register...
andl $0x7fffffff, %edx ; and...
mov %edx, %cr0 ; Disable paging.
mov $1024, %edx ; 1024*4bytes = 4096 bytes to copy
.loop:
mov (%ebx), %eax ; Get the word at the source address
mov %eax, (%ecx) ; Store it at the dest address
add $4, %ebx ; Source address += sizeof(word)
add $4, %ecx ; Dest address += sizeof(word)
dec %edx ; One less word to do
jnz .loop
mov %cr0, %edx ; Get the control register again
or $0x80000000, %edx ; and...
mov %edx, %cr0 ; Enable paging.
popf ; Pop EFLAGS back.
pop %ebx ; Get the original value of EBX back.
ret
.globl copy_page_physical
copy_page_physical:
push ebx ; According to __cdecl, we must preserve the contents of EBX.
pushf ; push EFLAGS, so we can pop it and reenable interrupts
; later, if they were enabled anyway.
cli ; Disable interrupts, so we aren't interrupted.
; Load these in BEFORE we disable paging!
mov ebx, [esp+12] ; Source address
mov ecx, [esp+16] ; Destination address
mov edx, cr0 ; Get the control register...
and edx, 0x7fffffff ; and...
mov cr0, edx ; Disable paging.
mov edx, 1024 ; 1024*4bytes = 4096 bytes to copy
.loop:
mov eax, [ebx] ; Get the word at the source address
mov [ecx], eax ; Store it at the dest address
add ebx, 4 ; Source address += sizeof(word)
add ecx, 4 ; Dest address += sizeof(word)
dec edx ; One less word to do
jnz .loop
mov edx, cr0 ; Get the control register again
or edx, 0x80000000 ; and...
mov cr0, edx ; Enable paging.
popf ; Pop EFLAGS back.
pop ebx ; Get the original value of EBX back.
ret
*/

4 changes: 2 additions & 2 deletions src/kernel/main.cpp
Expand Up @@ -184,9 +184,9 @@ int main(){
char buf[256];
uint32_t sz=read_fs(fsnode, 0, 256, buf);
int j;
for( j=0 ; j<sz ; j++)
for( j=0 ; j<sz ; j++){
kprintf("%c",buf[j]);

}
kprintf("\"\n");
}
++i;
Expand Down
82 changes: 82 additions & 0 deletions src/kernel/paging.cpp
Expand Up @@ -114,3 +114,85 @@ void Paging::page_fault(struct regs *r){
halt_machine();
}

page_directory_t *Paging::clone_directory(page_directory_t *src){
uint32_t phys;
// Make a new page directory and obtain its physical address.
page_directory_t *dir = (page_directory_t*)kmalloc_ap(sizeof(page_directory_t), &phys);
// Ensure that it is blank.
memset(dir, 0, sizeof(page_directory_t));

// Get the offset of tablesPhysical from the start of the page_directory_t structure.
uint32_t offset = (uint32_t)dir->tablesPhysical - (uint32_t)dir;

// Then the physical address of dir->tablesPhysical is:
dir->physicalAddr = phys + offset;

// Go through each page table. If the page table is in the kernel directory, do not make a new copy.
int i;
for (i = 0; i < 1024; i++)
{
if (!src->tables[i])
continue;

if (kernel_directory->tables[i] == src->tables[i])
{
// It's in the kernel, so just use the same pointer.
dir->tables[i] = src->tables[i];
dir->tablesPhysical[i] = src->tablesPhysical[i];
}
else
{
// Copy the table.
uint32_t phys;
dir->tables[i] = clone_table(src->tables[i], &phys);
dir->tablesPhysical[i] = phys | 0x07;
}
}
return dir;
}


void copy_page_physical( uint32_t dest, uint32_t src){
disable_interrupts();

register uint32_t cr0;
get_register_cr0(cr0);
cr0 &= 0x7fffffff;
set_register_cr0(cr0);

memset(dest, src, 4*1024 );

get_register_cr0(cr0);
cr0 |= 0x80000000;
set_register_cr0(cr0);
}


page_table_t *Paging::clone_table(page_table_t *src, uint32_t *physAddr){
// Make a new page table, which is page aligned.
page_table_t *table = (page_table_t*)kmalloc_ap(sizeof(page_table_t), physAddr);
// Ensure that the new table is blank.
memset(table, 0, sizeof(page_directory_t));

// For every entry in the table...
int i;
for (i = 0; i < 1024; i++)
{
// If the source entry has a frame associated with it...
if (src->pages[i].frame)
{
// Get a new frame.
alloc_frame(&table->pages[i], 0, 0);
// Clone the flags from source to destination.
if (src->pages[i].present) table->pages[i].present = 1;
if (src->pages[i].rw) table->pages[i].rw = 1;
if (src->pages[i].user) table->pages[i].user = 1;
if (src->pages[i].accessed) table->pages[i].accessed = 1;
if (src->pages[i].dirty) table->pages[i].dirty = 1;
// Physically copy the data across. This function is in process.s.
copy_page_physical(src->pages[i].frame*0x1000, table->pages[i].frame*0x1000);
}
}
return table;
}

11 changes: 9 additions & 2 deletions src/kernel/paging.hpp
Expand Up @@ -91,6 +91,13 @@ class Paging{
**/
void switch_page_directory(page_directory_t *new_page);

/**
Makes a copy of a page directory.
**/
page_directory_t *clone_directory(page_directory_t *src);

page_table_t *clone_table(page_table_t *src, uint32_t *physAddr);

/**
* Retrieves a pointer to the page required.
* If make == 1, if the page-table in which this page should
Expand All @@ -104,6 +111,8 @@ class Paging{
static void page_fault(struct regs *r);

page_directory_t *kernel_directory;
page_directory_t *current_directory;

void alloc_frame(page_t *page, const bool &is_kernel, const bool &is_writeable);
void free_frame(page_t *page);
~Paging(){
Expand All @@ -114,8 +123,6 @@ class Paging{
const uint32_t frame_qtd;
bitset frames;
IDT &idt;

page_directory_t *current_directory;
};

#endif /* ----- #ifndef paging_INC ----- */
Expand Down
4 changes: 4 additions & 0 deletions src/kernel/start.hpp
Expand Up @@ -2,6 +2,10 @@
#ifndef _CPP_CTOR_DTOR_IMPL__INC
#define _CPP_CTOR_DTOR_IMPL__INC

#include <stdint.h>

extern uint32_t initial_esp;

extern "C" void _at_global_begin();

extern "C" void _at_global_end();
Expand Down

0 comments on commit d5198be

Please sign in to comment.