文件系统重构
This commit is contained in:
parent
8a2a8685e4
commit
7e471c20ba
0
boot/asmfunc.asm
Normal file
0
boot/asmfunc.asm
Normal file
12
build.py
12
build.py
@ -80,6 +80,15 @@ def build_network(): # 构建网络系统
|
|||||||
return -1
|
return -1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def build_fs(): # 构建文件系统
|
||||||
|
print("Building fs source code...")
|
||||||
|
for file in os.listdir(cd + '\\fs'):
|
||||||
|
cmd = cd + gcc + " " + "fs\\" + file + " -o " + "target\\" + file.split(".")[0] + ".o"
|
||||||
|
e = os.system(cmd)
|
||||||
|
if e != 0:
|
||||||
|
return -1
|
||||||
|
return 0
|
||||||
|
|
||||||
def linker(): # 交叉编译链接
|
def linker(): # 交叉编译链接
|
||||||
print("Linking object files...")
|
print("Linking object files...")
|
||||||
source_file = ""
|
source_file = ""
|
||||||
@ -106,6 +115,9 @@ a = build_sysapp()
|
|||||||
if a != 0:
|
if a != 0:
|
||||||
exit(-1)
|
exit(-1)
|
||||||
a = build_network()
|
a = build_network()
|
||||||
|
if a != 0:
|
||||||
|
exit(-1)
|
||||||
|
a = build_fs()
|
||||||
if a != 0:
|
if a != 0:
|
||||||
exit(-1)
|
exit(-1)
|
||||||
a = linker()
|
a = linker()
|
||||||
|
@ -62,35 +62,35 @@ uint8_t read_cmos(uint8_t p) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_hour() {
|
uint32_t get_hour() {
|
||||||
return bcd2hex(read_cmos(CMOS_CUR_HOUR));
|
return bcd2hex(read_cmos(CMOS_CUR_HOUR));
|
||||||
}
|
}
|
||||||
|
|
||||||
;static uint32_t get_min() {
|
uint32_t get_min() {
|
||||||
return bcd2hex(read_cmos(CMOS_CUR_MIN));
|
return bcd2hex(read_cmos(CMOS_CUR_MIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_sec() {
|
uint32_t get_sec() {
|
||||||
return bcd2hex(read_cmos(CMOS_CUR_SEC));
|
return bcd2hex(read_cmos(CMOS_CUR_SEC));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_day_of_month() {
|
uint32_t get_day_of_month() {
|
||||||
return bcd2hex(read_cmos(CMOS_MON_DAY));
|
return bcd2hex(read_cmos(CMOS_MON_DAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_day_of_week() {
|
uint32_t get_day_of_week() {
|
||||||
return bcd2hex(read_cmos(CMOS_WEEK_DAY));
|
return bcd2hex(read_cmos(CMOS_WEEK_DAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_mon() {
|
uint32_t get_mon() {
|
||||||
return bcd2hex(read_cmos(CMOS_CUR_MON));
|
return bcd2hex(read_cmos(CMOS_CUR_MON));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_year() {
|
uint32_t get_year() {
|
||||||
return (bcd2hex(read_cmos(CMOS_CUR_CEN)) * 100) + bcd2hex(read_cmos(CMOS_CUR_YEAR)) + 1980;
|
return (bcd2hex(read_cmos(CMOS_CUR_CEN)) * 100) + bcd2hex(read_cmos(CMOS_CUR_YEAR)) + 1980;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_leap_year(int year) {
|
int is_leap_year(int year) {
|
||||||
if (year % 4 != 0) return 0;
|
if (year % 4 != 0) return 0;
|
||||||
if (year % 400 == 0) return 1;
|
if (year % 400 == 0) return 1;
|
||||||
return year % 100 != 0;
|
return year % 100 != 0;
|
||||||
|
62
driver/dma.c
Normal file
62
driver/dma.c
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include "../include/dma.h"
|
||||||
|
#include "../include/io.h"
|
||||||
|
|
||||||
|
unsigned char MaskReg[8] = {0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4};
|
||||||
|
unsigned char ModeReg[8] = {0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6};
|
||||||
|
unsigned char ClearReg[8] = {0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8};
|
||||||
|
|
||||||
|
unsigned char PagePort[8] = {0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A};
|
||||||
|
unsigned char AddrPort[8] = {0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC};
|
||||||
|
unsigned char CountPort[8] = {0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE};
|
||||||
|
|
||||||
|
void dma_xfer(unsigned char channel, unsigned long address, unsigned int length,
|
||||||
|
unsigned char read) {
|
||||||
|
unsigned char page = 0, mode = 0;
|
||||||
|
unsigned int offset = 0;
|
||||||
|
|
||||||
|
if (read)
|
||||||
|
mode = 0x48 + channel;
|
||||||
|
else
|
||||||
|
mode = 0x44 + channel;
|
||||||
|
|
||||||
|
page = address >> 16;
|
||||||
|
offset = address & 0xFFFF;
|
||||||
|
length--;
|
||||||
|
|
||||||
|
_dma_xfer(channel, page, offset, length, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _dma_xfer(unsigned char DMA_channel, unsigned char page,
|
||||||
|
unsigned int offset, unsigned int length, unsigned char mode) {
|
||||||
|
/* 我们不想别的事情来打扰 */
|
||||||
|
asm("cli");
|
||||||
|
|
||||||
|
/* 设置DMA通道,以便我们可以正确传输数据,这很简单,只要我们用I/O操作告诉DMA控制器就行了
|
||||||
|
*/
|
||||||
|
/* 我们将使用这个通道(DMA_channel)*/
|
||||||
|
io_out8(MaskReg[DMA_channel], 0x04 | DMA_channel);
|
||||||
|
|
||||||
|
/* 我们先得解除DMA对这个通道的屏蔽,不然用不了 */
|
||||||
|
io_out8(ClearReg[DMA_channel], 0x00);
|
||||||
|
|
||||||
|
/* 向DMA发送指定的模式 */
|
||||||
|
io_out8(ModeReg[DMA_channel], mode);
|
||||||
|
|
||||||
|
/* 发送偏移量地址,先发送高八位,再发送低八位(因为一次性最多只能发送一个byte)
|
||||||
|
*/
|
||||||
|
io_out8(AddrPort[DMA_channel], LOW_BYTE(offset));
|
||||||
|
io_out8(AddrPort[DMA_channel], HI_BYTE(offset));
|
||||||
|
|
||||||
|
/* 发送数据所在的物理页 */
|
||||||
|
io_out8(PagePort[DMA_channel], page);
|
||||||
|
|
||||||
|
/* 发送数据的长度 跟之前一样,先发送低八位,再发送高八位*/
|
||||||
|
io_out8(CountPort[DMA_channel], LOW_BYTE(length));
|
||||||
|
io_out8(CountPort[DMA_channel], HI_BYTE(length));
|
||||||
|
|
||||||
|
/* 现在我们该做的东西已经全部做完了,所以启用DMA_channel */
|
||||||
|
io_out8(MaskReg[DMA_channel], DMA_channel);
|
||||||
|
|
||||||
|
/* 重新让CPU能够接收到中断 */
|
||||||
|
asm("sti");
|
||||||
|
}
|
399
driver/floppy.c
Normal file
399
driver/floppy.c
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
#include "../include/floppy.h"
|
||||||
|
#include "../include/task.h"
|
||||||
|
#include "../include/printf.h"
|
||||||
|
#include "../include/vdisk.h"
|
||||||
|
#include "../include/io.h"
|
||||||
|
#include "../include/dma.h"
|
||||||
|
|
||||||
|
struct task_struct *floppy_use;
|
||||||
|
struct task_struct *waiter;
|
||||||
|
volatile int floppy_int_count = 0;
|
||||||
|
|
||||||
|
static volatile int done = 0;
|
||||||
|
static int dchange = 0;
|
||||||
|
static int motor = 0;
|
||||||
|
static int mtick = 0;
|
||||||
|
static volatile int tmout = 0;
|
||||||
|
static unsigned char status[7] = {0};
|
||||||
|
static unsigned char statsz = 0;
|
||||||
|
static unsigned char sr0 = 0;
|
||||||
|
static unsigned char fdc_track = 0xff;
|
||||||
|
static DrvGeom geometry = {DG144_HEADS, DG144_TRACKS, DG144_SPT};
|
||||||
|
unsigned long tbaddr = 0x80000L;
|
||||||
|
|
||||||
|
static void Read(char drive, unsigned char *buffer, unsigned int number,
|
||||||
|
unsigned int lba) {
|
||||||
|
floppy_use = get_current();
|
||||||
|
for (int i = 0; i < number; i += SECTORS_ONCE) {
|
||||||
|
int sectors = ((number - i) >= SECTORS_ONCE) ? SECTORS_ONCE : (number - i);
|
||||||
|
fdc_rw(lba + i, buffer + i * 512, 1, sectors);
|
||||||
|
}
|
||||||
|
floppy_use = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Write(char drive, unsigned char *buffer, unsigned int number,
|
||||||
|
unsigned int lba) {
|
||||||
|
floppy_use = get_current();
|
||||||
|
for (int i = 0; i < number; i += SECTORS_ONCE) {
|
||||||
|
int sectors = ((number - i) >= SECTORS_ONCE) ? SECTORS_ONCE : (number - i);
|
||||||
|
fdc_rw(lba + i, buffer + i * 512, 0, sectors);
|
||||||
|
}
|
||||||
|
floppy_use = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_floppy() {
|
||||||
|
sendbyte(CMD_VERSION); //发送命令(获取软盘版本),如果收到回应,说明软盘正在工作
|
||||||
|
if (getbyte() == -1) {
|
||||||
|
printf("floppy: no floppy drive found\n");
|
||||||
|
printf("No fount FDC\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_interrupt_handler(0x26,flint);
|
||||||
|
|
||||||
|
printf("[\035floppy\036]: FLOPPY DISK:RESETING\n");
|
||||||
|
reset(); //重置软盘驱动器
|
||||||
|
printf("[\035floppy\036]:FLOPPY DISK:reset over!\n");
|
||||||
|
sendbyte(CMD_VERSION); //获取软盘版本
|
||||||
|
printf("[\035floppy\036]:FDC_VER:0x%x\n", getbyte()); //并且输出到屏幕上
|
||||||
|
vdisk vd;
|
||||||
|
strcpy(vd.DriveName, "floppy");
|
||||||
|
vd.Read = Read;
|
||||||
|
vd.Write = Write;
|
||||||
|
vd.size = 1474560;
|
||||||
|
vd.flag = 1;
|
||||||
|
register_vdisk(vd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fdc_rw_ths(int track,
|
||||||
|
int head,
|
||||||
|
int sector,
|
||||||
|
unsigned char* blockbuff,
|
||||||
|
int read,
|
||||||
|
unsigned long nosectors) {
|
||||||
|
// 跟上面的大同小异
|
||||||
|
int tries, copycount = 0;
|
||||||
|
unsigned char* p_tbaddr = (char*)0x80000;
|
||||||
|
unsigned char* p_blockbuff = blockbuff;
|
||||||
|
|
||||||
|
motoron();
|
||||||
|
|
||||||
|
if (!read && blockbuff) {
|
||||||
|
for (copycount = 0; copycount < (nosectors * 512); copycount++) {
|
||||||
|
*p_tbaddr = *p_blockbuff;
|
||||||
|
p_blockbuff++;
|
||||||
|
p_tbaddr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tries = 0; tries < 3; tries++) {
|
||||||
|
if (io_in8(FDC_DIR) & 0x80) {
|
||||||
|
dchange = 1;
|
||||||
|
seek(1);
|
||||||
|
recalibrate();
|
||||||
|
motoroff();
|
||||||
|
|
||||||
|
return fdc_rw_ths(track, head, sector, blockbuff, read, nosectors);
|
||||||
|
}
|
||||||
|
if (!seek(track)) {
|
||||||
|
motoroff();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_out8(FDC_CCR, 0);
|
||||||
|
|
||||||
|
if (read) {
|
||||||
|
dma_xfer(2, tbaddr, nosectors * 512, 0);
|
||||||
|
sendbyte(CMD_READ);
|
||||||
|
} else {
|
||||||
|
dma_xfer(2, tbaddr, nosectors * 512, 1);
|
||||||
|
sendbyte(CMD_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendbyte(head << 2);
|
||||||
|
sendbyte(track);
|
||||||
|
sendbyte(head);
|
||||||
|
sendbyte(sector);
|
||||||
|
sendbyte(2);
|
||||||
|
sendbyte(geometry.spt);
|
||||||
|
|
||||||
|
if (geometry.spt == DG144_SPT)
|
||||||
|
sendbyte(DG144_GAP3RW);
|
||||||
|
else
|
||||||
|
sendbyte(DG168_GAP3RW);
|
||||||
|
sendbyte(0xff);
|
||||||
|
|
||||||
|
wait_floppy_interrupt();
|
||||||
|
|
||||||
|
if ((status[0] & 0xc0) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
recalibrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
motoroff();
|
||||||
|
|
||||||
|
if (read && blockbuff) {
|
||||||
|
p_blockbuff = blockbuff;
|
||||||
|
p_tbaddr = (char*)0x80000;
|
||||||
|
for (copycount = 0; copycount < (nosectors * 512); copycount++) {
|
||||||
|
*p_blockbuff = *p_tbaddr;
|
||||||
|
p_blockbuff++;
|
||||||
|
p_tbaddr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tries != 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int write_floppy_for_ths(int track,
|
||||||
|
int head,
|
||||||
|
int sec,
|
||||||
|
unsigned char* blockbuff,
|
||||||
|
unsigned long nosec) {
|
||||||
|
int res = fdc_rw_ths(track, head, sec, blockbuff, 0, nosec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flint(registers_t *reg) {
|
||||||
|
floppy_int_count =
|
||||||
|
1; // 设置中断计数器为1,代表中断已经发生(或者是系统已经收到了中断)
|
||||||
|
io_out8(0x20, 0x20); // 发送EOI信号,告诉PIC,我们已经处理完了这个中断
|
||||||
|
//task_run(waiter);
|
||||||
|
// task_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendbyte(int byte) {
|
||||||
|
volatile int msr;
|
||||||
|
int tmo; // 超时计数器
|
||||||
|
|
||||||
|
for (tmo = 0; tmo < 128; tmo++) // 这里我们只给128次尝试的机会
|
||||||
|
{
|
||||||
|
msr = io_in8(FDC_MSR);
|
||||||
|
if ((msr & 0xc0) ==
|
||||||
|
0x80) {
|
||||||
|
io_out8(FDC_DATA, byte);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
io_in8(0x80); /* 等待 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getbyte() {
|
||||||
|
int msr; // 软盘驱动器状态寄存器
|
||||||
|
int tmo; // 软盘驱动器状态寄存器的超时计数器
|
||||||
|
|
||||||
|
for (tmo = 0; tmo < 128; tmo++){
|
||||||
|
msr = io_in8(FDC_MSR);
|
||||||
|
if ((msr & 0xd0) == 0xd0){
|
||||||
|
return io_in8(FDC_DATA);
|
||||||
|
}
|
||||||
|
io_in8(0x80); /* 延时 */
|
||||||
|
}
|
||||||
|
return -1; /* 没读取到 */
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_waiter(struct task_struct *t) {
|
||||||
|
while(waiter); // wait
|
||||||
|
waiter = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(void) {
|
||||||
|
set_waiter(get_current());
|
||||||
|
io_out8(FDC_DOR, 0);
|
||||||
|
|
||||||
|
mtick = 0;
|
||||||
|
motor = 0;
|
||||||
|
|
||||||
|
io_out8(FDC_DRS, 0);
|
||||||
|
|
||||||
|
io_out8(FDC_DOR, 0x0c);
|
||||||
|
|
||||||
|
wait_floppy_interrupt();
|
||||||
|
sendbyte(CMD_SPECIFY);
|
||||||
|
sendbyte(0xdf); /* SRT = 3ms, HUT = 240ms */
|
||||||
|
sendbyte(0x02); /* HLT = 16ms, ND = 0 */
|
||||||
|
|
||||||
|
recalibrate();
|
||||||
|
|
||||||
|
dchange =
|
||||||
|
0; //清除“磁盘更改”状态(将dchange设置为false,让别的函数知道磁盘更改状态已经被清楚了)
|
||||||
|
}
|
||||||
|
void motoron(void) {
|
||||||
|
if (!motor) {
|
||||||
|
mtick = -1; /* 停止电机计时 */
|
||||||
|
io_out8(FDC_DOR, 0x1c);
|
||||||
|
for (int i = 0; i < 80000; i++)
|
||||||
|
;
|
||||||
|
motor = 1; //设置电机状态为true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 关闭电机 */
|
||||||
|
void motoroff(void) {
|
||||||
|
if (motor) {
|
||||||
|
mtick = 13500; /* 重新初始化电机计时器 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 重新校准驱动器 */
|
||||||
|
void recalibrate() {
|
||||||
|
set_waiter(get_current());
|
||||||
|
/* 先启用电机 */
|
||||||
|
motoron();
|
||||||
|
|
||||||
|
/* 然后重新校准电机 */
|
||||||
|
sendbyte(CMD_RECAL);
|
||||||
|
sendbyte(0);
|
||||||
|
|
||||||
|
/* 等待软盘中断(也就是电机校准成功) */
|
||||||
|
wait_floppy_interrupt();
|
||||||
|
/* 关闭电机 */
|
||||||
|
motoroff();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_floppy_interrupt() {
|
||||||
|
io_sti();
|
||||||
|
while(!floppy_int_count);
|
||||||
|
statsz = 0; // 清空状态
|
||||||
|
while ((statsz < 7) &&(io_in8(FDC_MSR) &(1<< 4))) {
|
||||||
|
status[statsz++] = getbyte(); // 获取数据
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获取中断状态 */
|
||||||
|
sendbyte(CMD_SENSEI);
|
||||||
|
sr0 = getbyte();
|
||||||
|
fdc_track = getbyte();
|
||||||
|
|
||||||
|
floppy_int_count = 0;
|
||||||
|
floppy_use = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int seek(int track) {
|
||||||
|
if (fdc_track == track) /* 目前的磁道和需要seek的磁道一样吗 */
|
||||||
|
{
|
||||||
|
// 一样的话就不用seek了
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
set_waiter(get_current());
|
||||||
|
/* 向软盘控制器发送SEEK命令 */
|
||||||
|
sendbyte(CMD_SEEK);
|
||||||
|
sendbyte(0);
|
||||||
|
sendbyte(track); /* 要seek到的磁道号 */
|
||||||
|
|
||||||
|
/* 发送完之后,软盘理应会送来一个中断 */
|
||||||
|
wait_floppy_interrupt(); // 所以我们需要等待软盘中断
|
||||||
|
|
||||||
|
for (int i = 0; i < 500; i++)
|
||||||
|
;
|
||||||
|
/* 检查一下成功了没有 */
|
||||||
|
if ((sr0 != 0x20) || (fdc_track != track))
|
||||||
|
return 0; // 没成功
|
||||||
|
else
|
||||||
|
return 1; // 成功了
|
||||||
|
}
|
||||||
|
|
||||||
|
void block2hts(int block, int* track, int* head, int* sector) {
|
||||||
|
*track = (block / 18) / 2;
|
||||||
|
*head = (block / 18) % 2;
|
||||||
|
*sector = block % 18 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hts2block(int track, int head, int sector, int* block) {
|
||||||
|
*block = track * 18 * 2 + head * 18 + sector;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fdc_rw(int block,
|
||||||
|
unsigned char* blockbuff,
|
||||||
|
int read,
|
||||||
|
unsigned long nosectors) {
|
||||||
|
set_waiter(get_current());
|
||||||
|
int head, track, sector, tries, copycount = 0;
|
||||||
|
unsigned char* p_tbaddr =
|
||||||
|
(char*)0x80000; // 512byte
|
||||||
|
// 缓冲区(大家可以放心,我们再page.c已经把这里设置为占用了)
|
||||||
|
unsigned char* p_blockbuff = blockbuff; // r/w的数据缓冲区
|
||||||
|
|
||||||
|
/* 获取block对应的ths */
|
||||||
|
block2hts(block, &track, &head, §or);
|
||||||
|
|
||||||
|
motoron();
|
||||||
|
|
||||||
|
if (!read && blockbuff) {
|
||||||
|
/* 从数据缓冲区复制数据到轨道缓冲区 */
|
||||||
|
for (copycount = 0; copycount < (nosectors * 512); copycount++) {
|
||||||
|
*p_tbaddr = *p_blockbuff;
|
||||||
|
p_blockbuff++;
|
||||||
|
p_tbaddr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tries = 0; tries < 3; tries++) {
|
||||||
|
/* 检查 */
|
||||||
|
if (io_in8(FDC_DIR) & 0x80) {
|
||||||
|
waiter = NULL;
|
||||||
|
dchange = 1;
|
||||||
|
seek(1); /* 清除磁盘更改 */
|
||||||
|
recalibrate();
|
||||||
|
motoroff();
|
||||||
|
return fdc_rw(block, blockbuff, read, nosectors);
|
||||||
|
}
|
||||||
|
waiter = NULL;
|
||||||
|
/* seek到track的位置*/
|
||||||
|
if (!seek(track)) {
|
||||||
|
motoroff();
|
||||||
|
waiter = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
set_waiter(get_current());
|
||||||
|
/* 传输速度(500K/s) */
|
||||||
|
io_out8(FDC_CCR, 0);
|
||||||
|
|
||||||
|
/* 发送命令 */
|
||||||
|
if (read) {
|
||||||
|
dma_xfer(2, tbaddr, nosectors * 512, 0);
|
||||||
|
sendbyte(CMD_READ);
|
||||||
|
} else {
|
||||||
|
dma_xfer(2, tbaddr, nosectors * 512, 1);
|
||||||
|
sendbyte(CMD_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendbyte(head << 2);
|
||||||
|
sendbyte(track);
|
||||||
|
sendbyte(head);
|
||||||
|
sendbyte(sector);
|
||||||
|
sendbyte(2); /* 每个扇区是512字节 */
|
||||||
|
sendbyte(geometry.spt);
|
||||||
|
|
||||||
|
if (geometry.spt == DG144_SPT)
|
||||||
|
sendbyte(DG144_GAP3RW);
|
||||||
|
else
|
||||||
|
sendbyte(DG168_GAP3RW);
|
||||||
|
sendbyte(0xff);
|
||||||
|
|
||||||
|
/* 等待中断...... */
|
||||||
|
/* 读写数据不需要中断状态 */
|
||||||
|
wait_floppy_interrupt();
|
||||||
|
|
||||||
|
if ((status[0] & 0xc0) == 0)
|
||||||
|
break; /* worked! outta here! */
|
||||||
|
waiter = NULL;
|
||||||
|
recalibrate(); /* az,报错了,再试一遍 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 关闭电动机 */
|
||||||
|
motoroff();
|
||||||
|
|
||||||
|
if (read && blockbuff) {
|
||||||
|
/* 复制数据 */
|
||||||
|
p_blockbuff = blockbuff;
|
||||||
|
p_tbaddr = (char*)0x80000;
|
||||||
|
for (copycount = 0; copycount < (nosectors * 512); copycount++) {
|
||||||
|
*p_blockbuff = *p_tbaddr;
|
||||||
|
p_blockbuff++;
|
||||||
|
p_tbaddr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tries != 3);
|
||||||
|
}
|
236
fs/file.c
Normal file
236
fs/file.c
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
#include "../include/file.h"
|
||||||
|
#include "../include/memory.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
|
||||||
|
int fseek(FILE *fp, int offset, int whence) {
|
||||||
|
if (whence == 0) {
|
||||||
|
fp->p = offset;
|
||||||
|
} else if (whence == 1) {
|
||||||
|
fp->p += offset;
|
||||||
|
} else if (whence == 2) {
|
||||||
|
fp->p = fp->fileSize + offset;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long ftell(FILE *stream) { return stream->p; }
|
||||||
|
|
||||||
|
FILE *fopen(char *filename, char *mode) {
|
||||||
|
unsigned int flag = 0;
|
||||||
|
FILE *fp = (FILE *)kmalloc(sizeof(FILE));
|
||||||
|
while (*mode != '\0') {
|
||||||
|
switch (*mode) {
|
||||||
|
case 'a':
|
||||||
|
flag |= APPEND;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
flag |= READ;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
flag |= WRITE;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
flag |= PLUS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mode++;
|
||||||
|
}
|
||||||
|
if (vfs_filesize(filename) == -1) {
|
||||||
|
kfree(fp);
|
||||||
|
return NULL; // 找不到
|
||||||
|
} else if (flag & WRITE) {
|
||||||
|
char buffe2[100];
|
||||||
|
// vfs_delfile(filename);
|
||||||
|
// vfs_createfile(filename);
|
||||||
|
}
|
||||||
|
if (flag & WRITE) {
|
||||||
|
fp->fileSize = 0;
|
||||||
|
} else {
|
||||||
|
fp->fileSize = vfs_filesize(filename);
|
||||||
|
}
|
||||||
|
fp->bufferSize = 0;
|
||||||
|
if (flag & READ || flag & PLUS || flag & APPEND) {
|
||||||
|
fp->bufferSize = vfs_filesize(filename);
|
||||||
|
// printk("[Set]BufferSize=%d\n",fp->bufferSize);
|
||||||
|
}
|
||||||
|
if (flag & WRITE || flag & PLUS || flag & APPEND) {
|
||||||
|
fp->bufferSize += 100;
|
||||||
|
}
|
||||||
|
if (fp->bufferSize == 0) {
|
||||||
|
fp->bufferSize = 1;
|
||||||
|
}
|
||||||
|
fp->buffer = kmalloc(fp->bufferSize);
|
||||||
|
if (flag & PLUS || flag & APPEND || flag & READ) {
|
||||||
|
// printk("ReadFile........\n");
|
||||||
|
vfs_readfile(filename, fp->buffer);
|
||||||
|
}
|
||||||
|
fp->p = 0;
|
||||||
|
if (flag & APPEND) {
|
||||||
|
fp->p = fp->fileSize;
|
||||||
|
}
|
||||||
|
fp->name = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(fp->name, filename);
|
||||||
|
fp->mode = flag;
|
||||||
|
// printk("[fopen]BufferSize=%d\n",fp->bufferSize);
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
int fgetc(FILE *stream) {
|
||||||
|
if (CANREAD(stream->mode)) {
|
||||||
|
if (stream->p >= stream->fileSize) {
|
||||||
|
return EOF;
|
||||||
|
} else {
|
||||||
|
return stream->buffer[stream->p++];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int fputc(int ch, FILE *stream) {
|
||||||
|
if (CANWRITE(stream->mode)) {
|
||||||
|
// printk("Current Buffer=%s\n",stream->buffer);
|
||||||
|
if (stream->p >= stream->bufferSize) {
|
||||||
|
// printk("Realloc....(%d,%d)\n",stream->p,stream->bufferSize);
|
||||||
|
stream->buffer = realloc(stream->buffer, stream->bufferSize + 100);
|
||||||
|
stream->bufferSize += 100;
|
||||||
|
}
|
||||||
|
if (stream->p >= stream->fileSize) {
|
||||||
|
stream->fileSize++;
|
||||||
|
}
|
||||||
|
// printk("Current Buffer=%s(A)\n",stream->buffer);
|
||||||
|
stream->buffer[stream->p++] = ch;
|
||||||
|
// printk("Current Buffer=%s(B)\n",stream->buffer);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
unsigned int fwrite(const void *ptr, unsigned int size, unsigned int nmemb,
|
||||||
|
FILE *stream) {
|
||||||
|
if (CANWRITE(stream->mode)) {
|
||||||
|
unsigned char *c_ptr = (unsigned char *)ptr;
|
||||||
|
for (int i = 0; i < size * nmemb; i++) {
|
||||||
|
fputc(c_ptr[i], stream);
|
||||||
|
}
|
||||||
|
return nmemb;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsigned int fread(void *buffer, unsigned int size, unsigned int count,
|
||||||
|
FILE *stream) {
|
||||||
|
if (CANREAD(stream->mode)) {
|
||||||
|
unsigned char *c_ptr = (unsigned char *)buffer;
|
||||||
|
for (int i = 0; i < size * count; i++) {
|
||||||
|
unsigned int ch = fgetc(stream);
|
||||||
|
if (ch == EOF) {
|
||||||
|
return i;
|
||||||
|
} else {
|
||||||
|
c_ptr[i] = ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int fclose(FILE *fp) {
|
||||||
|
if (fp == NULL) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
if (CANWRITE(fp->mode)) {
|
||||||
|
// printk("Save file.....(%s) Size =
|
||||||
|
//%d\n",fp->buffer,fp->fileSize);
|
||||||
|
// Edit_File(fp->name, fp->buffer, fp->fileSize, 0);
|
||||||
|
vfs_writefile(fp->name, fp->buffer, fp->fileSize);
|
||||||
|
}
|
||||||
|
kfree(fp->buffer);
|
||||||
|
kfree(fp->name);
|
||||||
|
kfree(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
char *fgets(char *str, int n, FILE *stream) {
|
||||||
|
if (CANREAD(stream->mode)) {
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
unsigned int ch = fgetc(stream);
|
||||||
|
if (ch == EOF) {
|
||||||
|
if (i == 0) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ch == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str[i] = ch;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int fputs(const char *str, FILE *stream) {
|
||||||
|
if (CANWRITE(stream->mode)) {
|
||||||
|
for (int i = 0; i < strlen(str); i++) {
|
||||||
|
fputc(str[i], stream);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
int fprintf(FILE *stream, const char *format, ...) {
|
||||||
|
if (CANWRITE(stream->mode)) {
|
||||||
|
int len;
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
char *buf = kmalloc(1024);
|
||||||
|
len = vsprintf(buf, format, ap);
|
||||||
|
fputs(buf, stream);
|
||||||
|
kfree(buf);
|
||||||
|
va_end(ap);
|
||||||
|
return len;
|
||||||
|
} else {
|
||||||
|
// printk("CAN NOT WRITE\n");
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int feof(FILE *stream) {
|
||||||
|
if (stream->p >= stream->fileSize) {
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int ferror(FILE *stream) { return 0; }
|
||||||
|
int fsz(char *filename) { return vfs_filesize(filename); }
|
||||||
|
|
||||||
|
void EDIT_FILE(char *name, char *dest, int length, int offset) {
|
||||||
|
if (vfs_filesize(name) == -1) {
|
||||||
|
//没有找到文件,创建一个,然后再编辑
|
||||||
|
vfs_createfile(name);
|
||||||
|
EDIT_FILE(name, dest, length, offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vfs_writefile(name, dest, length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int Copy(char *path, char *path1) {
|
||||||
|
unsigned char *path1_file_buffer;
|
||||||
|
if (fsz(path) == -1) {
|
||||||
|
// printk("file not found\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// printk("-----------------------------\n");
|
||||||
|
vfs_createfile(path1);
|
||||||
|
|
||||||
|
path1_file_buffer = kmalloc(fsz(path) + 1);
|
||||||
|
int sz = fsz(path);
|
||||||
|
vfs_readfile(path, path1_file_buffer);
|
||||||
|
vfs_writefile(path1, path1_file_buffer, sz);
|
||||||
|
kfree(path1_file_buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
313
fs/vfs.c
Normal file
313
fs/vfs.c
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* PlantsOS FileSystem Abstract Interface
|
||||||
|
* Copyright by min0911
|
||||||
|
*/
|
||||||
|
#include "../include/printf.h"
|
||||||
|
#include "../include/vfs.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/memory.h"
|
||||||
|
|
||||||
|
vfs_t vfsstl[26];
|
||||||
|
vfs_t vfsMount_Stl[26];
|
||||||
|
vfs_t *vfs_now;
|
||||||
|
|
||||||
|
static vfs_t *drive2fs(uint8_t drive) {
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
if (vfsMount_Stl[i].drive == toupper(drive) && vfsMount_Stl[i].flag == 1) {
|
||||||
|
return &vfsMount_Stl[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vfs_t *ParsePath(char *result) {
|
||||||
|
vfs_t *vfs_result = vfs_now;
|
||||||
|
if (result[1] == ':') {
|
||||||
|
if (!(vfs_result = drive2fs(result[0]))) {
|
||||||
|
printf("Mount Drive is not found!\n");
|
||||||
|
printf("Parse Error.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
delete_char(result, 0);
|
||||||
|
delete_char(result, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
for (int i = 0; i < strlen(result); i++) {
|
||||||
|
if (result[i] == '\\') {
|
||||||
|
result[i] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vfs_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vfs_t *findSeat(vfs_t *vstl) {
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
if (vstl[i].flag == 0) {
|
||||||
|
return &vstl[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vfs_t *check_disk_fs(uint8_t disk_number) {
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
if (vfsstl[i].flag == 1) {
|
||||||
|
if (vfsstl[i].Check(disk_number)) {
|
||||||
|
return &vfsstl[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insert_str1(char *str, char *insert_str1, int pos) {
|
||||||
|
for (int i = 0; i < strlen(insert_str1); i++) {
|
||||||
|
insert_char(str, pos + i, insert_str1[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_mount_disk(uint8_t disk_number, uint8_t drive) {
|
||||||
|
printf("Mount DISK ---- %02x\n", disk_number);
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
if (vfsMount_Stl[i].flag == 1 &&
|
||||||
|
(vfsMount_Stl[i].drive == drive ||
|
||||||
|
vfsMount_Stl[i].disk_number == disk_number)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vfs_t *seat = findSeat(vfsMount_Stl);
|
||||||
|
if (!seat) {
|
||||||
|
printf("can not find a seat of vfsMount_Stl(it's full)\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vfs_t *fs = check_disk_fs(disk_number);
|
||||||
|
if (!fs) {
|
||||||
|
printf("unknow file system.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*seat = *fs;
|
||||||
|
seat->InitFs(seat, disk_number);
|
||||||
|
seat->drive = drive;
|
||||||
|
seat->disk_number = disk_number;
|
||||||
|
seat->flag = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_unmount_disk(uint8_t drive) {
|
||||||
|
printf("Unmount disk ---- %c\n", drive);
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
if (vfsMount_Stl[i].drive == drive && vfsMount_Stl[i].flag == 1) {
|
||||||
|
vfsMount_Stl[i].DeleteFs(&vfsMount_Stl[i]);
|
||||||
|
vfsMount_Stl[i].flag = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Not found the drive.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_readfile(char *path, char *buffer) {
|
||||||
|
char *new_path = kmalloc(strlen(path) + 1);
|
||||||
|
strcpy(new_path, path);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->ReadFile(vfs, new_path, buffer);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_writefile(char *path, char *buffer, int size) {
|
||||||
|
char *new_path = kmalloc(strlen(path) + 1);
|
||||||
|
strcpy(new_path, path);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->WriteFile(vfs, new_path, buffer, size);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t vfs_filesize(char *filename) {
|
||||||
|
char *new_path = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(new_path, filename);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int result = vfs->FileSize(vfs, new_path); // 没找到文件统一返回-1
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
List *vfs_listfile(char *dictpath) { // dictpath == "" 则表示当前路径
|
||||||
|
if (strcmp(dictpath, "") == 0) {
|
||||||
|
return vfs_now->ListFile(vfs_now, dictpath);
|
||||||
|
} else {
|
||||||
|
char *new_path = kmalloc(strlen(dictpath) + 1);
|
||||||
|
strcpy(new_path, dictpath);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
List *result = vfs->ListFile(vfs, new_path);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_delfile(char *filename) {
|
||||||
|
char *new_path = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(new_path, filename);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->DelFile(vfs, new_path);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_deldir(char *dictname) {
|
||||||
|
char *new_path = kmalloc(strlen(dictname) + 1);
|
||||||
|
strcpy(new_path, dictname);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->DelDict(vfs, new_path);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_createfile(char *filename) {
|
||||||
|
char *new_path = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(new_path, filename);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->CreateFile(vfs, new_path);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_createdict(char *filename) {
|
||||||
|
char *new_path = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(new_path, filename);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->CreateDict(vfs, new_path);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_renamefile(char *filename, char *filename_of_new) {
|
||||||
|
char *new_path = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(new_path, filename);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->RenameFile(vfs, new_path, filename_of_new);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_attrib(char *filename, ftype type) {
|
||||||
|
char *new_path = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(new_path, filename);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int result = vfs->Attrib(vfs, new_path, type);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_format(uint8_t disk_number, char *FSName) {
|
||||||
|
for (int i = 0; i < 255; i++) {
|
||||||
|
if (strcmp(vfsstl[i].FSName, FSName) == 0 && vfsstl[i].flag == 1) {
|
||||||
|
return vfsstl[i].Format(disk_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfs_file *vfs_fileinfo(char *filename) {
|
||||||
|
char *new_path = kmalloc(strlen(filename) + 1);
|
||||||
|
strcpy(new_path, filename);
|
||||||
|
vfs_t *vfs = ParsePath(new_path);
|
||||||
|
if (vfs == NULL) {
|
||||||
|
kfree(new_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vfs_file *result = vfs->FileInfo(vfs, new_path);
|
||||||
|
kfree(new_path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_change_disk(uint8_t drive) {
|
||||||
|
if (vfs_now != NULL) {
|
||||||
|
while (FindForCount(1, vfs_now->path) != NULL) {
|
||||||
|
kfree(FindForCount(vfs_now->path->ctl->all, vfs_now->path)->val);
|
||||||
|
DeleteVal(vfs_now->path->ctl->all, vfs_now->path);
|
||||||
|
}
|
||||||
|
kfree(vfs_now->cache);
|
||||||
|
DeleteList(vfs_now->path);
|
||||||
|
kfree(vfs_now);
|
||||||
|
}
|
||||||
|
vfs_t *f;
|
||||||
|
if (!(f = drive2fs(drive))) {
|
||||||
|
return false; // 没有mount
|
||||||
|
}
|
||||||
|
vfs_now = kmalloc(sizeof(vfs_t));
|
||||||
|
memcpy(vfs_now, f, sizeof(vfs_t));
|
||||||
|
f->CopyCache(vfs_now, f);
|
||||||
|
vfs_now->path = NewList();
|
||||||
|
vfs_now->cd(vfs_now, "/");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_vfs() {
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
vfsstl[i].flag = 0;
|
||||||
|
vfsstl[i].disk_number = 0;
|
||||||
|
vfsstl[i].drive = 0;
|
||||||
|
vfsMount_Stl[i].flag = 0;
|
||||||
|
vfsMount_Stl[i].disk_number = 0;
|
||||||
|
vfsMount_Stl[i].drive = 0;
|
||||||
|
// PDEBUG("Set vfsstl[%d] & vfsMount_Stl[%d] OK.", i, i);
|
||||||
|
}
|
||||||
|
vfs_now = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfs_register_fs(vfs_t vfs) {
|
||||||
|
printf("Register file system: %s\n", vfs.FSName);
|
||||||
|
vfs_t *seat;
|
||||||
|
seat = findSeat(vfsstl);
|
||||||
|
if (!seat) {
|
||||||
|
printf("can not find a seat of vfsstl(it's full)\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*seat = vfs;
|
||||||
|
return true;
|
||||||
|
}
|
@ -30,4 +30,13 @@ uint8_t read_cmos(uint8_t p);
|
|||||||
char *get_date_time();
|
char *get_date_time();
|
||||||
void print_cpu_id();
|
void print_cpu_id();
|
||||||
|
|
||||||
|
uint32_t get_hour();
|
||||||
|
uint32_t get_min();
|
||||||
|
uint32_t get_sec();
|
||||||
|
uint32_t get_day_of_month();
|
||||||
|
uint32_t get_day_of_week();
|
||||||
|
uint32_t get_mon();
|
||||||
|
uint32_t get_year();
|
||||||
|
int is_leap_year(int year);
|
||||||
|
|
||||||
#endif //CRASHPOWEROS_CMOS_H
|
#endif //CRASHPOWEROS_CMOS_H
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
#define LONG_MAX 9223372036854775807L
|
#define LONG_MAX 9223372036854775807L
|
||||||
#define LONG_MIN -9223372036854775808L
|
#define LONG_MIN -9223372036854775808L
|
||||||
|
|
||||||
|
#define UINT32_MAX 0xffffffff
|
||||||
|
#define INT32_MAX 0x7fffffff
|
||||||
|
|
||||||
#define swap32(x) \
|
#define swap32(x) \
|
||||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||||
@ -17,7 +20,16 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
typedef int bool;
|
typedef int bool;
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#define EOF -1
|
||||||
|
|
||||||
|
unsigned int rand(void);
|
||||||
|
void srand(unsigned long seed);
|
||||||
|
void insert_char(char* str, int pos, char ch);
|
||||||
|
void delete_char(char* str, int pos);
|
||||||
|
void strtoupper(char* str);
|
||||||
|
int strncmp(const char* s1, const char* s2, size_t n);
|
||||||
void assert(int b,char* message);
|
void assert(int b,char* message);
|
||||||
size_t strlen(const char* str);
|
size_t strlen(const char* str);
|
||||||
int strcmp(const char *s1, const char *s2);
|
int strcmp(const char *s1, const char *s2);
|
||||||
|
12
include/dma.h
Normal file
12
include/dma.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef CRASHPOWEROS_DMA_H
|
||||||
|
#define CRASHPOWEROS_DMA_H
|
||||||
|
|
||||||
|
#define LOW_BYTE(x) (x & 0x00FF)
|
||||||
|
#define HI_BYTE(x) ((x & 0xFF00) >> 8)
|
||||||
|
|
||||||
|
void _dma_xfer(unsigned char DMA_channel, unsigned char page,
|
||||||
|
unsigned int offset, unsigned int length, unsigned char mode);
|
||||||
|
void dma_xfer(unsigned char channel, unsigned long address, unsigned int length,
|
||||||
|
unsigned char read);
|
||||||
|
|
||||||
|
#endif
|
122
include/fat.h
122
include/fat.h
@ -1,7 +1,47 @@
|
|||||||
#ifndef CRASHPOWEROS_FAT_H
|
#ifndef CRASHPOWEROS_FAT_H
|
||||||
#define CRASHPOWEROS_FAT_H
|
#define CRASHPOWEROS_FAT_H
|
||||||
|
|
||||||
|
#define BS_jmpBoot 0
|
||||||
|
#define BS_OEMName 3
|
||||||
|
#define BPB_BytsPerSec 11
|
||||||
|
#define BPB_SecPerClus 13
|
||||||
|
#define BPB_RsvdSecCnt 14
|
||||||
|
#define BPB_NumFATs 16
|
||||||
|
#define BPB_RootEntCnt 17
|
||||||
|
#define BPB_TotSec16 19
|
||||||
|
#define BPB_Media 21
|
||||||
|
#define BPB_FATSz16 22
|
||||||
|
#define BPB_SecPerTrk 24
|
||||||
|
#define BPB_NumHeads 26
|
||||||
|
#define BPB_HiddSec 28
|
||||||
|
#define BPB_TotSec32 32
|
||||||
|
#define BPB_FATSz32 36
|
||||||
|
#define BPB_ExtFlags 40
|
||||||
|
#define BPB_FSVer 42
|
||||||
|
#define BPB_RootClus 44
|
||||||
|
#define BPB_FSInfo 48
|
||||||
|
#define BPB_BkBootSec 50
|
||||||
|
#define BPB_Reserved 52
|
||||||
|
#define BPB_Fat32ExtByts 28
|
||||||
|
#define BS_DrvNum 36
|
||||||
|
#define BS_Reserved1 37
|
||||||
|
#define BS_BootSig 38
|
||||||
|
#define BS_VolD 39
|
||||||
|
#define BS_VolLab 43
|
||||||
|
#define BS_FileSysType 54
|
||||||
|
#define EOF -1
|
||||||
|
#define SEEK_SET 0
|
||||||
|
#define SEEK_CUR 1
|
||||||
|
#define SEEK_END 2
|
||||||
|
|
||||||
|
#define get_dm(vfs) ((fat_cache *)(vfs->cache))->dm
|
||||||
|
#define get_now_dir(vfs) ((fat_cache *)(vfs->cache))->dir
|
||||||
|
#define get_clustno(high, low) (high << 16) | (low & 0xffff)
|
||||||
|
#define clustno_end(type) 0xfffffff & ((((1 << (type - 1)) - 1) << 1) + 1)
|
||||||
|
#define rmfarptr2ptr(x) ((x).seg * 0x10 + (x).offset)
|
||||||
|
|
||||||
#include "../include/common.h"
|
#include "../include/common.h"
|
||||||
|
#include "vfs.h"
|
||||||
|
|
||||||
struct FAT_CACHE {
|
struct FAT_CACHE {
|
||||||
unsigned int ADR_DISKIMG;
|
unsigned int ADR_DISKIMG;
|
||||||
@ -21,16 +61,12 @@ struct FAT_CACHE {
|
|||||||
unsigned char *FatClustnoFlags;
|
unsigned char *FatClustnoFlags;
|
||||||
int type;
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct FAT_CACHE dm;
|
struct FAT_CACHE dm;
|
||||||
struct FAT_FILEINFO *dir;
|
struct FAT_FILEINFO *dir;
|
||||||
} fat_cache;
|
} fat_cache;
|
||||||
|
|
||||||
#define get_dm(vfs) ((fat_cache *)(vfs->cache))->dm
|
|
||||||
#define get_now_dir(vfs) ((fat_cache *)(vfs->cache))->dir
|
|
||||||
#define get_clustno(high, low) (high << 16) | (low & 0xffff)
|
|
||||||
#define clustno_end(type) 0xfffffff & ((((1 << (type - 1)) - 1) << 1) + 1)
|
|
||||||
|
|
||||||
struct FAT_FILEINFO {
|
struct FAT_FILEINFO {
|
||||||
unsigned char name[8], ext[3], type;
|
unsigned char name[8], ext[3], type;
|
||||||
char reserve;
|
char reserve;
|
||||||
@ -40,54 +76,40 @@ struct FAT_FILEINFO {
|
|||||||
unsigned int size;
|
unsigned int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct FILE {
|
|
||||||
unsigned int mode;
|
|
||||||
unsigned int fileSize;
|
|
||||||
unsigned char *buffer;
|
|
||||||
unsigned int bufferSize;
|
|
||||||
unsigned int p;
|
|
||||||
char *name;
|
|
||||||
} FILE;
|
|
||||||
|
|
||||||
typedef enum { FLE, DIR, RDO, HID, SYS } ftype;
|
|
||||||
typedef struct {
|
|
||||||
char name[255];
|
|
||||||
ftype type;
|
|
||||||
unsigned int size;
|
|
||||||
unsigned short year, month, day;
|
|
||||||
unsigned short hour, minute;
|
|
||||||
} vfs_file;
|
|
||||||
|
|
||||||
typedef struct vfs_t {
|
|
||||||
struct List *path;
|
|
||||||
void *cache;
|
|
||||||
char FSName[255];
|
|
||||||
int disk_number;
|
|
||||||
uint8_t drive; // 大写(必须)
|
|
||||||
vfs_file *(*FileInfo)(struct vfs_t *vfs, char *filename);
|
|
||||||
struct List *(*ListFile)(struct vfs_t *vfs, char *dictpath);
|
|
||||||
bool (*ReadFile)(struct vfs_t *vfs, char *path, char *buffer);
|
|
||||||
bool (*WriteFile)(struct vfs_t *vfs, char *path, char *buffer, int size);
|
|
||||||
bool (*DelFile)(struct vfs_t *vfs, char *path);
|
|
||||||
bool (*DelDict)(struct vfs_t *vfs, char *path);
|
|
||||||
bool (*CreateFile)(struct vfs_t *vfs, char *filename);
|
|
||||||
bool (*CreateDict)(struct vfs_t *vfs, char *filename);
|
|
||||||
bool (*RenameFile)(struct vfs_t *vfs, char *filename, char *filename_of_new);
|
|
||||||
bool (*Attrib)(struct vfs_t *vfs, char *filename, ftype type);
|
|
||||||
bool (*Format)(uint8_t disk_number);
|
|
||||||
void (*InitFs)(struct vfs_t *vfs, uint8_t disk_number);
|
|
||||||
void (*DeleteFs)(struct vfs_t *vfs);
|
|
||||||
bool (*Check)(uint8_t disk_number);
|
|
||||||
bool (*cd)(struct vfs_t *vfs, char *dictName);
|
|
||||||
int (*FileSize)(struct vfs_t *vfs, char *filename);
|
|
||||||
void (*CopyCache)(struct vfs_t *dest, struct vfs_t *src);
|
|
||||||
int flag;
|
|
||||||
} vfs_t;
|
|
||||||
/*
|
|
||||||
void read_fat(unsigned char *img, int *fat, unsigned char *ff, int max,int type);
|
void read_fat(unsigned char *img, int *fat, unsigned char *ff, int max,int type);
|
||||||
int get_directory_max(struct FAT_FILEINFO *directory, vfs_t *vfs);
|
int get_directory_max(struct FAT_FILEINFO *directory, vfs_t *vfs);
|
||||||
void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs);
|
void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs);
|
||||||
|
void file_savefile(int clustno, int size, char *buf, int *fat,
|
||||||
|
unsigned char *ff, vfs_t *vfs);
|
||||||
|
void file_saveinfo(struct FAT_FILEINFO *directory, vfs_t *vfs);
|
||||||
void file_savefat(int *fat, int clustno, int length, vfs_t *vfs);
|
void file_savefat(int *fat, int clustno, int length, vfs_t *vfs);
|
||||||
*/
|
int mkfile(char *name, vfs_t *vfs);
|
||||||
|
int del(char *cmdline, vfs_t *vfs);
|
||||||
|
int deldir(char *path, vfs_t *vfs);
|
||||||
|
int format(char drive);
|
||||||
|
int attrib(char *filename, ftype type, struct vfs_t *vfs);
|
||||||
|
void Register_fat_fileSys();
|
||||||
|
struct FAT_FILEINFO *Get_dictaddr(char *path1, vfs_t *vfs);
|
||||||
|
void Fat_CopyCache(struct vfs_t *dest, struct vfs_t *src);
|
||||||
|
bool Fat_cd(struct vfs_t *vfs, char *dictName);
|
||||||
|
bool Fat_ReadFile(struct vfs_t *vfs, char *path, char *buffer);
|
||||||
|
bool Fat_WriteFile(struct vfs_t *vfs, char *path, char *buffer, int size);
|
||||||
|
List *Fat_ListFile(struct vfs_t *vfs, char *dictpath);
|
||||||
|
bool Fat_RenameFile(struct vfs_t *vfs, char *filename, char *filename_of_new);
|
||||||
|
bool Fat_CreateFile(struct vfs_t *vfs, char *filename);
|
||||||
|
bool Fat_DelFile(struct vfs_t *vfs, char *path);
|
||||||
|
bool Fat_DelDict(struct vfs_t *vfs, char *path);
|
||||||
|
void Fat_DeleteFs(struct vfs_t *vfs);
|
||||||
|
bool Fat_Check(uint8_t disk_number);
|
||||||
|
int Fat_FileSize(struct vfs_t *vfs, char *filename);
|
||||||
|
bool Fat_Format(uint8_t disk_number);
|
||||||
|
bool Fat_CreateDict(struct vfs_t *vfs, char *filename);
|
||||||
|
bool Fat_Attrib(struct vfs_t *vfs, char *filename, ftype type);
|
||||||
|
vfs_file *Fat_FileInfo(struct vfs_t *vfs, char *filename);
|
||||||
|
void fat_InitFS(struct vfs_t *vfs, uint8_t disk_number);
|
||||||
|
int get_directory_max(struct FAT_FILEINFO *directory, vfs_t *vfs);
|
||||||
|
int mkdir(char *dictname, int last_clust, vfs_t *vfs);
|
||||||
|
int rename(char *src_name, char *dst_name, vfs_t *vfs);
|
||||||
|
int changedict(char *dictname, vfs_t *vfs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
33
include/file.h
Normal file
33
include/file.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef CRASHPOWEROS_FILE_H
|
||||||
|
#define CRASHPOWEROS_FILE_H
|
||||||
|
|
||||||
|
#define READ 0x2
|
||||||
|
#define WRITE 0x4
|
||||||
|
#define APPEND 0x8
|
||||||
|
#define BIN 0x0
|
||||||
|
#define PLUS 0x10
|
||||||
|
#define CANREAD(flag) ((flag)&READ || (flag)&PLUS)
|
||||||
|
#define CANWRITE(flag) ((flag)&WRITE || (flag)&PLUS || (flag)&APPEND)
|
||||||
|
|
||||||
|
#include "../include/vfs.h"
|
||||||
|
|
||||||
|
int fseek(FILE *fp, int offset, int whence);
|
||||||
|
long ftell(FILE *stream);
|
||||||
|
FILE *fopen(char *filename, char *mode);
|
||||||
|
int fgetc(FILE *stream);
|
||||||
|
int fputc(int ch, FILE *stream);
|
||||||
|
unsigned int fwrite(const void *ptr, unsigned int size, unsigned int nmemb,
|
||||||
|
FILE *stream);
|
||||||
|
unsigned int fread(void *buffer, unsigned int size, unsigned int count,
|
||||||
|
FILE *stream);
|
||||||
|
int fclose(FILE *fp);
|
||||||
|
char *fgets(char *str, int n, FILE *stream);
|
||||||
|
int fputs(const char *str, FILE *stream);
|
||||||
|
int fprintf(FILE *stream, const char *format, ...);
|
||||||
|
int feof(FILE *stream);
|
||||||
|
int ferror(FILE *stream);
|
||||||
|
int fsz(char *filename);
|
||||||
|
void EDIT_FILE(char *name, char *dest, int length, int offset);
|
||||||
|
int Copy(char *path, char *path1);
|
||||||
|
|
||||||
|
#endif
|
71
include/floppy.h
Normal file
71
include/floppy.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef CRASHPOWEROS_FLOPPY_H
|
||||||
|
#define CRASHPOWEROS_FLOPPY_H
|
||||||
|
|
||||||
|
#define DG144_HEADS 2 /* 每个磁道中的磁头数 (1.44M) */
|
||||||
|
#define DG144_TRACKS 80 /* 每个驱动器的磁道数 (1.44M) */
|
||||||
|
#define DG144_SPT 18 /* 每个磁头中的的扇区数 (1.44M) */
|
||||||
|
#define DG144_GAP3FMT 0x54 /* GAP3格式化 (1.44M) */
|
||||||
|
#define DG144_GAP3RW 0x1b /* GAP3(读/写) (1.44M) */
|
||||||
|
|
||||||
|
#define DG168_HEADS 2 /* 每个磁道中的磁头数 (1.68M) */
|
||||||
|
#define DG168_TRACKS 80 /* 每个驱动器的磁道数 (1.68M) */
|
||||||
|
#define DG168_SPT 21 /* 每个磁头中的的扇区数 (1.68M) */
|
||||||
|
#define DG168_GAP3FMT 0x0c /* GAP3格式化 (1.68M) */
|
||||||
|
#define DG168_GAP3RW 0x1c /* GAP3(读/写) (1.68M) */
|
||||||
|
|
||||||
|
/* i/o端口定义 */
|
||||||
|
#define FDC_DOR (0x3f2) /* 数字输出寄存器 */
|
||||||
|
#define FDC_MSR (0x3f4) /* 主要状态寄存器(输入) */
|
||||||
|
#define FDC_DRS (0x3f4) /* DRS寄存器 */
|
||||||
|
#define FDC_DATA (0x3f5) /* 数据寄存器 */
|
||||||
|
#define FDC_DIR (0x3f7) /* 数字输入寄存器(输入) */
|
||||||
|
#define FDC_CCR (0x3f7) /* CCR寄存器 */
|
||||||
|
|
||||||
|
/* 软盘命令 */
|
||||||
|
#define CMD_SPECIFY (0x03) /* 指定驱动器计时 */
|
||||||
|
#define CMD_WRITE (0xc5) /* 写(写入数据的最小单位是扇区) */
|
||||||
|
#define CMD_READ (0xe6) /* 读(读取扇区的最小单位是扇区) */
|
||||||
|
#define CMD_RECAL (0x07) /* 重新校准软盘 */
|
||||||
|
#define CMD_SENSEI (0x08) /* 中断状态 */
|
||||||
|
#define CMD_FORMAT (0x4d) /* 格式化磁道 */
|
||||||
|
#define CMD_SEEK (0x0f) /* 寻找磁道 */
|
||||||
|
#define CMD_VERSION (0x10) /* 获取软盘驱动器的版本 */
|
||||||
|
#define SECTORS_ONCE 4
|
||||||
|
|
||||||
|
#include "isr.h"
|
||||||
|
|
||||||
|
typedef struct DrvGeom {
|
||||||
|
unsigned char heads;
|
||||||
|
unsigned char tracks;
|
||||||
|
unsigned char spt; /* 每轨扇区数 */
|
||||||
|
} DrvGeom;
|
||||||
|
|
||||||
|
int getbyte();
|
||||||
|
void sendbyte(int byte);
|
||||||
|
void motoron(void);
|
||||||
|
void motoroff(void);
|
||||||
|
void recalibrate(void);
|
||||||
|
void init_floppy();
|
||||||
|
void hts2block(int track, int head, int sector, int* block);
|
||||||
|
void block2hts(int block, int* track, int* head, int* sector);
|
||||||
|
int seek(int track);
|
||||||
|
void wait_floppy_interrupt();
|
||||||
|
void reset(void);
|
||||||
|
int fdc_rw(int block,
|
||||||
|
unsigned char* blockbuff,
|
||||||
|
int read,
|
||||||
|
unsigned long nosectors);
|
||||||
|
void flint(registers_t *reg);
|
||||||
|
int write_floppy_for_ths(int track,
|
||||||
|
int head,
|
||||||
|
int sec,
|
||||||
|
unsigned char* blockbuff,
|
||||||
|
unsigned long nosec);
|
||||||
|
int fdc_rw_ths(int track,
|
||||||
|
int head,
|
||||||
|
int sector,
|
||||||
|
unsigned char* blockbuff,
|
||||||
|
int read,
|
||||||
|
unsigned long nosectors);
|
||||||
|
|
||||||
|
#endif
|
@ -20,5 +20,10 @@ typedef struct List List;
|
|||||||
|
|
||||||
struct List* FindForCount(size_t count, struct List* Obj);
|
struct List* FindForCount(size_t count, struct List* Obj);
|
||||||
int GetLastCount(struct List* Obj);
|
int GetLastCount(struct List* Obj);
|
||||||
|
void DeleteList(struct List* Obj);
|
||||||
|
struct List* NewList();
|
||||||
|
void Change(size_t count, struct List* Obj, uintptr_t val);
|
||||||
|
void DeleteVal(size_t count, struct List* Obj);
|
||||||
|
void AddVal(uintptr_t val, struct List* Obj);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,4 +85,6 @@ void init_page();
|
|||||||
|
|
||||||
void memclean(char *s, int len);
|
void memclean(char *s, int len);
|
||||||
|
|
||||||
|
void *realloc(void *ptr, uint32_t size);
|
||||||
|
|
||||||
#endif //CRASHPOWEROS_MEMORY_H
|
#endif //CRASHPOWEROS_MEMORY_H
|
||||||
|
@ -1,10 +1,34 @@
|
|||||||
#ifndef CRASHPOWEROS_TIMER_H
|
#ifndef CRASHPOWEROS_TIMER_H
|
||||||
#define CRASHPOWEROS_TIMER_H
|
#define CRASHPOWEROS_TIMER_H
|
||||||
|
|
||||||
|
#define MAX_TIMER 500
|
||||||
|
#define TIMER_FLAGS_ALLOC 1 /* 已配置状态 */
|
||||||
|
#define TIMER_FLAGS_USING 2 /* 定时器运行中 */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
struct TIMER {
|
||||||
|
struct TIMER *next;
|
||||||
|
unsigned int timeout, flags;
|
||||||
|
struct FIFO8 *fifo;
|
||||||
|
unsigned char data;
|
||||||
|
struct task_struct *waiter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TIMERCTL {
|
||||||
|
unsigned int count, next;
|
||||||
|
struct TIMER *t0;
|
||||||
|
struct TIMER timers0[MAX_TIMER];
|
||||||
|
};
|
||||||
|
|
||||||
void init_timer(uint32_t timer);
|
void init_timer(uint32_t timer);
|
||||||
|
void timer_free(struct TIMER *timer);
|
||||||
|
void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data);
|
||||||
|
void timer_settime(struct TIMER *timer, unsigned int timeout);
|
||||||
void clock_sleep(uint32_t timer);
|
void clock_sleep(uint32_t timer);
|
||||||
|
struct TIMER *timer_alloc(void);
|
||||||
|
unsigned int time(void);
|
||||||
|
void init_pit(void);
|
||||||
|
|
||||||
#endif //CRASHPOWEROS_TIMER_H
|
#endif //CRASHPOWEROS_TIMER_H
|
||||||
|
71
include/vfs.h
Normal file
71
include/vfs.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef CRASHPOWEROS_VFS_H
|
||||||
|
#define CRASHPOWEROS_VFS_H
|
||||||
|
|
||||||
|
#define toupper(c) ((c) >= 'a' && (c) <= 'z' ? c - 32 : c)
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
typedef struct FILE {
|
||||||
|
unsigned int mode;
|
||||||
|
unsigned int fileSize;
|
||||||
|
unsigned char *buffer;
|
||||||
|
unsigned int bufferSize;
|
||||||
|
unsigned int p;
|
||||||
|
char *name;
|
||||||
|
} FILE;
|
||||||
|
|
||||||
|
typedef enum { FLE, DIR, RDO, HID, SYS } ftype;
|
||||||
|
typedef struct {
|
||||||
|
char name[255];
|
||||||
|
ftype type;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned short year, month, day;
|
||||||
|
unsigned short hour, minute;
|
||||||
|
} vfs_file;
|
||||||
|
|
||||||
|
typedef struct vfs_t {
|
||||||
|
struct List *path;
|
||||||
|
void *cache;
|
||||||
|
char FSName[255];
|
||||||
|
int disk_number;
|
||||||
|
uint8_t drive; // 大写(必须)
|
||||||
|
vfs_file *(*FileInfo)(struct vfs_t *vfs, char *filename);
|
||||||
|
struct List *(*ListFile)(struct vfs_t *vfs, char *dictpath);
|
||||||
|
bool (*ReadFile)(struct vfs_t *vfs, char *path, char *buffer);
|
||||||
|
bool (*WriteFile)(struct vfs_t *vfs, char *path, char *buffer, int size);
|
||||||
|
bool (*DelFile)(struct vfs_t *vfs, char *path);
|
||||||
|
bool (*DelDict)(struct vfs_t *vfs, char *path);
|
||||||
|
bool (*CreateFile)(struct vfs_t *vfs, char *filename);
|
||||||
|
bool (*CreateDict)(struct vfs_t *vfs, char *filename);
|
||||||
|
bool (*RenameFile)(struct vfs_t *vfs, char *filename, char *filename_of_new);
|
||||||
|
bool (*Attrib)(struct vfs_t *vfs, char *filename, ftype type);
|
||||||
|
bool (*Format)(uint8_t disk_number);
|
||||||
|
void (*InitFs)(struct vfs_t *vfs, uint8_t disk_number);
|
||||||
|
void (*DeleteFs)(struct vfs_t *vfs);
|
||||||
|
bool (*Check)(uint8_t disk_number);
|
||||||
|
bool (*cd)(struct vfs_t *vfs, char *dictName);
|
||||||
|
int (*FileSize)(struct vfs_t *vfs, char *filename);
|
||||||
|
void (*CopyCache)(struct vfs_t *dest, struct vfs_t *src);
|
||||||
|
int flag;
|
||||||
|
} vfs_t;
|
||||||
|
|
||||||
|
bool vfs_mount_disk(uint8_t disk_number, uint8_t drive);
|
||||||
|
bool vfs_unmount_disk(uint8_t drive);
|
||||||
|
bool vfs_readfile(char *path, char *buffer);
|
||||||
|
bool vfs_writefile(char *path, char *buffer, int size);
|
||||||
|
uint32_t vfs_filesize(char *filename);
|
||||||
|
List *vfs_listfile(char *dictpath);
|
||||||
|
bool vfs_delfile(char *filename);
|
||||||
|
bool vfs_deldir(char *dictname);
|
||||||
|
bool vfs_createfile(char *filename);
|
||||||
|
bool vfs_createdict(char *filename);
|
||||||
|
bool vfs_renamefile(char *filename, char *filename_of_new);
|
||||||
|
bool vfs_attrib(char *filename, ftype type);
|
||||||
|
bool vfs_format(uint8_t disk_number, char *FSName);
|
||||||
|
vfs_file *vfs_fileinfo(char *filename);
|
||||||
|
bool vfs_change_disk(uint8_t drive);
|
||||||
|
bool vfs_register_fs(vfs_t vfs);
|
||||||
|
void init_vfs();
|
||||||
|
|
||||||
|
#endif
|
380
kernel/fat.c
380
kernel/fat.c
@ -1,380 +0,0 @@
|
|||||||
/*
|
|
||||||
* PlantsOS fat FileSystem
|
|
||||||
* Copyright by min0911
|
|
||||||
*/
|
|
||||||
#include "../include/vdisk.h"
|
|
||||||
#include "../include/fat.h"
|
|
||||||
#include "../include/memory.h"
|
|
||||||
#include "../include/list.h"
|
|
||||||
#include "../include/common.h"
|
|
||||||
/*
|
|
||||||
static inline int get_fat_date(unsigned short year, unsigned short month,
|
|
||||||
unsigned short day) {
|
|
||||||
year -= 1980;
|
|
||||||
unsigned short date = 0;
|
|
||||||
date |= (year & 0x7f) << 9;
|
|
||||||
date |= (month & 0x0f) << 5;
|
|
||||||
date |= (day & 0x1f);
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
static inline int get_fat_time(unsigned short hour, unsigned short minute) {
|
|
||||||
unsigned short time = 0;
|
|
||||||
time |= (hour & 0x1f) << 11;
|
|
||||||
time |= (minute & 0x3f) << 5;
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_fat(unsigned char *img, int *fat, unsigned char *ff, int max,
|
|
||||||
int type) {
|
|
||||||
if (type == 12) {
|
|
||||||
for (int i = 0, j = 0; i < max; i += 2) {
|
|
||||||
fat[i + 0] = (img[j + 0] | img[j + 1] << 8) & 0xfff;
|
|
||||||
fat[i + 1] = (img[j + 1] >> 4 | img[j + 2] << 4) & 0xfff;
|
|
||||||
j += 3;
|
|
||||||
}
|
|
||||||
// 保留簇
|
|
||||||
ff[0] = 1;
|
|
||||||
ff[1] = 1;
|
|
||||||
for (int i = 1; i < max; i++) {
|
|
||||||
if (fat[i] > 0 && fat[i] < 0xff0) {
|
|
||||||
ff[fat[i]] = 1;
|
|
||||||
} else if (fat[i] >= 0xff0 && fat[i] <= 0xfff) {
|
|
||||||
ff[i + 1] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type == 16) {
|
|
||||||
unsigned short *p = (unsigned short *)img;
|
|
||||||
for (int i = 0; i != max; i++) {
|
|
||||||
fat[i] = p[i];
|
|
||||||
}
|
|
||||||
ff[0] = 1;
|
|
||||||
ff[1] = 1;
|
|
||||||
for (int i = 1; i < max; i++) {
|
|
||||||
if (fat[i] > 0 && fat[i] < 0xfff0) {
|
|
||||||
ff[fat[i]] = 1;
|
|
||||||
} else if (fat[i] >= 0xfff0 && fat[i] <= 0xffff) {
|
|
||||||
ff[i + 1] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type == 32) {
|
|
||||||
unsigned int *p = (unsigned int *)img;
|
|
||||||
for (int i = 0; i != max; i++) {
|
|
||||||
fat[i] = p[i];
|
|
||||||
}
|
|
||||||
ff[0] = 1;
|
|
||||||
ff[1] = 1;
|
|
||||||
for (int i = 1; i < max; i++) {
|
|
||||||
if (fat[i] > 0 && fat[i] < 0xffffff0) {
|
|
||||||
ff[fat[i]] = 1;
|
|
||||||
} else if (fat[i] >= 0xffffff0 && fat[i] <= 0xfffffff) {
|
|
||||||
ff[i + 1] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_directory_max(struct FAT_FILEINFO *directory, vfs_t *vfs) {
|
|
||||||
if (directory == get_dm(vfs).root_directory) {
|
|
||||||
return get_dm(vfs).RootMaxFiles;
|
|
||||||
}
|
|
||||||
for (int i = 1; FindForCount(i, get_dm(vfs).directory_list) != NULL; i++) {
|
|
||||||
struct List *l = FindForCount(i, get_dm(vfs).directory_list);
|
|
||||||
if ((struct FAT_FILEINFO *)l->val == directory) {
|
|
||||||
return (int)FindForCount(i, get_dm(vfs).directory_max_list)->val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs) {
|
|
||||||
if (!size) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void *img = kmalloc(((size - 1) / get_dm(vfs).ClustnoBytes + 1) *
|
|
||||||
get_dm(vfs).ClustnoBytes);
|
|
||||||
for (int i = 0; i != (size - 1) / get_dm(vfs).ClustnoBytes + 1; i++) {
|
|
||||||
uint32_t sec = (get_dm(vfs).FileDataAddress +
|
|
||||||
(clustno - 2) * get_dm(vfs).ClustnoBytes) /
|
|
||||||
get_dm(vfs).SectorBytes;
|
|
||||||
Disk_Read(sec, get_dm(vfs).ClustnoBytes / get_dm(vfs).SectorBytes,
|
|
||||||
img + i * get_dm(vfs).ClustnoBytes, vfs->disk_number);
|
|
||||||
clustno = fat[clustno];
|
|
||||||
}
|
|
||||||
memcpy((void *)buf, img, size);
|
|
||||||
kfree(img, ((size - 1) / get_dm(vfs).SectorBytes + 1) *
|
|
||||||
get_dm(vfs).SectorBytes);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void file_savefile(int clustno, int size, char *buf, int *fat,
|
|
||||||
unsigned char *ff, vfs_t *vfs) {
|
|
||||||
uint32_t clustall = 0;
|
|
||||||
int tmp = clustno;
|
|
||||||
int end = clustno_end(get_dm(vfs).type);
|
|
||||||
while (fat[clustno] != end) { // 计算文件占多少Fat项 Fat项 = 大小 / 簇大小 + 1
|
|
||||||
clustno = fat[clustno];
|
|
||||||
clustall++;
|
|
||||||
}
|
|
||||||
int old_clustno = clustno;
|
|
||||||
clustno = tmp;
|
|
||||||
int alloc_size;
|
|
||||||
if (size >
|
|
||||||
(clustall + 1) *
|
|
||||||
get_dm(vfs).ClustnoBytes) { // 新大小 > (旧大小 / 簇大小 + 1) * 簇大小
|
|
||||||
// 请求内存大小 = (新大小 / 簇大小 + 1) * 簇大小
|
|
||||||
alloc_size =
|
|
||||||
((size - 1) / get_dm(vfs).ClustnoBytes + 1) * get_dm(vfs).ClustnoBytes;
|
|
||||||
// 分配Fat(这里需要在写盘前分配)
|
|
||||||
for (int size1 = size; size1 > ((clustall + 1) * get_dm(vfs).ClustnoBytes);
|
|
||||||
size1 -= get_dm(vfs).ClustnoBytes) {
|
|
||||||
for (int i = 0; i != get_dm(vfs).FatMaxTerms; i++) {
|
|
||||||
if (!ff[i]) {
|
|
||||||
fat[old_clustno] = i;
|
|
||||||
old_clustno = i;
|
|
||||||
ff[i] = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fat[old_clustno] = end; // 结尾Fat
|
|
||||||
ff[old_clustno] = true;
|
|
||||||
} else if (size <=
|
|
||||||
(clustall + 1) *
|
|
||||||
get_dm(vfs).ClustnoBytes) { // 新大小 <= (旧大小 / 簇大小
|
|
||||||
// + 1) * 簇大小
|
|
||||||
// 请求内存大小 = (旧大小 / 簇大小 + 1) * 簇大小
|
|
||||||
alloc_size = (clustall + 1) * get_dm(vfs).ClustnoBytes;
|
|
||||||
// 这里不分配Fat的原因是要清空更改后多余的数据
|
|
||||||
}
|
|
||||||
void *img = kmalloc(alloc_size);
|
|
||||||
clean((char *)img, alloc_size);
|
|
||||||
memcpy(img, buf, size); // 把要写入的数据复制到新请求的内存地址
|
|
||||||
for (int i = 0; i != (alloc_size / get_dm(vfs).ClustnoBytes); i++) {
|
|
||||||
uint32_t sec = (get_dm(vfs).FileDataAddress +
|
|
||||||
(clustno - 2) * get_dm(vfs).ClustnoBytes) /
|
|
||||||
get_dm(vfs).SectorBytes;
|
|
||||||
Disk_Write(sec, get_dm(vfs).ClustnoBytes / get_dm(vfs).SectorBytes,
|
|
||||||
img + i * get_dm(vfs).ClustnoBytes, vfs->disk_number);
|
|
||||||
clustno = fat[clustno];
|
|
||||||
}
|
|
||||||
kfree(img, alloc_size);
|
|
||||||
if (size <
|
|
||||||
clustall *
|
|
||||||
get_dm(vfs).ClustnoBytes) { // 新大小 < (旧大小 / 簇大小) * 簇大小
|
|
||||||
// 分配Fat(中间情况没必要分配)
|
|
||||||
int i = old_clustno;
|
|
||||||
for (int size1 = clustall * get_dm(vfs).ClustnoBytes; size1 > size;
|
|
||||||
size1 -= get_dm(vfs).ClustnoBytes) {
|
|
||||||
fat[i] = 0;
|
|
||||||
ff[i] = 0;
|
|
||||||
for (int j = 0; j != get_dm(vfs).FatMaxTerms; j++) {
|
|
||||||
if (fat[j] == i) {
|
|
||||||
i = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
old_clustno = i;
|
|
||||||
fat[old_clustno] = end;
|
|
||||||
ff[old_clustno] = 1;
|
|
||||||
}
|
|
||||||
file_savefat(fat, 0, get_dm(vfs).FatMaxTerms, vfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void file_savefat(int *fat, int clustno, int length, vfs_t *vfs) {
|
|
||||||
unsigned char *img = get_dm(vfs).ADR_DISKIMG + get_dm(vfs).Fat1Address;
|
|
||||||
int size, sec;
|
|
||||||
if (get_dm(vfs).type == 12) {
|
|
||||||
for (int i = 0; i <= length; i++) {
|
|
||||||
if ((clustno + i) % 2 == 0) {
|
|
||||||
img[(clustno + i) * 3 / 2 + 0] = fat[clustno + i] & 0xff;
|
|
||||||
img[(clustno + i) * 3 / 2 + 1] =
|
|
||||||
(fat[clustno + i] >> 8 | (img[(clustno + i) * 3 / 2 + 1] & 0xf0)) &
|
|
||||||
0xff;
|
|
||||||
} else if ((clustno + i) % 2 != 0) {
|
|
||||||
img[(clustno + i - 1) * 3 / 2 + 1] =
|
|
||||||
((img[(clustno + i - 1) * 3 / 2 + 1] & 0x0f) | fat[clustno + i]
|
|
||||||
<< 4) &
|
|
||||||
0xff;
|
|
||||||
img[(clustno + i - 1) * 3 / 2 + 2] = (fat[clustno + i] >> 4) & 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
size = length * 3 / 2 - 1;
|
|
||||||
sec = clustno * 3 / 2;
|
|
||||||
} else if (get_dm(vfs).type == 16) {
|
|
||||||
for (int i = 0; i <= length; i++) {
|
|
||||||
img[(clustno + i) * 2 + 0] = fat[clustno + i] & 0xff;
|
|
||||||
img[(clustno + i) * 2 + 1] = (fat[clustno + i] >> 8) & 0xff;
|
|
||||||
}
|
|
||||||
size = length * 2 - 1;
|
|
||||||
sec = clustno * 2;
|
|
||||||
} else if (get_dm(vfs).type == 32) {
|
|
||||||
for (int i = 0; i <= length; i++) {
|
|
||||||
img[(clustno + i) * 4 + 0] = fat[clustno + i] & 0xff;
|
|
||||||
img[(clustno + i) * 4 + 1] = (fat[clustno + i] >> 8) & 0xff;
|
|
||||||
img[(clustno + i) * 4 + 2] = (fat[clustno + i] >> 16) & 0xff;
|
|
||||||
img[(clustno + i) * 4 + 3] = fat[clustno + i] >> 24;
|
|
||||||
}
|
|
||||||
size = length * 4 - 1;
|
|
||||||
sec = clustno * 4;
|
|
||||||
}
|
|
||||||
Disk_Write((get_dm(vfs).Fat1Address + sec) / get_dm(vfs).SectorBytes,
|
|
||||||
size / get_dm(vfs).SectorBytes + 1,
|
|
||||||
get_dm(vfs).ADR_DISKIMG + get_dm(vfs).Fat1Address,
|
|
||||||
vfs->disk_number);
|
|
||||||
Disk_Write((get_dm(vfs).Fat2Address + sec) / get_dm(vfs).SectorBytes,
|
|
||||||
size / get_dm(vfs).SectorBytes + 1,
|
|
||||||
get_dm(vfs).ADR_DISKIMG + get_dm(vfs).Fat2Address,
|
|
||||||
vfs->disk_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FAT_FILEINFO *file_search(char *name, struct FAT_FILEINFO *finfo,
|
|
||||||
int max) {
|
|
||||||
int i, j;
|
|
||||||
char s[12];
|
|
||||||
for (j = 0; j < 11; j++) {
|
|
||||||
s[j] = ' ';
|
|
||||||
}
|
|
||||||
j = 0;
|
|
||||||
for (i = 0; name[i] != 0; i++) {
|
|
||||||
if (j >= 11) {
|
|
||||||
return 0; //没有找到
|
|
||||||
}
|
|
||||||
if (name[i] == '.' && j <= 8) {
|
|
||||||
j = 8;
|
|
||||||
} else {
|
|
||||||
s[j] = name[i];
|
|
||||||
if ('a' <= s[j] && s[j] <= 'z') {
|
|
||||||
//将小写字母转换为大写字母
|
|
||||||
s[j] -= 0x20;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < max;) {
|
|
||||||
if (finfo[i].name[0] == 0x00) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((finfo[i].type & 0x18) == 0) {
|
|
||||||
for (j = 0; j < 11; j++) {
|
|
||||||
if (finfo[i].name[j] != s[j]) {
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return finfo + i; //找到文件
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return 0; //没有找到
|
|
||||||
}
|
|
||||||
struct FAT_FILEINFO *dict_search(char *name, struct FAT_FILEINFO *finfo,
|
|
||||||
int max) {
|
|
||||||
int i, j;
|
|
||||||
char s[12];
|
|
||||||
for (j = 0; j < 11; j++) {
|
|
||||||
s[j] = ' ';
|
|
||||||
}
|
|
||||||
j = 0;
|
|
||||||
for (i = 0; name[i] != 0; i++) {
|
|
||||||
if (j >= 11) {
|
|
||||||
return 0; //没有找到
|
|
||||||
} else {
|
|
||||||
s[j] = name[i];
|
|
||||||
if ('a' <= s[j] && s[j] <= 'z') {
|
|
||||||
//将小写字母转换为大写字母
|
|
||||||
s[j] -= 0x20;
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < max;) {
|
|
||||||
if (finfo[i].name[0] == 0x00) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (finfo[i].type == 0x10) {
|
|
||||||
for (j = 0; j < 11; j++) {
|
|
||||||
if (finfo[i].name[j] != s[j]) {
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return finfo + i; // 找到文件
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return 0; //没有找到
|
|
||||||
}
|
|
||||||
struct FAT_FILEINFO *Get_File_Address(char *path1, vfs_t *vfs) {
|
|
||||||
// TODO: Modifly it
|
|
||||||
struct FAT_FILEINFO *bmpDict = get_now_dir(vfs);
|
|
||||||
int drive_number = vfs->disk_number;
|
|
||||||
char *path = (char *)page_malloc(strlen(path1) + 1);
|
|
||||||
char *bmp = path;
|
|
||||||
strcpy(path, path1);
|
|
||||||
strtoupper(path);
|
|
||||||
if (strncmp("/", path, 1) == 0) {
|
|
||||||
path += 1;
|
|
||||||
bmpDict = get_dm(vfs).root_directory;
|
|
||||||
}
|
|
||||||
if (path[0] == '\\' || path[0] == '/') {
|
|
||||||
//跳过反斜杠和正斜杠
|
|
||||||
for (int i = 0; i < strlen(path); i++) {
|
|
||||||
if (path[i] != '\\' && path[i] != '/') {
|
|
||||||
path += i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char *temp_name = (char *)kmalloc(128);
|
|
||||||
struct FAT_FILEINFO *finfo = get_dm(vfs).root_directory;
|
|
||||||
int i = 0;
|
|
||||||
while (1) {
|
|
||||||
int j;
|
|
||||||
for (j = 0; i < strlen(path); i++, j++) {
|
|
||||||
if (path[i] == '\\' || path[i] == '/') {
|
|
||||||
temp_name[j] = '\0';
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
temp_name[j] = path[i];
|
|
||||||
}
|
|
||||||
finfo = dict_search(temp_name, bmpDict, get_directory_max(bmpDict, vfs));
|
|
||||||
if (finfo == 0) {
|
|
||||||
if (path[i] != '\0') {
|
|
||||||
kfree((void *)temp_name, 128);
|
|
||||||
kfree((void *)bmp, strlen(path1) + 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
finfo = file_search(temp_name, bmpDict, get_directory_max(bmpDict, vfs));
|
|
||||||
if (finfo == 0) {
|
|
||||||
kfree((void *)temp_name, 128);
|
|
||||||
kfree((void *)bmp, strlen(path1) + 1);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
goto END;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (get_clustno(finfo->clustno_high, finfo->clustno_low) != 0) {
|
|
||||||
for (int count = 1;
|
|
||||||
FindForCount(count, get_dm(vfs).directory_clustno_list) != NULL;
|
|
||||||
count++) {
|
|
||||||
struct List *list =
|
|
||||||
FindForCount(count, get_dm(vfs).directory_clustno_list);
|
|
||||||
if (get_clustno(finfo->clustno_high, finfo->clustno_low) ==
|
|
||||||
list->val) {
|
|
||||||
list = FindForCount(count, get_dm(vfs).directory_list);
|
|
||||||
bmpDict = (struct FAT_FILEINFO *)list->val;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bmpDict = get_dm(vfs).root_directory;
|
|
||||||
}
|
|
||||||
clean(temp_name, 128);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END:
|
|
||||||
kfree((void *)temp_name, 128);
|
|
||||||
kfree((void *)bmp, strlen(path1) + 1);
|
|
||||||
return finfo;
|
|
||||||
}
|
|
||||||
*/
|
|
@ -15,6 +15,8 @@
|
|||||||
#include "../include/vdisk.h"
|
#include "../include/vdisk.h"
|
||||||
#include "../include/pci.h"
|
#include "../include/pci.h"
|
||||||
#include "../include/pcnet.h"
|
#include "../include/pcnet.h"
|
||||||
|
#include "../include/fat.h"
|
||||||
|
#include "../include/floppy.h"
|
||||||
|
|
||||||
extern uint32_t end;
|
extern uint32_t end;
|
||||||
extern int status;
|
extern int status;
|
||||||
@ -64,22 +66,26 @@ void kernel_main(multiboot_t *multiboot) {
|
|||||||
init_keyboard();
|
init_keyboard();
|
||||||
printf("[\035kernel\036]: Keyboard driver load success!\n");
|
printf("[\035kernel\036]: Keyboard driver load success!\n");
|
||||||
multiboot_all = multiboot;
|
multiboot_all = multiboot;
|
||||||
|
io_sti();
|
||||||
|
init_pit();
|
||||||
init_vdisk();
|
init_vdisk();
|
||||||
init_pci();
|
init_pci();
|
||||||
|
init_vfs();
|
||||||
|
//init_floppy();
|
||||||
|
Register_fat_fileSys();
|
||||||
syscall_install();
|
syscall_install();
|
||||||
|
|
||||||
if(pcnet_find_card()){
|
if(pcnet_find_card()){
|
||||||
init_pcnet_card();
|
//init_pcnet_card();
|
||||||
} else printf("[\035kernel\036]: \033Cannot found pcnet.\036\n");
|
} else printf("[\035kernel\036]: \033Cannot found pcnet.\036\n");
|
||||||
|
|
||||||
print_cpu_id();
|
print_cpu_id();
|
||||||
io_sti();
|
|
||||||
|
|
||||||
printf("Memory: %dMB.",(multiboot->mem_upper + multiboot->mem_lower)/1024/1024);
|
printf("Memory: %dMB.",(multiboot->mem_upper + multiboot->mem_lower)/1024/1024);
|
||||||
|
|
||||||
clock_sleep(25);
|
clock_sleep(25);
|
||||||
|
|
||||||
//kernel_thread(setup_shell, NULL, "CPOS-Shell");
|
kernel_thread(setup_shell, NULL, "CPOS-Shell");
|
||||||
launch_date();
|
launch_date();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -50,3 +50,13 @@ void *memmove(void *dest, const void *src, size_t num) {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *realloc(void *ptr, uint32_t size) {
|
||||||
|
void *new = kmalloc(size);
|
||||||
|
if (ptr) {
|
||||||
|
memcpy(new, ptr, *(int *)((int)ptr - 4));
|
||||||
|
kfree(ptr);
|
||||||
|
}
|
||||||
|
return new;
|
||||||
|
}
|
@ -1,11 +1,19 @@
|
|||||||
#include "../include/timer.h"
|
#include "../include/timer.h"
|
||||||
#include "../include/io.h"
|
#include "../include/io.h"
|
||||||
#include "../include/graphics.h"
|
#include "../include/graphics.h"
|
||||||
#include "../include/isr.h"
|
#include "../include/cmos.h"
|
||||||
#include "../include/task.h"
|
|
||||||
|
|
||||||
uint32_t tick = 0;
|
uint32_t tick = 0;
|
||||||
extern struct task_struct *current;
|
extern struct task_struct *current;
|
||||||
|
struct TIMERCTL timerctl;
|
||||||
|
|
||||||
|
unsigned int time(void) {
|
||||||
|
unsigned int t;
|
||||||
|
t = get_year() * get_mon() * get_day_of_month() * get_hour() * get_min() * get_sec() + timerctl.count + timerctl.next;
|
||||||
|
t |= (int)timerctl.t0;
|
||||||
|
t |= get_day_of_week();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
static void timer_handle(registers_t *regs) {
|
static void timer_handle(registers_t *regs) {
|
||||||
io_cli();
|
io_cli();
|
||||||
@ -18,11 +26,33 @@ void clock_sleep(uint32_t timer){
|
|||||||
uint32_t sleep = tick + timer;
|
uint32_t sleep = tick + timer;
|
||||||
while(1){
|
while(1){
|
||||||
printf("");
|
printf("");
|
||||||
if(tick >= sleep)break;
|
if(tick >= sleep) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_pit(void) {
|
||||||
|
io_out8(0x43, 0x34);
|
||||||
|
io_out8(0x40, 0x9c);
|
||||||
|
io_out8(0x40, 0x2e);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
struct TIMER *t;
|
||||||
|
timerctl.count = 0;
|
||||||
|
for (i = 0; i < MAX_TIMER; i++) {
|
||||||
|
timerctl.timers0[i].flags = 0; /* 没有使用 */
|
||||||
|
}
|
||||||
|
t = timer_alloc(); /* 取得一个 */
|
||||||
|
t->timeout = 0xffffffff;
|
||||||
|
t->flags = TIMER_FLAGS_USING;
|
||||||
|
t->next = 0; /* 末尾 */
|
||||||
|
timerctl.t0 = t; /* 因为现在只有哨兵,所以他就在最前面*/
|
||||||
|
timerctl.next =
|
||||||
|
0xffffffff; /* 因为只有哨兵,所以下一个超时时刻就是哨兵的时刻 */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void init_timer(uint32_t timer) {
|
void init_timer(uint32_t timer) {
|
||||||
|
printf("REG TIMER INT: %d, function address: %08x.\n",IRQ0, &timer_handle);
|
||||||
register_interrupt_handler(IRQ0, &timer_handle);
|
register_interrupt_handler(IRQ0, &timer_handle);
|
||||||
uint32_t divisor = 1193180 / timer;
|
uint32_t divisor = 1193180 / timer;
|
||||||
|
|
||||||
@ -34,3 +64,55 @@ void init_timer(uint32_t timer) {
|
|||||||
outb(0x40, l);
|
outb(0x40, l);
|
||||||
outb(0x40, h);
|
outb(0x40, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TIMER *timer_alloc(void) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_TIMER; i++) {
|
||||||
|
if (timerctl.timers0[i].flags == 0) {
|
||||||
|
timerctl.timers0[i].flags = TIMER_FLAGS_ALLOC;
|
||||||
|
timerctl.timers0[i].waiter = NULL;
|
||||||
|
return &timerctl.timers0[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; /* 没找到 */
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_free(struct TIMER *timer) {
|
||||||
|
timer->flags = 0; /* 未使用 */
|
||||||
|
timer->waiter = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data) {
|
||||||
|
timer->fifo = fifo;
|
||||||
|
timer->data = data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_settime(struct TIMER *timer, unsigned int timeout) {
|
||||||
|
int e;
|
||||||
|
struct TIMER *t, *s;
|
||||||
|
timer->timeout = timeout + timerctl.count;
|
||||||
|
timer->flags = TIMER_FLAGS_USING;
|
||||||
|
e = io_load_eflags();
|
||||||
|
t = timerctl.t0;
|
||||||
|
if (timer->timeout <= t->timeout) {
|
||||||
|
/* 插入最前面的情况 */
|
||||||
|
timerctl.t0 = timer;
|
||||||
|
timer->next = t; /* 下面是设定t */
|
||||||
|
timerctl.next = timer->timeout;
|
||||||
|
io_store_eflags(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
s = t;
|
||||||
|
t = t->next;
|
||||||
|
if (timer->timeout <= t->timeout) {
|
||||||
|
/* 插入s和t之间的情况 */
|
||||||
|
s->next = timer; /* s下一个是timer */
|
||||||
|
timer->next = t; /* timer的下一个是t */
|
||||||
|
io_store_eflags(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "../include/timer.h"
|
#include "../include/timer.h"
|
||||||
#include "../include/memory.h"
|
#include "../include/memory.h"
|
||||||
#include "../include/printf.h"
|
#include "../include/printf.h"
|
||||||
|
#include "../include/dhcp.h"
|
||||||
|
|
||||||
uint8_t bus = 255, dev = 255, func = 255;
|
uint8_t bus = 255, dev = 255, func = 255;
|
||||||
|
|
||||||
@ -56,7 +57,10 @@ void reset_card() {
|
|||||||
void Activate() {
|
void Activate() {
|
||||||
// 激活PCNET IRQ中断
|
// 激活PCNET IRQ中断
|
||||||
io_out16(io_base + RAP16, CSR0);
|
io_out16(io_base + RAP16, CSR0);
|
||||||
|
|
||||||
|
printf("[pcnet]: io\n");
|
||||||
io_out16(io_base + RDP16, 0x41);
|
io_out16(io_base + RDP16, 0x41);
|
||||||
|
printf("[pcnet]: success.\n");
|
||||||
|
|
||||||
io_out16(io_base + RAP16, CSR4);
|
io_out16(io_base + RAP16, CSR4);
|
||||||
uint32_t temp = io_in16(io_base + RDP16);
|
uint32_t temp = io_in16(io_base + RDP16);
|
||||||
@ -65,6 +69,7 @@ void Activate() {
|
|||||||
|
|
||||||
io_out16(io_base + RAP16, CSR0);
|
io_out16(io_base + RAP16, CSR0);
|
||||||
io_out16(io_base + RDP16, 0x42);
|
io_out16(io_base + RDP16, 0x42);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcnet_find_card() {
|
int pcnet_find_card() {
|
||||||
@ -88,6 +93,8 @@ static void init_Card_all() {
|
|||||||
reset_card();
|
reset_card();
|
||||||
clock_sleep(1);
|
clock_sleep(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
io_out16(io_base + RAP16, BCR20);
|
io_out16(io_base + RAP16, BCR20);
|
||||||
io_out16(io_base + BDP16, 0x102);
|
io_out16(io_base + BDP16, 0x102);
|
||||||
io_out16(io_base + RAP16, CSR0);
|
io_out16(io_base + RAP16, CSR0);
|
||||||
@ -146,28 +153,19 @@ static void init_Card_all() {
|
|||||||
ip == 0xFFFFFFFF) {
|
ip == 0xFFFFFFFF) {
|
||||||
initBlock.logicalAddress = ip;
|
initBlock.logicalAddress = ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化ARP表
|
|
||||||
|
|
||||||
|
|
||||||
// DNSParseIP("baidu.com");
|
|
||||||
|
|
||||||
// UDPProviderSend(0x761ff8d7, initBlock.logicalAddress, 52949, 38,
|
|
||||||
// "来自Powerint DOS 386的消息:我是周志昊!!!", strlen("来自Powerint DOS
|
|
||||||
// 386的消息:我是周志昊!!!"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_pcnet_card() {
|
void init_pcnet_card() {
|
||||||
printf("[\035kernel\036]: Loading pcnet driver.\n");
|
printf("[\035kernel\036]: Loading pcnet driver.\n");
|
||||||
// 允许PCNET网卡产生中断
|
|
||||||
// 1.注册中断
|
|
||||||
register_interrupt_handler(pci_get_drive_irq(bus, dev, func),PCNET_IRQ);
|
register_interrupt_handler(pci_get_drive_irq(bus, dev, func),PCNET_IRQ);
|
||||||
// 2,写COMMAND和STATUS寄存器
|
// 2,写COMMAND和STATUS寄存器
|
||||||
uint32_t conf = pci_read_command_status(bus, dev, func);
|
uint32_t conf = pci_read_command_status(bus, dev, func);
|
||||||
conf &= 0xffff0000; // 保留STATUS寄存器,清除COMMAND寄存器
|
conf &= 0xffff0000; // 保留STATUS寄存器,清除COMMAND寄存器
|
||||||
conf |= 0x7; // 设置第0~2位(允许PCNET网卡产生中断
|
conf |= 0x7; // 设置第0~2位(允许PCNET网卡产生中断
|
||||||
|
|
||||||
pci_write_command_status(bus, dev, func, conf);
|
pci_write_command_status(bus, dev, func, conf);
|
||||||
io_base = pci_get_port_base(bus, dev, func);
|
io_base = pci_get_port_base(bus, dev, func);
|
||||||
|
|
||||||
init_Card_all();
|
init_Card_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,42 @@
|
|||||||
|
|
||||||
static char num_str_buf[BUF_SIZE];
|
static char num_str_buf[BUF_SIZE];
|
||||||
|
|
||||||
|
void insert_char(char* str, int pos, char ch) {
|
||||||
|
int i;
|
||||||
|
for (i = strlen(str); i >= pos; i--) {
|
||||||
|
str[i + 1] = str[i];
|
||||||
|
}
|
||||||
|
str[pos] = ch;
|
||||||
|
}
|
||||||
|
void delete_char(char* str, int pos) {
|
||||||
|
int i;
|
||||||
|
for (i = pos; i < strlen(str); i++) {
|
||||||
|
str[i] = str[i + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void strtoupper(char* str) {
|
||||||
|
while (*str != '\0') {
|
||||||
|
if (*str >= 'a' && *str <= 'z') {
|
||||||
|
*str -= 32;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int strncmp(const char* s1, const char* s2, size_t n) {
|
||||||
|
const unsigned char *p1 = (const unsigned char*)s1,
|
||||||
|
*p2 = (const unsigned char*)s2;
|
||||||
|
while (n-- > 0) {
|
||||||
|
if (*p1 != *p2)
|
||||||
|
return *p1 - *p2;
|
||||||
|
if (*p1 == '\0')
|
||||||
|
return 0;
|
||||||
|
p1++, p2++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
long int strtol(const char *str,char **endptr,int base){
|
long int strtol(const char *str,char **endptr,int base){
|
||||||
const char *s;
|
const char *s;
|
||||||
unsigned long acc;
|
unsigned long acc;
|
||||||
|
73
util/list.c
73
util/list.c
@ -1,4 +1,5 @@
|
|||||||
#include "../include/list.h"
|
#include "../include/list.h"
|
||||||
|
#include "../include/memory.h"
|
||||||
|
|
||||||
int GetLastCount(struct List* Obj) {
|
int GetLastCount(struct List* Obj) {
|
||||||
return Obj->ctl->all;
|
return Obj->ctl->all;
|
||||||
@ -19,3 +20,75 @@ struct List* FindForCount(size_t count, struct List* Obj) {
|
|||||||
q = q->prev;
|
q = q->prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Change(size_t count, struct List* Obj, uintptr_t val) {
|
||||||
|
struct List* Will_Change = FindForCount(count + 1, Obj);
|
||||||
|
if (Will_Change != NULL) {
|
||||||
|
Will_Change->val = val;
|
||||||
|
} else {
|
||||||
|
AddVal(val, Obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteList(struct List* Obj) {
|
||||||
|
Obj = Obj->ctl->start;
|
||||||
|
kfree((void *)Obj->ctl);
|
||||||
|
for (; Obj != (struct List*)NULL;) {
|
||||||
|
//printf("Will free: %llx\n", Obj);
|
||||||
|
struct List* tmp = Obj;
|
||||||
|
Obj = Obj->next;
|
||||||
|
kfree((void *)tmp);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct List* NewList() {
|
||||||
|
struct List* Obj = (struct List*)kmalloc(sizeof(struct List));
|
||||||
|
struct ListCtl* ctl = (struct ListCtl*)kmalloc(sizeof(struct ListCtl));
|
||||||
|
Obj->ctl = ctl;
|
||||||
|
Obj->ctl->start = Obj;
|
||||||
|
Obj->ctl->end = Obj;
|
||||||
|
Obj->val = 0x123456; // 头结点数据不可用
|
||||||
|
Obj->prev = (List*)NULL;
|
||||||
|
Obj->next = (List*)NULL;
|
||||||
|
Obj->ctl->all = 0;
|
||||||
|
return Obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteVal(size_t count, struct List* Obj) {
|
||||||
|
struct List* Will_Free = FindForCount(count, Obj);
|
||||||
|
if (Will_Free == NULL) {
|
||||||
|
// Not found!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Will_Free->next == (List*)NULL) {
|
||||||
|
// 是尾节点
|
||||||
|
struct List* prev = FindForCount(count - 1, Obj);
|
||||||
|
prev->next = (List*)NULL;
|
||||||
|
prev->ctl->end = prev;
|
||||||
|
} else {
|
||||||
|
struct List* prev = FindForCount(count - 1, Obj);
|
||||||
|
struct List* next = FindForCount(count + 1, Obj);
|
||||||
|
prev->next = next;
|
||||||
|
next->prev = prev;
|
||||||
|
}
|
||||||
|
kfree((void *)Will_Free);
|
||||||
|
Obj->ctl->all--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddVal(uintptr_t val, struct List* Obj) {
|
||||||
|
while (Obj->next != NULL)
|
||||||
|
Obj = Obj->next;
|
||||||
|
Obj = Obj->ctl->end;
|
||||||
|
struct List* new = (struct List*)kmalloc(sizeof(struct List));
|
||||||
|
Obj->next = new;
|
||||||
|
Obj->ctl->end = new;
|
||||||
|
new->prev = Obj;
|
||||||
|
new->ctl = Obj->ctl;
|
||||||
|
new->next = (List*)NULL;
|
||||||
|
new->val = val;
|
||||||
|
new->ctl->all++;
|
||||||
|
}
|
||||||
|
12
util/rand.c
Normal file
12
util/rand.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "../include/common.h"
|
||||||
|
|
||||||
|
static unsigned long next1 = 1;
|
||||||
|
|
||||||
|
unsigned int rand(void) {
|
||||||
|
next1 = next1 * 1103515245 + 12345;
|
||||||
|
return ((unsigned int)(next1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void srand(unsigned long seed) {
|
||||||
|
next1 = seed;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user