2007年12月19日水曜日

次やることを模索中・・・

ここにきて、次何に手をつけるかわからなくなった・・・・・

というか、やるべきことはたくさん思いつくのだが、どれも簡単には

いかないわけで・・・・

で、整理するために書き出してみる。誰かてつだってぇ~。
  • Floppy Disk から Readする(Recalibrateまではできた)
  • Event Queue を Template にする
  • Event Queueで実態を管理する。今はポインタをやりとりしてる。
  • Mutex とか、Semaphoe とか実装したい
  • FATを読み書きしたい
  • Diskから読み込んだアプリを実行したい(その前にプロセス管理か?)

以下は現実逃避っていうか、見た目を変えて気分転換したい・・・・

  • 解像度を変えたい
  • でも、解像度かえるには、VBEつかわんと・・・
  • BIOSたたくっつーことは、v86mode使わんといかん・・・・
  • ・・・・・わかんねぇ。。

前途多難っす。

2007年12月6日木曜日

Keyboardからの入力完成

先日、Keyboardからの入力を作成している と書きましたが、

やっと完成しました。

かなり複雑な状態遷移になるかなぁ。 と思っていましたが、

予想以上に簡単でした・・・・ 下記の図が、完成した状態遷移図です。

ここまでのソースをアップ(http://sourceforge.jp/projects/ice/files/)しておきます。

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つずつソースを掲載してく予定です。

2007年10月29日月曜日

Keyboard Intを動作させよう

前回、Timer Int を動作させようといいましたが、

そもそも、割り込みを使用したことなかったので、

まずは、Keyboard Intを使ってみよう!

で、GDT と、IDTと、PICを設定して、



いざ!!! 実行!・・・・・・・・・・・・・・・・・・・・



うごかねぇっす。 orz.....

いきなり、飛ばしすぎたか・・・まずは、GDTの設定から、

ちゃんと確認しながら進むことにします。

動作したら、ソース公開するっす。もうしばしお待ちを。

2007年10月25日木曜日

IDTを操作してみよう!

やっと、kernelが動作したので、次は、タスクスイッチ!!!!



と言いたいところなのですが、ただ、タスクスイッチするのも何だから、

Timerを実装しようかなぁ。

Timer実装するとなると、割込みが使えないとなぁ。

割込み使うためには、IDT設定しないとなぁ。

ということで、ちゃんと(?) IDT設定して、Interrupt handler 書いて、

Timerを動作させることを次の目標としました。

2007年10月21日日曜日

floppy imageの作成  - その3

やっと、floppy image 作成完了して、kernel bootできました。

忘れぬうちに、手順を書きとめておく。

(1) VMware Player の導入

  VMwareのWebサイトより、Windows用のVMware Playerをダウンロード、

  インストールします。

(2) QEMU の導入(VMware の Disk Image作成のため)

  qemu を ここ から取ってこよう。とってきたパッケージを適当なところへ

  解凍すると、中に qemu-img.exe があるはず。

(3) Ubuntu の導入

  日本語ローカライズされた VMwareイメージを ここ からダウンロードし、

  解凍すれば、 そのまま、VMware Player で実行できます。

(4) Floppy disk image の作成

  qemu-img create -f vmdk floppy0.bin 1440

  Ubuntu で FAT Formatする。

  mkdosfs /dev/fd0

(5) GRUBのインストール

  まずは Floppy diskをマウント。

  cd ~
  mkdir ./floppy
  sudo mount -t vfat /dev/fd0 ./floppy


  次に、Ubuntu の GRUB をそのまま使っちゃおう。

  mkdir ./floppy/boot
  mkdir ./floppy/boot/grub
  cp /boot/grub/stage1 /boot/grub/stage2 /boot/grub/menu.lst \\
    ./floppy/boot/grub/.
  /usr/sbin/grub

  grub> root (fd0)
  grub> setup (fd0)
  grub> quit

  最後に menu.lst の編集。
  Ubuntu用のエントリは全て削除して、下記エントリを追加。

  # For booting Sample Kernel
  title SampleKernel
  root (fd0)
  boot

(6) Sample Kernel のビルド

  ここ に書いてある、multiboot.h、boot.S、kernel.c がソース。

  Makefile が無いので、下記のように作成。

  TARGET= kernel
  MAPFILE= kernel.map
  START= 0x100000
  CC=/usr/bin/gcc
  CFLAGS= -ffreestanding -nostdinc -nostdlib -fno-stack-protector -I.
  LDFLAGS= -Ttext $(START) -e start -Map $(MAPFILE)
  OBJS= boot.o kernel.o
  
  .c.o:
   $(CC) $(CFLAGS) -c $*.c
  .S.o:
   $(CC) $(CFLAGS) -c $*.S

  all: $(TARGET)
  $(TARGET): $(OBJS)
   $(LD) $(LDFLAGS) -o $@ $(OBJS)

  clean::
   rm -f $(TARGET) $(OBJS) *~

  boot.o: Makefile boot.S multiboot.h
  kernel.o: Makefile kernel.c multiboot.h

(7) Sample Kernel を Floppy diskへコピー

  cp kernel ./floppy/boot/.

(8) Boot

  Boot画面はこんなかんじ。

2007年10月19日金曜日

floppy image の作成 - その2

昨日のつづきだが、 まずは、 floppy disk image を作成しよう!

これは、qemu-img を使えば簡単なはず。

まずは、qemu を ここ から取ってこよう。

とってきたパッケージを適当なところへ解凍すると、中に qemu-img.exe があるはず。

raw image ならば、下記のように作成する。

 qemu-img create floppy0.bin 1440

ここまでは、あっさりと成功したが・・・・問題はこの後。

この、floppy disk image を どーやって FAT formatするのだ???

Linux とかだったら、 mkdosfs とかで楽勝なのだが・・・・・・

Windows の Format って、 disk image file に対しては動作しないだろうし・・・

Cygwin とか導入しちゃうか??? それなら、Linux 入れた方が良さそうだなあ。



とか、ぐちぐち 言っていますが、今後 GRUB をインストールしなきゃいけない

ことを考えると、Linux 入れた方が良さそうですねぇ。

2007年10月18日木曜日

floppy image の作成

Floppy Disk からカーネル起動するぞ! と意気込んだのは良かったのですが・・・・・・・

いきなり、つまずいてます。。。。 orz



Windows だけだと、いろいろと面倒なんですよねぇ。

準備したい環境は・・・
 
 - デバッグは、QEMU or VMWarePlayer を使用して行う
 - Kernel コンパイルは MinGW 使う
 - ファイルシステムは FAT12 (floppyだからね)
 - Boot loader は GRUB

ということで、最初に GRUB を導入した floppy disk image を作成

したいのだが・・・・・Windowsだと面倒くさい。

作成するには下記の2通りだと思うのだが。。

 (1) FAT format した 本物の Floppy disk に GRUBインストールし
    その Floppy disk image を吸い出す。
      -> 本物の Floppy 使うのって格好わるいよねぇ。 
        それに、image吸い出すツールが見つからない。。

 (2) qemu-img 使って Floppy disk image を作成。
    その image に GRUBインストール。
      -> imageに対して GRUBインストールが出来ない。。
       PC Unix ならば、楽勝なのだが・・・・

ん~、、、、Ubuntuでもインストールしちゃうか?

それも面倒だしねぇ。。。。。悩み中。

---------------------------------------------------
2007.10.19 追記
 (1)はあまりに格好悪いので、(2)を採用!

2007年10月17日水曜日

Grub から自作 kernel起動の例

grub のドキュメントにも載っているが、実際 bootしてみた人がいた。

ちょっと、途方に暮れていたので、とても助かった。

 http://d.hatena.ne.jp/Yusuke_Yamamoto/20061002

これは、まず HDD Imageで grub boot環境をつくっておいて、そこから、FDにある、 kernelをロードするのかぁ。

結構面倒。。。。。全部 FD内に収まらないのだろーか?

 http://tiki.is.os-omicron.org/tiki.cgi?c=v&p=Grub%A4%F2%BB%C8%A4%C3%A4%BFOS%B3%AB%C8%AF

をっ! これは、FDに全て収める方式ですね。すばらしい、これを真似してみよう!

2007年10月16日火曜日

まずは、環境整備&ブートローダー

まずは、開発環境を整えなくてはならないのだが・・・・・

それよりも先に、ブートローダーについて考えなくてはならない。

?なぜ先ブートローダー? と思われる方もいらっしゃるとおもうので、説明しましょう。



ブートローダーは出来るだけ既存のものを使用しようと思っているのです。

というのも、このブログは OSつくるのが目的であって、ブートローダーをつくるのが目的ではないからです。

よって、出来るだけブートシーケンスを意識せずに済むようなブートローダーを望みました。

そこで、なんとも頼もしいブートローダーに出会います。 その名も・・・・

Grub

A20の Enable も、プロテクトモードへの移行も grub がやっちゃってくれます。

しかも、grub がサポートしているファイルシステムからならば、カーネルをファイル

としてロードが可能なのです。

なんとも、夢のよう!!!!!! が、しか~し、そんなにうまくはいきませぬ。

この、grub、Windows環境だと めちゃくちゃ扱いにくい。だからといって、

grubのためだけに 開発環境を Linuxや、FreeBSDにするのはねぇ。。。。。

うまーいこと、Windowsから、grub 使えないかなぁ。

2007年10月12日金曜日

OSでも作ってみるかなぁ。

”車輪の再発明” なのですが、勉強&趣味を兼ねて OSでも作ってみようかなぁ と思い立ちました。

単なる、思いつきなので、いつやめるかわかりませんが・・・・・・・・



で、まずは、参考になる本が必要なわけで・・・

これ
さすがに、30日じゃぁきびしいが、とても読みやすく、とっつきやすい。
まずは、この HariboteOS をベースに(ぱくるだけだが・・・・)、作っていこう!