#include "type.h"
#include "config.h"
#include "const.h"
#include "protect.h"
#include "console.h"
#include "tty.h"
#include "proc.h"
#include "proto.h"
#include "string.h"
#include "fs.h"
#include "hd.h"
#include "global.h"
PRIVATE void init_fs();
PRIVATE void mkfs();
PRIVATE void read_super_block(int dev);
PRIVATE int fs_fork();
PRIVATE int fs_exit();
/**
* <Ring 1> The main loop of TASK FS.
*/
PUBLIC void task_fs()
{
printl("Task FS begins.\n");
init_fs();
while (1) {
send_recv(RECEIVE, ANY, &fs_msg);
int src = fs_msg.source;
pcaller = &proc_table[src];
switch (fs_msg.type) {
case OPEN:
fs_msg.FD = do_open();
break;
case CLOSE:
fs_msg.RETVAL = do_close();
break;
case READ:
case WRITE:
fs_msg.CNT = do_rdwt();
break;
case UNLINK:
fs_msg.RETVAL = do_unlink();
break;
case RESUME_PROC:
src = fs_msg.PROC_NR;
break;
case FORK:
fs_msg.RETVAL = fs_fork();
break;
case EXIT:
fs_msg.RETVAL = fs_exit();
break;
case STAT:
fs_msg.RETVAL = do_stat();
break;
case LSEEK:
fs_msg.OFFSET = do_lseek();
break;
default:
dump_msg("FS::unknown message:", &fs_msg);
assert(0);
break;
}
/* reply */
if (fs_msg.type != SUSPEND_PROC) {
fs_msg.type = SYSCALL_RET;
send_recv(SEND, src, &fs_msg);
}
}
}
/**
* <Ring 1> Do some preparation.
*/
PRIVATE void init_fs()
{
int i;
/* f_desc_table[] */
for (i = 0; i < NR_FILE_DESC; i++) {
memset(&f_desc_table[i], 0, sizeof(struct file_desc));
}
/* inode_table[] */
for (i = 0; i < NR_INODE; i++) {
memset(&inode_table[i], 0, sizeof(struct inode));
}
/* super_block[] */
struct super_block * sb = super_block;
for (; sb < &super_block[NR_SUPER_BLOCK]; sb++) {
sb->sb_dev = NO_DEV;
}
/* open the device: hard disk */
MESSAGE driver_msg;
driver_msg.type = DEV_OPEN;
driver_msg.DEVICE = MINOR(ROOT_DEV);
assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);
/* read the super block of ROOT DEVICE */
RD_SECT(ROOT_DEV, 1);
sb = (struct super_block *)fsbuf;
if (sb->magic != MAGIC_V1) {
printl("{FS} mkfs\n");
mkfs(); /* make FS */
}
/* load super block of ROOT */
read_super_block(ROOT_DEV);
sb = get_super_block(ROOT_DEV);
assert(sb->magic == MAGIC_V1);
root_inode = get_inode(ROOT_DEV, ROOT_INODE);
}
/**
* <Ring 1> Make a available Orange'S FS in the disk. it will
* - Write a super block to sector 1.
* - Create three special files: dev_tty0, dev_tty1, dev_tty2
* - Create a file cmd.tar
* - Create the inode map
* - Create the sector map
* - Create the inodes of the files
* - Create '/' the root directory
*/
PRIVATE void mkfs()
{
MESSAGE driver_msg;
int i, j;
int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */
/* get the geometry of ROOTDEV */
struct part_info geo;
driver_msg.type = DEV_IOCTL;
driver_msg.DEVICE = MINOR(ROOT_DEV);
driver_msg.REQUEST = DIOCTL_GET_GEO;
driver_msg.BUF = &geo;
driver_msg.PROC_NR = TASK_FS;
assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);
printl("dev size: 0x%x sectors\n", geo.size);
/* super block */
struct super_block sb;
sb.magic = MAGIC_V1;
sb.nr_inodes = bits_per_sect;
sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
sb.nr_sects = geo.size; /* partition size in sector */
sb.nr_imap_sects = 1;
sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1;
sb.n_1st_sect = 1 + 1 + /* boot sector & super block */
sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
sb.root_inode = ROOT_INODE;
sb.inode_size = INODE_SIZE;
struct inode x;
sb.inode_isize_off = (int)&x.i_size - (int)&x;
sb.inode_start_off = (int)&x.i_start_sect - (int)&x;
sb.dir_ent_size = DIR_ENTRY_SIZE;
struct dir_entry de;
sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de;
sb.dir_ent_fname_off = (int)&de.name - (int)&de;
memset(fsbuf, 0x90, SECTOR_SIZE);
memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);
/* write the super block */
WR_SECT(ROOT_DEV, 1);
printl("devbase:0x%x00, sb:0x%x00, imap:0x%x00, smap:0x%x00\n",
geo.base * 2,
(geo.base + 1) * 2,
(geo.base + 1 + 1) * 2,
(geo.base + 1 + 1 + sb.nr_imap_sects) * 2);
printl(" inodes:0x%x00, 1st_sector:0x%x00\n",
(geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
(geo.base + sb.n_1st_sect) * 2);
/* inode map */
memset(fsbuf, 0, SECTOR_SIZE);
for (i = 0; i < (NR_CONSOLES + 3); i++) {
fsbuf[0] |= 1 << i;
}
assert(fsbuf[0] == 0x3F); /* 0011 1111 :
* || ||||
* || |||`--- bit 0 : reserved
* || ||`---- bit 1 : the first inode,
* || || which indicates `/'
* || |`----- bit 2 : /dev_tty0
* || `------ bit 3 : /dev_tty1
* |`-------- bit 4 : /dev_tty2
* `--------- bit 5 : /cmd.tar
*/
WR_SECT(ROOT_DEV, 2);
/* sector map */
memset(fsbuf, 0, SECTOR_SIZE);
int nr_sects = NR_DEFAULT_FILE_SECTS + 1;
/* ~~~~~~~~~~~~~~~~~~~|~ |
* | `--- bit 0 is reserved
* `-------- for `/'
*/
for (i = 0; i < nr_sects / 8; i++) {
fsbuf[i] = 0xFF;
}
for (j = 0; j < nr_sects % 8; j++) {
fsbuf[i] |= (1 << j);
}
WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);
/* zeromemory the rest sector-map */
memset(fsbuf, 0, SECTOR_SIZE);
for (i = 1; i < sb.nr_smap_sects; i++) {
WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);
}
/* cmd.tar */
int bit_offset = INSTALL_START_SECT - sb.n_1st_sect + 1; /* sect M <-> bit (M - sb.n_1st_sect + 1) */
int bit_off_in_sect = bit_offset % (SECTOR_SIZE * 8);
int bit_left = INSTALL_NR_SECTS;
int cur_sect = bit_offset / (SECTOR_SIZE * 8);
RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
while (bit_left) {
int byte_off = bit_off_in_sect / 8;
/* this line is ineffecient in a loop, but I don't care */
fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8);
bit_left--;
bit_off_in_sect++;
if (bit_off_in_sect == (SECTOR_SIZE * 8)) {
WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
cur_sect++;
RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
bit_off_in_sect = 0;
}
}
WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
/* inodes */
/* inode of '/' */
memset(fsbuf, 0, SECTOR_SIZE);
struct inode * pi = (struct inode*)fsbuf;
pi->i_mode = I_DIRECTORY;
pi->i_size = DIR_ENTRY_SIZE * 5; /* 5 files:
《ORANGE’S:一个操作系统的实现》读书笔记(三十七)尾声(一)文章代码
177 浏览量
2024-01-23
10:26:26
上传
评论
收藏 281KB ZIP 举报
zorro_z
- 粉丝: 661
- 资源: 26
最新资源
- STC12C5A60S2单片机+LCD12864液晶显示手机菜单实例源码KEIL C51工程文件.zip
- !!!CSDN上唯一能拿得出手的ASP.NET MVC程序 ASP.NET MVC鞋类销售商城系统
- Screenshot_2024-06-01-10-11-15-96_a935a6faaffa07c582f2c3acde62ae6b.jpg
- STC12C5A60S2单片机+LCD12864液晶图片动画显示实例源码KEIL C51工程文件.zip
- Transmission是一种BitTorrent客户端,他支持了多种操作系统,并且支持多种Nas设备
- 单家独院式农房户型设计水电图.dwg
- STC12C5A60S2单片机+LCD12864俄罗斯方块源码程序实例源码KEIL C51工程文件.zip
- 编程IDE等宽字体,不错的
- FlowGeek FlowGeek是基于MVP架构的、遵循Material Design设计规范的开源中国社区客户端
- 单家独院式图纸农房户型设计90平09.20-t3.dwg
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈