Skip to content

Commit

Permalink
Merge pull request #75 from bassaer/develop
Browse files Browse the repository at this point in the history
[ver 2.0.1] fix paging
  • Loading branch information
bassaer committed Mar 21, 2020
2 parents 49f9cc3 + 1a9df09 commit c75402f
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 41 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## ver 2.0.1
- fix paging
- fix itoa

## ver 2.0.0
- add GUI

Expand Down
9 changes: 9 additions & 0 deletions include/io.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef MYOS_IO_H
#define MYOS_IO_H

#include <mm/pgtable.h>

/**
* HLT : CPU停止
*/
Expand Down Expand Up @@ -47,6 +49,7 @@ int io_in(int port);
/**
* 割り込みハンドラ
*/
void asm_handle_intr14(void);
void asm_handle_intr20(void);
void asm_handle_intr21(void);
void asm_handle_intr27(void);
Expand All @@ -72,6 +75,12 @@ int load_cr0(void);
*/
void store_cr0(int cr0);

void set_pd(page_directory_entry *pde);

void enable_pagin();

int load_cr3();

/**
* TRは現在実行中のタスクを記憶するためのレジスタ
* ltrはTRを変更するための命令
Expand Down
5 changes: 5 additions & 0 deletions include/mm/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,9 @@ void stats();
*/
unsigned int scan_mem(unsigned int start, unsigned int end);

/**
* ページフォールハンドラ
*/
void handle_intr14(int *esp);

#endif
2 changes: 1 addition & 1 deletion include/mm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int is_pte_present(page_table_entry *pte);

int is_pte_writeable(page_table_entry *pte);

unsigned long get_pte_index(unsigned long vaddr);
int get_pte_index(unsigned long vaddr);

page_table_entry* get_pte(page_table_entry *table, unsigned int vaddr);

Expand Down
1 change: 1 addition & 0 deletions kernel/dsctbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void init_gdtidt() {
// タイマーはIRQ0なのでINT 0x20
// キーボードはIRQ1なのでINT 0x21
// 割り込み発生でasm_handle_intrをcall
set_gatedesc(idt + 0x0e, (int) asm_handle_intr14, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x20, (int) asm_handle_intr20, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x21, (int) asm_handle_intr21, 2 * 8, AR_INTGATE32);
set_gatedesc(idt + 0x27, (int) asm_handle_intr27, 2 * 8, AR_INTGATE32);
Expand Down
36 changes: 34 additions & 2 deletions kernel/func.s
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
.code32
.global io_cli, io_sti, io_stihlt, io_hlt
.global set_gdtr, set_idtr, outb_p, io_in
.global asm_handle_intr20, asm_handle_intr21, asm_handle_intr27, asm_handle_intr2c
.global asm_handle_intr14, asm_handle_intr20, asm_handle_intr21, asm_handle_intr27, asm_handle_intr2c
.global io_load_eflags, io_store_eflags, load_cr0, store_cr0
.global set_pd, enable_paging, load_cr3
.global set_tr, context_switch
.extern handle_intr20, handle_intr21, handle_intr27, handle_intr2c
.extern handle_intr14, handle_intr20, handle_intr21, handle_intr27, handle_intr2c
.text

io_hlt:
Expand Down Expand Up @@ -67,6 +68,23 @@ io_in:
inb %dx, %al
ret

asm_handle_intr14:
pop %eax
push %es
push %ds
pusha
mov %esp, %eax
push %eax
mov %ss, %ax
mov %ax, %ds
mov %ax, %es
call handle_intr14
pop %eax
popa
pop %ds
pop %es
iret

asm_handle_intr20:
push %es
push %ds
Expand Down Expand Up @@ -131,6 +149,20 @@ asm_handle_intr2c:
pop %es
iret

enable_paging:
movl %cr0, %eax # cr0をeaxにコピー
or $0x80000000,%eax # マスク
movl %eax, %cr0 # 戻す
ret

set_pd:
movl 4(%esp), %eax
movl %eax, %cr3
ret

load_cr3:
movl %cr3, %eax # CR0を返すためにEAXにいれる
ret

set_tr:
ltr 4(%esp)
Expand Down
5 changes: 4 additions & 1 deletion kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ int main() {
init_queue(&keyboard_q, QUEUE_LIMIT, keyboard_buf);
init_keyboard(&keyboard_q);

init_mem_info();
if (init_mem_info() != MEM_SUCCESS) {
printf("memory init error.\n");
while(1) { io_hlt(); }
}

if (boot_info->gui == 1) {
start_gui(boot_info, &keyboard_q);
Expand Down
1 change: 0 additions & 1 deletion kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ void handle_intr20(int *esp) {
outb_p(PIC0_OCW2, 0x60); // IRQ-00受付完了をPICに通知
// uptimeを更新
timerctrl.uptime++;
debug("uptime: %d", timerctrl.uptime);
// 次のタイマーの時刻を確認
if (timerctrl.next_timeout > timerctrl.uptime) {
return;
Expand Down
10 changes: 5 additions & 5 deletions lib/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ int atoi(char *src) {
return num / 10;
}

int itoa(int src, char *dst, int base) {
unsigned long itoa(unsigned long src, char *dst, int base) {
int len = 0;
int buf[10];
int buf[100];
int negative = 0;
if (src < 0) {
src *= -1;
Expand Down Expand Up @@ -94,14 +94,14 @@ int itoa(int src, char *dst, int base) {
char* format_str(char *str, char *format, va_list *arg) {
va_list list;
va_copy(list, *arg);
int d_arg;
long d_arg;
char *s_arg;
while(*format) {
if (*format == '%') {
++format;
switch(*format) {
case 'd':
d_arg = va_arg(list, int);
d_arg = va_arg(list, long);
if (d_arg < 0) {
d_arg *= -1;
*(str++) = '-';
Expand All @@ -111,7 +111,7 @@ char* format_str(char *str, char *format, va_list *arg) {
case 'x':
*(str++) = '0';
*(str++) = 'x';
str += itoa(va_arg(list, int), str, 16);
str += itoa(va_arg(list, unsigned long), str, 16);
break;
case 'c':
*(str++) = va_arg(list, int);
Expand Down
61 changes: 32 additions & 29 deletions mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,57 +37,53 @@ int init_mem_info() {
}

unsigned int get_kernel_size() {
return (unsigned int)(&_KERN_END - PMEM_KERN_START);
return (unsigned int)((unsigned int)&_KERN_END - PMEM_KERN_START);
}

int init_pg_table() {
// 0x00400000 - 0x00401000 を割り当て
page_table_entry *user_table = (page_table_entry *)alloc_single_block();
// 0x00401000 - 0x00402000 を割り当て
page_table_entry *kernel_table = (page_table_entry *)alloc_single_block();
if (user_table == NULL || kernel_table == NULL) {
// TODO : user_tableとkernel_tableを分ける
page_table_entry *page_table = (page_table_entry *)alloc_single_block();
if (page_table == NULL) {
return MEM_ERROR;
}

// 使用するブロックを初期化
set_mem(user_table, 0x00, BLOCK_SIZE);
set_mem(kernel_table, 0x00, BLOCK_SIZE);
set_mem(page_table, 0x00, BLOCK_SIZE);

/**
* 各ページテーブル初期化
* 確認のため1番目のページテーブルに共存する
* ユーザ空間 0x00000000 - 0x0027ffff
* カーネル空間 0x00280000 - 0x003fffff
*
*/
unsigned int i;
unsigned long paddr;
unsigned long vaddr;
// ユーザ空間割当
for (i = 0, paddr = PMEM_FREE_START, vaddr = VMEM_USER_START; i < PTE_NUM; ++i, paddr += BLOCK_SIZE, vaddr += BLOCK_SIZE) {
page_table_entry *pte = get_pte(user_table, vaddr);
set_pte_flags(pte, PDE_FLAG_PRESENT | PDE_FLAG_RW);
set_pte_paddr(pte, paddr);
}
// カーネル空間割当
// TODO : 仮想アドレス開始をVMEM_KERN_START(0xc0000000)に変更する
// 動作確認のためストレートマップさせている
for (i = 0, paddr = PMEM_KERN_START, vaddr = 0x28000000; i < PTE_NUM; ++i, paddr += BLOCK_SIZE, vaddr += BLOCK_SIZE) {
page_table_entry *pte = get_pte(kernel_table, vaddr);
set_pte_flags(pte, PDE_FLAG_PRESENT | PDE_FLAG_RW);
set_pte_paddr(pte, paddr);
// ページ割当
for (i = 0, paddr = PMEM_FREE_START, vaddr = VMEM_USER_START; i < PTE_NUM; i++, paddr += BLOCK_SIZE, vaddr += BLOCK_SIZE) {
page_table_entry *pte = get_pte(page_table, vaddr);
set_pte_flags(pte, vaddr | PDE_FLAG_PRESENT | PDE_FLAG_RW);
}

page_directory_entry *pd_table = (page_directory_entry *)alloc_single_block();
if (pd_table == NULL) {
return MEM_ERROR;
}

// ユーザ空間ページディレクトリ設定
page_directory_entry *pde = get_pde(pd_table, VMEM_USER_START);
set_pde_flags(pde, PDE_FLAG_PRESENT | PDE_FLAG_RW);
set_pde_paddr(pde, (unsigned long)user_table);
// ページディレクトリ設定
for (i = 0, vaddr = VMEM_USER_START; i < PTE_NUM; ++i, vaddr += BLOCK_SIZE) {
pd_table[i] = PDE_FLAG_RW;
}

// カーネル空間ぺージディレクトリ設定
// TODO : 仮想アドレス開始をVMEM_KERN_START(0xc0000000)に変更する
pde = get_pde(pd_table, 0x28000000);
// 1番目のPTEだけひとまず設定
page_directory_entry *pde = get_pde(pd_table, VMEM_USER_START);
set_pde_flags(pde, PDE_FLAG_PRESENT | PDE_FLAG_RW);
set_pde_paddr(pde, (unsigned long)user_table);
set_pde_paddr(pde, (unsigned long)page_table);

// ページディレクトリを設定
set_pd(pde);
set_pd(pd_table);
// ページングを有効化
enable_paging();

Expand Down Expand Up @@ -272,3 +268,10 @@ unsigned int scan_mem(unsigned int start, unsigned int end) {
}
return index;
}

/**
* ページフォールトハンドラ
*/
void handle_intr14(int *esp) {
debug("page fault!!!");
}
7 changes: 5 additions & 2 deletions mm/pgtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ int is_pte_writeable(page_table_entry *pte) {
* 12から21bitの10bitを取得
* これがページテーブルのインデックスになる
*/
unsigned long get_pte_index(unsigned long vaddr) {
int get_pte_index(unsigned long vaddr) {
return (vaddr >> PTE_SHIFT) & PTE_MASK;
}

page_table_entry* get_pte(page_table_entry *table, unsigned int vaddr) {
if (table == NULL) {
return (page_table_entry *)NULL;
}
return (page_table_entry *)(table[get_pte_index(vaddr)]);
return &table[get_pte_index(vaddr)];
}


Expand Down Expand Up @@ -95,6 +95,8 @@ page_table_entry get_pde_ptaddr(page_directory_entry *pd) {
return *pd & PDE_PT_ADDR;
}

/*
func.sに一旦移動
void set_pd(page_directory_entry *pde) {
__asm__ volatile("movl %%cr3, %0"::"r"(pde));
}
Expand All @@ -108,3 +110,4 @@ void enable_paging() {
"pop %eax;"
);
}
*/

0 comments on commit c75402f

Please sign in to comment.