课上
lab5-1 exam
从 rtc
态获取时间,并且实现用户态的进程休眠,比较简单。
注意读写外设系统调用的使用。
代码:
/**********user/include/lib.h**********/
u_int get_time(u_int *us);
void usleep(u_int us);
/*************user/lib/ipc.c***********/
u_int get_time(u_int *us) {
u_int tmp = 0;
u_int total = 0;
u_int accur = 0;
u_long RTC_ADDR = 0x15000000;
u_long OFF0 = 0x0000;
u_long OFF1 = 0x0010;
u_long OFF2 = 0x0020;
syscall_read_dev((void*)&tmp, RTC_ADDR + OFF0, 4);
syscall_read_dev((void*)&total, RTC_ADDR + OFF1, 4);
syscall_read_dev((void*)&accur, RTC_ADDR + OFF2, 4);
*us = accur;
return total;
}
void usleep(u_int us) {
// 读取进程进入 usleep 函数的时间
u_int total1;
u_int us1;
total1 = get_time(&us1);
while (1) {
// 读取当前时间
u_int us2;
u_int total2;
total2 = get_time(&us2);
if ((u_long)total2 * 1000000 + us2 >= (u_long)total1 * 1000000 + us1 + us) {
return;
} else {
// 进程切换
syscall_yield();
}
}
}
lab5-1 extra
模拟固态硬盘的管理,实现固态硬盘初始化、读写及擦除,重点是均匀磨损的实现。
没做出来,评测显示 ssd_read()
返回值错误,发现是擦除磁盘逻辑块对应物理块后未将其映射物理块设为空,非常可惜。
代码:
/***************fs/serv.h**************/
void ssd_init();
int ssd_read(u_int logic_no, void *dst);
void ssd_write(u_int logic_no, void *src);
void ssd_erase(u_int logic_no);
/***************fs/ide.c***************/
int flash_map[64];
int phy_bitmap;
int erase_cnt[64];
void era_phy(int id) {
phy_bitmap |= (1 << id);
erase_cnt[id]++; //add cnt when erase
char arr[512];
memset(arr, 0, sizeof(arr)); //all zero
ide_write(0, id, (void*)arr, 1);
}
int alloc_phy() {
int tar = -1;
int cnt = -1;
for (int i = 0; i < 32; ++i) {
if (phy_bitmap & (1 << i)) {
if (tar == -1) {
tar = i;
cnt = erase_cnt[i];
} else {
if (cnt > erase_cnt[i]) {
tar = i;
cnt = erase_cnt[i];
}
}
}
}
//panic_on(tar == -1);
if (cnt >= 5) {
int a = tar;
tar = -1;
cnt = -1;
for (int i = 0; i < 32; ++i) {
if ((phy_bitmap & (1 << i)) == 0) {
if (tar == -1) {
tar = i;
cnt = erase_cnt[i];
} else {
if (cnt > erase_cnt[i]) {
tar = i;
cnt = erase_cnt[i];
}
}
}
}
//panic_on(tar == -1);
int b = tar;
char arr[512];
ide_read(0, b, (void*)arr, 1);
for (int j = 0; j <= 31; j++) {
if (flash_map[j] == b) {
flash_map[j] == a;
break;
}
} //renew phy
ide_write(0, a, (void*)arr, 1);
phy_bitmap &= ~(1 << a); //a nwr
phy_bitmap |= (1 << b); //b wr
//era_phy(b);
era_phy(b);
} else {
}
return tar;
}
void ssd_init() {
int total = 0;
phy_bitmap = -1;
memset(flash_map, -1, sizeof(flash_map)); //-1;
memset(erase_cnt, 0, sizeof(erase_cnt));
}
int ssd_read(u_int logic_no, void *dst) {
if (flash_map[logic_no] == -1) return -1;
ide_read(0, flash_map[logic_no], dst, 1); //read
return 0;
}
void ssd_write(u_int logic_no, void *src) {
if (flash_map[logic_no] == -1) {
flash_map[logic_no] = alloc_phy();
phy_bitmap &= ~(1 << flash_map[logic_no]); //not writable
ide_write(0, flash_map[logic_no], src, 1);
} else {
ssd_erase(logic_no);
flash_map[logic_no] = alloc_phy();
phy_bitmap &= ~(1 << flash_map[logic_no]); //not writable
ide_write(0, flash_map[logic_no], src, 1); //read
}
}
void ssd_erase(u_int logic_no) {
if (flash_map[logic_no] == -1) return;
era_phy(flash_map[logic_no]);
flash_map[logic_no] = -1; //reset
}