-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMachine.cpp
145 lines (132 loc) · 3.79 KB
/
Machine.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "Machine.h"
#include "Kernel.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <iostream>
using namespace std;
Machine::Machine()
{
}
Machine::~Machine()
{
}
void Machine::Initialize()
{
this->m_BufferManager = &Kernel::Instance().GetBufferManager();
int fd = open(devpath, O_RDWR); // 打开镜像文件
if (fd == -1)
{
fd = open(devpath, O_RDWR | O_CREAT, 0666);
if (fd == -1)
{
sys_err("Machine Init Error!");
exit(-1);
}
// 初始化镜像文件
this->init_img(fd);
}
// 用mmap映射进来
mmap_img(fd);
this->img_fd = fd;
}
void Machine::quit()
{
struct stat st; // 定义文件信息结构体
/*取得文件大小*/
int r = fstat(this->img_fd, &st);
if (r == -1)
{
sys_err("Failt to get the infomation of img!");
close(this->img_fd);
exit(-1);
}
int len = st.st_size;
// 将mmap内容刷回去
msync((void *)(this->m_BufferManager->GetMmapAddr()), len, MS_SYNC);
}
void Machine::init_spb(SuperBlock &sb)
{
// 初始化sqb
sb.s_isize = FileSystem::INODE_ZONE_SIZE;
sb.s_fsize = FileSystem::DATA_ZONE_END_SECTOR + 1;
sb.s_nfree = (FileSystem::DATA_ZONE_SIZE - 99) % 100;
int start_last_datablk = FileSystem::DATA_ZONE_START_SECTOR;
while (true)
{
if ((start_last_datablk + 100 - 1) < FileSystem::DATA_ZONE_END_SECTOR)
start_last_datablk += 100;
else
break;
}
start_last_datablk--;
for (int i = 0; i < sb.s_nfree; ++i)
sb.s_free[i] = start_last_datablk + i;
sb.s_ninode = 100;
for (int i = 0; i < sb.s_ninode; ++i)
sb.s_inode[i] = i;
sb.s_fmod = 0;
sb.s_ronly = 0;
}
void Machine::init_db(char *data)
{
struct
{
int nfree;
int free[100];
} tmp_table;
int last_datablk_num = FileSystem::DATA_ZONE_SIZE;
for (int i = 0;; i++)
{
if (last_datablk_num >= 100)
tmp_table.nfree = 100;
else
tmp_table.nfree = last_datablk_num;
last_datablk_num -= tmp_table.nfree;
for (int j = 0; j < tmp_table.nfree; j++)
{
if (i == 0 && j == 0)
tmp_table.free[j] = 0;
else
{
tmp_table.free[j] = 100 * i + j + FileSystem::DATA_ZONE_START_SECTOR - 1;
}
}
memcpy(&data[99 * 512 + i * 100 * 512], (void *)&tmp_table, sizeof(tmp_table));
if (last_datablk_num == 0)
break;
}
}
void Machine::init_img(int fd)
{
SuperBlock spb;
init_spb(spb); // 初始化SPB
DiskInode *di_table = new DiskInode[FileSystem::INODE_ZONE_SIZE * FileSystem::INODE_NUMBER_PER_SECTOR];
di_table[0].d_mode = Inode::IFDIR;
di_table[0].d_mode |= Inode::IEXEC;
char *datablock = new char[FileSystem::DATA_ZONE_SIZE * 512];
memset(datablock, 0, FileSystem::DATA_ZONE_SIZE * 512);
init_db(datablock); // 初始化DB
write(fd, &spb, sizeof(SuperBlock));
write(fd, di_table, FileSystem::INODE_ZONE_SIZE * FileSystem::INODE_NUMBER_PER_SECTOR * sizeof(DiskInode));
write(fd, datablock, FileSystem::DATA_ZONE_SIZE * 512);
sys_log("Disk Initialize complete!");
}
void Machine::mmap_img(int fd)
{
struct stat st;
int r = fstat(fd, &st);
if (r == -1)
{
sys_err("Failt to get the info of img!");
close(fd);
exit(-1);
}
int len = st.st_size;
// 使用mmap映射
char *addr = (char *)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
this->m_BufferManager->SetMmapAddr(addr);
}