Compare commits

...

2 Commits

Author SHA1 Message Date
Yourtion
bf248a9f46 update README 2016-04-12 13:40:01 +08:00
Yourtion
e620e5e6ed 挑战内存管理 2016-04-12 13:38:29 +08:00
2 changed files with 238 additions and 7 deletions

View File

@@ -3,14 +3,33 @@
#include "bootpack.h"
#include <stdio.h>
#define MEMMAN_FREES 4090 /* 大约是32KB*/
struct FREEINFO { /* 可用信息 */
unsigned int addr, size;
};
struct MEMMAN { /* 内存管理 */
int frees, maxfrees, lostsize, losts;
struct FREEINFO free[MEMMAN_FREES];
};
unsigned int memtest(unsigned int start, unsigned int end);
void memman_init(struct MEMMAN *man);
unsigned int memman_total(struct MEMMAN *man);
unsigned int memman_alloc(struct MEMMAN *man, unsigned int size);
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size);
#define MEMMAN_ADDR 0x003c0000
void HariMain(void)
{
struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
char s[40], mcursor[256], keybuf[32], mousebuf[128];
int mx, my, i;
struct MOUSE_DEC mdec;
struct MOUSE_DEC mdec;
unsigned int memtotal;
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
init_gdtidt();
init_pic();
@@ -23,6 +42,10 @@ void HariMain(void)
init_keyboard();
enable_mouse(&mdec);
memtotal = memtest(0x00400000, 0xbfffffff);
memman_init(memman);
memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff */
memman_free(memman, 0x00400000, memtotal - 0x00400000);
init_palette();
init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);
@@ -33,8 +56,7 @@ void HariMain(void)
sprintf(s, "(%d, %d)", mx, my);
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s);
i = memtest(0x00400000, 0xbfffffff) / (1024 * 1024);
sprintf(s, "memory %dMB", i);
sprintf(s, "memory %dMB free : %dKB", memtotal / (1024 * 1024), memman_total(memman) / 1024);
putfonts8_asc(binfo->vram, binfo->scrnx, 0, 32, COL8_FFFFFF, s);
for (;;) {
@@ -52,7 +74,7 @@ void HariMain(void)
i = fifo8_get(&mousefifo);
io_sti();
if (mouse_decode(&mdec, i) != 0) {
/* 3字节都凑齐了所以把它们显示出来*/
/* 3字节都凑齐了所以把它们显示出来*/
sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);
if ((mdec.btn & 0x01) != 0) {
s[1] = 'L';
@@ -128,3 +150,107 @@ unsigned int memtest(unsigned int start, unsigned int end)
return i;
}
void memman_init(struct MEMMAN *man){
man->frees = 0; /* 可用信息数目 */
man->maxfrees = 0; /* 用于观察可用状况frees的最大值 */
man->lostsize = 0; /* 释放失败的内存的大小总和 */
man->losts = 0; /* 释放失败次数 */
return;
}
unsigned int memman_total(struct MEMMAN *man)
/* 报告空余内存大小的合计 */
{
unsigned int i, t = 0;
for (i = 0; i < man->frees; i++) {
t += man->free[i].size;
}
return t;
}
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) {
/* 如果free[i]变成了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;
/* 为便于归纳内存将free[]按照addr的顺序排列 */
/* 所以,先决定应该放在哪里 */
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->free[i]删除 */
/* free[i]变成0后归纳到前面去 */
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) {
/* free[i]之后的,向后移动,腾出一点可用空间 */
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; /* 失败 */
}

111
README.md
View File

@@ -1,10 +1,115 @@
30dayMakeOS
30dayMakeOS —— OSASK
===========
《30天自制操作系统》源码中文版。自己制作一个操作系统的过程
阅读过程会一边汉化源码,一边执行还有根据一些相关的内容进行代码的书写,欢迎大家交流。
运行方法,在tolset中新建一个run文件夹,把代码拷贝进去,然后根据系统版本运行!cons_**.bat。
运行方法,在 `tolset` 中新建一个 `run` 文件夹,把代码拷贝进去,然后根据系统版本运行 `!cons_**.bat`
命令跟进每天的内容会有不同,接下来会写博客跟进,也可以直接看书。
一般都是使用 `make run` 运行代码。可以直接看书。
## 内容简介
### 第一周第1天第7天
一开始首先要考虑怎么来写一个“只要一通电就能运行的程序”。这部分用C语言写起来有些困难所以主要还是用汇编语言来写。
这步完成之后下一步就要写一个从磁盘读取操作系统的程序。这时即便打开电脑电源它也不会自动地将操作系统全部都读进来它只能读取磁盘上最开始的512字节的内容所以我们要编写剩余部分的载入程序。这个程序也要用汇编语言编写。
一旦完成了这一步以后的程序就可以用C语言来编写了。我们就尽快使用C语言来学习开发显示画面的程序。同时我们也能慢慢熟悉C语言语法。这个时候我们好像在做自己想做的事但事实上我们还没有自由操纵C语言。
接下来为了实现“移动鼠标”这一雄心我们要对CPU进行细致的设定并掌握中断处理程序的写法。从全书总体看来这一部分是水平相当高的部分笔者也觉得放在这里有些不妥但从本书条理上讲这些内容必须放在这里所以只好请大家忍耐一下了。在这里CPU的规格以及电脑复杂的规格都会给我们带来各种各样的麻烦。而且开发语言既有C语言又有汇编语言这又给我们造成了更大的混乱。这个时候我们一点儿也不会觉得这是在做自己想做的事怎么看都像是在“受人摆布”。
渡过这个痛苦的时期,第一周就该结束了。
### 第二周第8天第14天
一周的苦战还是很有意义的回头一看我们就会发现自己还是斩获颇丰的。这时我们已经基本掌握了C语言的语法连汇编语言的水平也能达到本书的要求了。
所以现在我们就可以着手开发像样的操作系统了。但是这一次我们又要为算法头痛了。即使掌握了编程语言的语法,如果不懂得好的算法的话,也还是不能开发出来自己想要的操作系统。
所以这一周我们就边学习算法边慢慢地开发操作系统。不过到了这一阶段,我们就能感觉到基本上不会再受技术问题限制了。
### 第三周第15天第21天
现在我们的技术已经相当厉害了,可以随心所欲地开发自己的操作系统了。首先是要支持多任务,然后是开发命令行窗口,之后就可以着手开发应用程序了。
到本周结束时,就算还不够完备,我们也能拿出一个可以称之为操作系统的软件了。
### 第四周第22天第28天
在这个阶段,我们可以尽情地给操作系统增加各种各样的功能,同时还可以开发出大量像模像样的应用程序来。
这个阶段我们已经能做得很好了,这可能也是我们最高兴的时期。这部分要讲解的内容很少,笔者也不用再煞费苦心地去写那些文字说明了,可以把精力都集中在编程上(笑)。
对了,说起文字才想起来,正好在这个时期可以让我们的操作系统显示文字了。
### 免费赠送两天第29天第30天
剩下的两天用来润色加工。这两天我们来做一些之前没来得及做,但做起来既简单又有趣的内容。
## 川合堂许可协议
### 概要
通俗地说:“这是自由软件,使用前使用后都无须支付任何费用,可以自由使用,也可以
复制、修改以及用于商业目的但是作者对软件的bug以及因此所造成的损失不负任何责
任。”
为了保护软件使用者以及软件修改者、参考者的利益,即便作者将来为该软件中所使用的
算法申请专利,也保证不会向使用者收取授权费用。
### 目的
适用于本协议的软件,旨在为公众带来利益,以及为软件技术的进步做出贡献。
#### 宗旨
本协议并不代表作者放弃著作权(仅放弃独家复制发布的权利),使用者可以自由复制并
再次发布本软件的一部分甚至全部内容。使用时无须支付任何费用,对本软件的解析、修改
也无须支付任何费用。
适用于本协议的软件,可以无条件地用作商业目的,甚至可以将软件直接有偿出售。
对于以适用于本协议的软件的一部分或全部内容为基础,在此之上所开发的软件(下称“
派生物”),可以赋予任何种类的许可协议。即,派生物的作者可以禁止对派生物进行复制,
也可以只允许派生物以有偿形式发布。派生物的著作权属于该派生物的生成者,适用于本协
议的软件作者不会对其派生物主张著作权。
在派生物的文档中,没有义务对原始软件的作者进行介绍,但这句话,理所当然地,不意
味着禁止这一行为。
在发布派生物时,没有义务取得原始软件作者的同意,但这句话,理所当然地,不意味着
禁止这一行为。
作者不对软件的质量作出任何保证,因此,由于使用本软件所造成的损害,或者没有达到
所期望的结果,作者不负任何责任。
对于适用于本协议的软件中所使用的技术,除了事先取得作者授权的人以外,禁止其他人
对其申请专利。但如果附加了新的技术并生成了派生物,允许对于追加的部分申请专利。作
者在将来有可能对软件中的技术申请专利,但保证不会向派生物以及软件的使用收取授权费
用。本保证不仅适用于申请专利之前所生成的派生物,也适用于专利取得后所生成的派生物。
将解析结果汇总并申请专利,需要事先取得作者的同意,但对于申请专利以外的行为,没
有任何限制。
### Links
[川合堂](http://www.imasy.org/~mone/kawaido/)
[kawai](http://www.imasy.org/~kawai/)
[豆瓣图书链接](http://book.douban.com/subject/11530329/)
[OSASK计划](http://http://osask.net/)
[OSASK wiki](http://ja.wikipedia.org/wiki/OSASK)
[source code at sourceforge](http://zh.sourceforge.jp/projects/osask/releases/?package_id=10517)
### 工具软件使用
[GNU GPL协议](http://www.gnu.org/licenses/gpl-3.0.html)
[GNU LGPL协议](http://www.gnu.org/licenses/lgpl-3.0.html)