OS学習メモ9(30日OS自作入門9日目)
(完成直前の記事が誤操作で一度全部消えたので沈みムード)
1週間ぶりのOS本の進捗です。ここ1週間は中間試験の勉強やseccampの選択課題の勉強であまりこちらに手を回せていませんでしたが、意欲は全く下がっていません。張り切ってやっていきましょうー。
前回は「ようやく動いたマウスカーソル君がせっかく作った画面をどんどん破壊してしまう」という状態で終了したので、今回はそれを直していく...のかなと思いきやちょっと休憩。メモリ管理のお話です。
さてメモリ管理とは言っても、そもそもメモリがどのくらいの容量なのかが分からなければ管理もへったくれもないので、まずはそこから調べていきます。どうやら起動時にBIOSがチェックしてくれているらしいのですが、それを見るのはややこしいこといっぱいあって大変なのでBIOSを使わないでメモリチェックしていきます。
...って本には書いてあったんですが、そう言われちゃうとBIOSを使ってメモリチェックしてみたくなり、自分にはまだ早いかなー出来ないだろうなぁ..ーとは思いつつ、
http://oswiki.osask.jp/?(AT)BIOS
http://softwaretechnique.jp/OS_Development/Tips/Bios_Services/video_services.html
あたりを見ながら一応自分でも色々試してみました。3時間くらいは粘ったんですが案の定うまく行かなくて「やっぱり一旦本に沿って終わらせよう...」と改めて思うのでした...(悔しい)
— Yamahiro (@_YMHR_U) 2018年5月13日
まぁそんなわけで今回も本に沿って進めていきました。
32MB。
更に進めて...
空き容量も表示できましたよ
(正直書くのがちょっと面倒くさくなっちゃっているんですが...笑)説明これだけというのはさすがに雑なので、簡単に何をやったのかだけ書いて今日は終わろうと思います。
まずはコードをコピぺして置いておきます
void memman_init(struct MEMMAN *man){ man->frees = 0; /* 空き情報の個数 */ man->maxfrees = 0; /* 状況観察用:freesの最大値 */ man->lostsize = 0; /* 解放に失敗した合計サイズ */ man->losts = 0; /* 解放に失敗した回数 */ return; } /*確保*/ unsigned int memman_alloc(struct MEMMAN *man, unsigned int size){ unsigned int i, a; for (i = 0; i < man->frees; i++) { if (man->free[i].size >= size) { /* 十分な広さの空きを発見した時 */ a = man->free[i].addr; man->free[i].addr += size; man->free[i].size -= size; if (man->free[i].size == 0) { man->frees--; for (; i < man->frees; i++) { man->free[i] = man->free[i + 1]; } } return a; } } return 0; /* 空きが無かった場合 */ } /* 解放 */ int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size){ int i, j; for (i = 0; i < man->frees; i++) { if (man->free[i].addr > addr) { break; } } /* free[i - 1].addr < addr < free[i].addr */ if (i > 0) { if (man->free[i - 1].addr + man->free[i - 1].size == addr) { man->free[i - 1].size += size; if (i < man->frees) { if (addr + size == man->free[i].addr) { man->free[i - 1].size += man->free[i].size; man->frees--; for (; i < man->frees; i++) { man->free[i] = man->free[i + 1]; } } } return 0; } } if (i < man->frees) { if (addr + size == man->free[i].addr) { man->free[i].addr = addr; man->free[i].size += size; return 0; } } if (man->frees < MEMMAN_FREES) { for (j = man->frees; j > i; j--) { man->free[j] = man->free[j - 1]; } man->frees++; if (man->maxfrees < man->frees) { man->maxfrees = man->frees; } man->free[i].addr = addr; man->free[i].size = size; return 0; } man->losts++; man->lostsize += size; return -1; }
メモリ管理用に作った構造体MEMMANには「frees,maxfrees,lostsize,losts,free」の5つが入っていて、その中のfree[ ]は「空いているメモリの番地と大きさの情報が(○○から--だけ空いていると言った感じに)入っている構造体FREEINFO」の配列です。
メモリが必要になったら、MEMMANの中のfree[ ]から(free[i].sizeを見て)必要な大きさを確保できるところを探し、見つかったらその部分を確保。その部分は空き情報リストから削除します。反対に解放する時は、空き情報を追加して隣の空き地とひとまとめに出来ないかを調べ可能であればまとめるといった作業をしています。
後半は結構本の説明を借りちゃってますが..まぁ9日目はこんなところで。MINIX本の方のメモリ管理の章は手を付けていなかったと思うので、なるべく早めに読んでみようと思います。
おやすみなさい〜