shell 拷贝文件到指定目录_自制操作系统(12)——读取文件目录与shell的简单交互...

本文介绍了一种基于C语言的系统,通过汇编辅助实现了硬盘I/O操作,重点讲解了如何读取FAT12目录项并用于文件管理。作者展示了如何使用中断检测、扇区读取函数和基本的文件操作,以提升系统的交互性和炫酷感。
摘要由CSDN通过智能技术生成
项目地址
https://github.com/belowthetree/Make-a-system​github.com

进程切换在本项目中其实不是什么重要的部分,因为没有打算加入执行外部程序的功能(主要是懒)。那么为了让这个系统看起来更炫酷(在外行面前装13),就需要把交互性做好。

硬盘IO

bootloader部分已经用汇编完成了一个文件的读取,现在需要加入到C内核的功能里面,方便调用读取文件。

#define PORT_DISK0_DATA	0x1f0
#define PORT_DISK0_ERR_FEATURE 0x1f1
#define PORT_DISK0_SECTOR_CNT 0x1f2
#define PORT_DISK0_SECTOR_LOW 0x1f3
#define PORT_DISK0_SECTOR_MID 0x1f4
#define PORT_DISK0_SECTOR_HIGH 0x1f5
#define PORT_DISK0_DEVICE 0x1f6
#define PORT_DISK0_STATUS_CMD 0x1f7

#define DISK_STATUS_BUSY	(1 << 7)
#define DISK_STATUS_READY	(1 << 6)
#define DISK_STATUS_SEEK	(1 << 4)
#define DISK_STATUS_REQ		(1 << 3)
#define DISK_STATUS_ERROR	(1 << 0)

以上是预设的一些量,在发送命令之后检查状态的第三位,确认硬盘数据是否发送完毕

void read_one_sector(int n, unsigned char* cx){
	finish = 0;
	reader = cx;

	io_out8(PORT_DISK0_ALT_STA_CTL, 0);
	io_out8(PORT_DISK0_SECTOR_CNT, 1);
	io_out8(PORT_DISK1_ERR_FEATURE, 0);
	io_out8(PORT_DISK0_SECTOR_LOW, (unsigned char)(n & 0xff));
	io_out8(PORT_DISK0_SECTOR_MID, (unsigned char)((n >> 8) & 0xff));
	io_out8(PORT_DISK0_SECTOR_HIGH, (unsigned char)((n >> 16) & 0xff));
	io_out8(PORT_DISK0_DEVICE, 0xe0 | (unsigned char)((n >> 24) & 0x0f));
	io_out8(PORT_DISK0_STATUS_CMD, 0x20);

	// 直接检测数据是否抵达端口
	while (!(io_in8(PORT_DISK0_STATUS_CMD) & DISK_STATUS_REQ));

	port_insw(PORT_DISK0_DATA, reader, 256);
	finish = 1;
}

这个函数对外作为读取磁盘的接口,一次读取一个扇区。

#define port_insw(port,buffer,nr)	
__asm__ __volatile__("cld;rep;insw;mfence;"::"d"(port),"D"(buffer),"c"(nr):"memory")

文件读取

struct DIR{
	char filename[11];
	unsigned char attr;
	unsigned char rev[10];
	unsigned short wtime;
	unsigned short wdate;
	unsigned short stcluster;
	unsigned int filesize;
}__attribute__((packed));

struct DIR dirs[16];

DIRFAT12目录项结构,一个扇区16个目录项。

void scanf_files(){
	filecnt = 0;

	int i, j;
	for (j = 0;j < 14;j++){
		read_one_sector(19 + j, dirs);
		while (!finish);

		for (i = 0; i < 0x10; i++){
			if (dirs[i].attr != 0x20)
				continue;
			files[filecnt++] = dirs[i];
			printf_color(BLACK, YELLOW, "%sn", dirs[i].filename);
		}
	}
	printf_color(BLACK, RED, "scanf finishn");
}

void list_files(){
	int i;
	for (i = 0;i < filecnt; i++){
		printf_color(BLACK, INDIGO, "%st", files[i].filename);
	}
	printf("n");
}

通过扫描读取完所有的目录项,保存已有的文件信息。方便之后使用。

交互

交互目前提供以下指令

char *ins[] = {
	"ls",
	"cls",
	"help help me",
};

char *helpinfo[] = {
	"list files",
	"clear screen",
	"list help info",
};

void help(){
	int i;
	for (i = 0; i < 3;i++)
		printf_color(BLACK, GREEN, "%s: %sn", ins[i], helpinfo[i]);
}

为了进行字符串对比,写了一个strcmpcurcmd是键盘解码时保存的当前输入 ,cls是新增的清屏函数

while(1){
		hlt();
		decode_keyboard();
		if (cmd){
			cmd = 0;
			if (strcmp(curcmd, "ls"))
				list_files();
			else if(strcmp(curcmd, "cls"))
				cls();
			else if (strcmp(curcmd, "help help me"))
				help();
			else
				printf_color(BLACK, RED, "no cmdn");
		}
	}

这样就完成简单的交互了

fed2cf6e005e3fa2066c706bf4b59a6e.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值