2007年11月29日木曜日

Keyboard からの入力

Shellというか簡単なコンソールつくろうかなぁ。

と思っていたのですが、そのためには、まず、Keyboardから

入力できなければいかんわけです。

で、Haribote OS はどーやって実装してあるのかなぁ。。。




うげ・・・・汚い(失礼!)。

Ascii文字に変換する処理と、キーコードとしての処理(Non Ascii)

がまざってる orz.....




ここは気を取り直して、考えてみよう!下記のような流れがよいかなぁ。

KeyPress(or Release) → KeyEvent作成 → InputStreamへ通知 → Shellが InputStreamから取得して処理する。

まずは、InputStream経由せずに、KeyEvent作成して Shell へ通知

することにしよう!

KeyPress(or Release)割込みを受けてから Event作成するまでの

状態遷移は、下記のようになる。

2007年11月25日日曜日

悩み多き年頃(グローバルオブジェクトの扱い編)

現状、グローバルオブジェクトが多数ある。

これらは、本当に、グローバルにすべきなのだろうか?

システムにただひとつ存在するものは、どのようにモデリングすべきなのか?

やはり、システムで唯一のものは、クラス定義の時点で唯一であることを

保障すべきなのではないか? という結論に達しました。

ということで、Singletonパターンを適用することにしました。

全て対策しきっていませんが、とりあえず、今日現在の最新コードを

アップ(http://sourceforge.jp/projects/ice/files/)しておきます。

2007年11月19日月曜日

悩み多き年頃(コーディングルール編)

とりあえず、なんとかマルチタスクで動作するところまで

こぎつけては居ますが・・・・・

プランなしにつくってきたため、コードがぐちゃぐちゃです。

で、今悩んでいるのは、、、、、

(1) コーディングルールがない。
(2) Kernelオブジェクト(というかグローバルオブジェクト)
  の扱いがばらばら。
(3) Task管理の方法が決まっていない。

という3点です。

まずは、早急にコーディングルールを決める必要がある。

大雑把に考えてみた。。。

 -クラス名は、単語の先頭のみ大文字。それ以外は、小文字。
   ex.) Kernel、IntMgr

 -グローバルオブジェクト名もクラス名と同じ規則

 -定数は、全て大文字。単語間はアンダーバーとする。
   ex.) KERNEL_CS、PIC0_ICW1

 -メンバ変数は、クラス名と同じ規則。

 -メソッドは、動詞始まりで、先頭は小文字。その後、
  単語の区切り毎に大文字。
   ex.) getAllocSize()

 -メソッドの特例。Event Listener のようなもので、
  特定イベントのときにコールされる関数は、on~
  という名前でも良い。
   ex.) onTimerExpired、onMouseRelease

 -ローカルオブジェクト名は、全て小文字。単語間は、
  アンダーバーを使用する。
   ex.) int_mgr

とりあえず、この規則に合うように変更中。

2007年11月15日木曜日

SourceForge に登録したっす。

いちいち、ソースコードを紹介するのが面倒になったので・・・・・・・

SourceForgeに登録して、ソースアーカイブを載せておきました。

ここ からダウンロードできます。

ちなみに、私の開発環境ですが、Ubuntu 7.04 です。

ダウンロードしたアーカイブを展開して、 make すれば kernel が

作成されます。

2007年11月14日水曜日

IDTの設定

(1) GDTの設定
(2) IDTの設定 <- 今日はここ
(3) 割込み制御
(4) Global Constructor の呼び出し
(5) メモリ管理

ヘッダはこれ。

#ifndef __IDT_H__
#define __IDT_H__

#include "types.h"
#include "descripter.h"

struct IdtEntry{
uint16 offset_low;
uint16 selector;
uint16 copy :8;
uint16 type :8;
uint16 offset_hi;
} __attribute__ ((packed));

class Idt{
public:
static const int NUM = 256;
void init(void);

void set(int index, uint32 offset, uint16 selector, uint8 copy, uint8 type);
void load(void) const;

private:
DescripterTable table __attribute__((aligned(8)));
IdtEntry entry[NUM] __attribute__((aligned(8)));
};

#endif /* __IDT_H__ */


で、こっちが本体。
とりあえず、Timer と Keyboard の割り込みにハンドラを設定しました。


#include "idt.h"
#include "gdt.h"

extern "C" {
extern void asm_int_handler0(void);
extern void asm_int_handler1(void);
}

void Idt::init(void) {
table.limit = Idt::NUM * sizeof(IdtEntry) - 1;
table.offset = (uint32)entry;

for (int i = 0; i
set(i, 0, 0, 0, 0);
}

set(0x20, (uint32)asm_int_handler0,
Gdt::KERNEL_CS * sizeof(GdtEntry), 0, 0x8E);
set(0x21, (uint32)asm_int_handler1,
Gdt::KERNEL_CS * sizeof(GdtEntry), 0, 0x8E);
load();
}

void Idt::set(int index, uint32 offset, uint16 selector, uint8 copy, uint8 type) {
IdtEntry& desc = entry[index];

desc.offset_low = offset & 0xFFFF;
desc.offset_hi = (offset >> 16) & 0xFFFF;
desc.selector = selector;
desc.copy = copy;
desc.type = type;
}

void Idt::load(void) const {
__asm__ __volatile__("lidt %0" :: "m" (table));
}

2007年11月7日水曜日

GDTの設定

ではまず、GDTの設定ですが、Gdtというクラスを作成しました。

とりあえず、Kernel用のセグメントとして、Code Segment = 1

Data Segment = 2 ということにしました。

gdt.h は下記のとおり。


#ifndef __GDT_H__
#define __GDT_H__

#include "types.h"
#include "descripter.h"

struct GdtEntry
{
enum {
G_FLAG = 0x0800,
D_FLAG = 0x0400,
AVL_FLAG = 0x0100,
P_FLAG = 0x0080,
DPL0 = 0x0000,
DPL1 = 0x0020,
DPL2 = 0x0040,
DPL3 = 0x0060,
S_FLAG = 0x0010,
TYPE_CS = 0x000A,
TYPE_DS = 0x0002,
TYPE_SS = 0x0006,
A_FLAG = 0x0001
};
uint16 limit_low;
uint16 segbase_low;
uint8 segbase_mid;
uint8 type_low;
uint8 type_hi :4;
uint8 limit_hi :4;
uint8 segbase_hi;
} __attribute__ ((packed));

class Gdt
{
public:
static const int NUM = 8192;

enum {
NULL_S = 0,
KERNEL_CS = 1,
KERNEL_DS = 2
};

static const uint16 KERNEL_CS_FLAG =
(GdtEntry::G_FLAG | GdtEntry::D_FLAG | GdtEntry::P_FLAG |
GdtEntry::DPL0 | GdtEntry::S_FLAG | GdtEntry::TYPE_CS);
static const uint16 KERNEL_DS_FLAG =
(GdtEntry::G_FLAG | GdtEntry::D_FLAG | GdtEntry::P_FLAG |
GdtEntry::DPL0 | GdtEntry::S_FLAG | GdtEntry::TYPE_DS);

void init(void);
void set(int index, uint32 segbase, uint32 limit, uint16 type);
void load(void) const;

private:
DescripterTable table __attribute__((aligned(8)));
GdtEntry entry[NUM] __attribute__((aligned(8)));
};

#endif /* __GDT_H__ */


gdt.cc は以下のとおり。


#include "gdt.h"

void Gdt::init(void) {
table.limit = Gdt::NUM * sizeof(GdtEntry) - 1;
table.offset = (uint32)entry;
for (int i = 0; i < Gdt::NUM; i++) {
set(i, 0, 0, 0);
}

set(NULL_S, 0, 0, 0); // for Null seg
set(KERNEL_CS, 0, 0xFFFFF, KERNEL_CS_FLAG); // for Kernel code
set(KERNEL_DS, 0, 0xFFFFF, KERNEL_DS_FLAG); // for Kernel data

load();

/* Change segments */
asm("ljmp %0, $1f; 1:" : : "i" (KERNEL_CS * sizeof(GdtEntry)));
asm("mov %0, %%ax" : : "i" (KERNEL_DS * sizeof(GdtEntry)));
asm("mov %ax, %ds");
asm("mov %ax, %es");
asm("mov %ax, %fs");
asm("mov %ax, %gs");
asm("mov %ax, %ss");
}

void Gdt::set(int index, uint32 segbase, uint32 limit, uint16 type) {
GdtEntry& desc = entry[index];

desc.limit_low = limit & 0xFFFF;
desc.limit_hi = (limit >> 16) & 0xF;
desc.segbase_low = segbase & 0xFFFF;
desc.segbase_mid = (segbase >> 16) & 0xFF;
desc.segbase_hi = (segbase >> 24) & 0xFF;
desc.type_low = type & 0xFF;
desc.type_hi = (type >> 8) & 0xF;
}

void Gdt::load(void) const {
__asm__ __volatile__("lgdt %0" :: "m" (table));
}

2007年11月5日月曜日

Keyboard Int と、メモリ管理はできた!

試行錯誤の上、やっとのことで、 Keyboard Int と、

メモリ管理くらいまでは完成しました。

じゃぁ、ソースを tar で固めてアップ・・・・・・・・・・んな”ぁ!!!

ここ(blogspot ね)って、画像以外アップロードできないじゃないか!!
ん~、まいりましたねぇ。

ソース置き場が欲しい。。。。 誰か良いソース置き場知りませんか?

Sourceforge とかになっちゃうのかなぁ。

とりあえず、ここまでやったことを書き留めておきますか、、、

(1) GDTの設定
(2) IDTの設定
(3) 割込み制御
(4) Global Constructor の呼び出し
(5) メモリ管理

ってな感じです。 明日以降、1つずつソースを掲載してく予定です。