⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 harddisk.c

📁 一个完整的GUI界面OS,单盘启动 实现了多线程、FAT32文件读写
💻 C
字号:
//-----------------------------------------------------------------------------------------------------------------------
//          HardDisk Driver For FireXOS  1.01 
//
//          Version  1.01
//
//          Create by  xiaofan                                   2004.9.20
//
//          Update by xiaofan                                    2004.9.20
//------------------------------------------------------------------------------------------------------------------------
#include "Io.h"
#include "Traps.h"
#include "HardDisk.h"
#include "String.h"
#include "Timer.h"
#include "Console.h"

unsigned char NR_HD_DEV;
struct HardDiskStruct HardDiskInfo[2];
static char HardDiskName[16];


#define MAIN_PART 4
struct  disk_partition hd[MAIN_PART+1];


struct partitiontypes partition_types[] = {
    {0, "Unknow Partition"},
    {1, "DOS 12-bit FAT"},		/* Primary DOS with 12-bit FAT */
    {2, "XENIX /"},			/* XENIX / filesystem */
    {3, "XENIX /usr"},			/* XENIX /usr filesystem */
    {4, "DOS 16-bit FAT <32M"},		/* Primary DOS with 16-bit FAT */
    {5, "DOS Extended"},		/* DOS 3.3+ extended partition */
    {6, "DOS 16-bit FAT >=32M"},
    {7, "OS/2 IFS (e.g., HPFS) or NTFS or QNX2 or Advanced UNIX"},
    {8, "AIX boot or SplitDrive"},
    {9, "AIX data or Coherent"},
    {0x0a, "OS/2 Boot Manager or Coherent swap"},
    {0x0b, "Microsoft Windows FAT32"},
    {0x0c, "Windows FAT32 (lba)"},
    {0x0d, "Windows FAT16(lba)"},
    {0x0e, "MSDOS FAT16. CHS-mapped"},
    {0x0f, "Ext. partition, CHS-mapped"},
    {0x10, "OPUS"},
    {0x11, "OS/2 BM: hidden DOS 12-bit FAT"},
    {0x12, "Compaq diagnostics"},
    {0x14, "OS/2 BM: hidden DOS 16-bit FAT <32M"},
    {0x16, "OS/2 BM: hidden DOS 16-bit FAT >=32M"},
    {0x17, "OS/2 BM: hidden IFS"},
    {0x18, "AST Windows swapfile"},
    {0x24, "NEC DOS"},
    {0x3c, "PartitionMagic recovery"},
    {0x40, "Venix 80286"},
    {0x41, "Linux/MINIX (sharing disk with DRDOS)"},
    {0x42, "SFS or Linux swap (sharing disk with DRDOS)"},
    {0x43, "Linux native (sharing disk with DRDOS)"},
    {0x50, "DM (disk manager)"},
    {0x51, "DM6 Aux1 (or Novell)"},
    {0x52, "CP/M or Microport SysV/AT"},
    {0x53, "DM6 Aux3"},
    {0x54, "DM6"},
    {0x55, "EZ-Drive (disk manager)"},
    {0x56, "Golden Bow (disk manager)"},
    {0x5c, "Priam Edisk (disk manager)"}, /* according to S. Widlake */
    {0x61, "SpeedStor"},
    {0x63, "GNU HURD or Mach or Sys V/386 (such as ISC UNIX)"},
    {0x64, "Novell Netware 286"},
    {0x65, "Novell Netware 386"},
    {0x70, "DiskSecure Multi-Boot"},
    {0x75, "PC/IX"},
    {0x77, "QNX4.x"},
    {0x78, "QNX4.x 2nd part"},
    {0x79, "QNX4.x 3rd part"},
    {0x80, "MINIX until 1.4a"},
    {0x81, " MINIX Version 2. "},
    {0x82, "Unite Journal File System  Jicama native"},
    {0x83, "Linux native:Ext2 Fs"},
    {0x84, "OS/2 hidden C: drive"},
    {0x85, "Linux extended"},
    {0x86, "NTFS volume set??"},
    {0x87, "NTFS volume set??"},
    {0x90, "???????"},
    {0x93, "Amoeba"},
    {0x94, "Amoeba BBT"},		/* (bad block table) */
    {0xa0, "IBM Thinkpad hibernation"}, /* according to dan@fch.wimsey.bc.ca */
    {0xa5, "BSD/386"},			/* 386BSD */
    {0xa7, "NeXTSTEP 486"},
    {0xb7, "BSDI fs"},
    {0xb8, "BSDI swap"},
    {0xc1, "DRDOS/sec (FAT-12)"},
    {0xc4, "DRDOS/sec (FAT-16, < 32M)"},
    {0xc6, "DRDOS/sec (FAT-16, >= 32M)"},
    {0xc7, "Syrinx"},
    {0xdb, "CP/M or Concurrent CP/M or Concurrent DOS or CTOS"},
    {0xe1, "DOS access or SpeedStor 12-bit FAT extended partition"},
    {0xe3, "DOS R/O or SpeedStor"},
    {0xe4, "SpeedStor 16-bit FAT extended partition < 1024 cyl."},
    {0xf1, "SpeedStor"},
    {0xf2, "DOS 3.3+ secondary"},
    {0xf4, "SpeedStor large partition"},
    {0xfe, "SpeedStor >1024 cyl. or LANstep"},
    {0xff, "Xenix Bad Block Table"}
};


void HardDiskInterrupt(void);                                               //硬盘中断句柄

//-------------------------------------------------------------------------------------------------------------------------------////  字符交换////-------------------------------------------------------------------------------------------------------------------------------
void SwapChar(unsigned char* toswap)
{
	int      i = 0;
	unsigned char temp;

	while (toswap[i+1] != 0)
	{
		  temp = toswap[i];
		  toswap[i] = toswap[i+1];
		  toswap[i+1] = temp;

		  i += 2;
    }

	return;
}

//-------------------------------------------------------------------------------------------------------------------------------////  检测硬盘存在函数////-------------------------------------------------------------------------------------------------------------------------------
static int	GetIDENum(void)
{
	 unsigned short    buffer[256];
	 char              *text;
	 unsigned char     c_disks;
 
   c_disks = ReadCmos(0x12);
	
	if (c_disks & 0xf0){
		if (c_disks & 0x0f){
			NR_HD_DEV = 2;
		}
		else{
			NR_HD_DEV = 1;
	   }
    }
	else{
		  NR_HD_DEV = 0;
		  return 0;
	}

	outb(0xA0,0x1F6); // Get first/second drive 
	outb(0xEC,0x1F7);  // 获取驱动器信息数据 
    
	memset(HardDiskInfo, 0, sizeof(struct HardDiskStruct));

	while (inb(HD_STATUS)&0x80);
	insw(0x1f0, buffer, 256);  //将数据读到缓冲区
	HardDiskInfo[0].sect = buffer[6];
	HardDiskInfo[0].head = buffer[3];
	HardDiskInfo[0].cyl =  buffer[1];

	text = (unsigned char*)&buffer[27];
	SwapChar(text);
	strcpy(HardDiskName, text);
  HardDiskName[15]=0;

	return NR_HD_DEV;
}


//-------------------------------------------------------------------------------------------------------------------------------////  读取硬盘信息函数////-------------------------------------------------------------------------------------------------------------------------------
void	ReadIDEInfo(void)
{
	int i, partsize, sect_count;

	sect_count = HardDiskInfo[0].head * HardDiskInfo[0].sect * HardDiskInfo[0].cyl;
	partsize =   sect_count /2048;
	ConsoleMsg("  Harddisk Information:\n");
	ConsoleMsg("  Total Space:%i MB\n", partsize );
	ConsoleMsg("  Sectors:%i  Heads:%i Cylinder:%i \n\n", 
	HardDiskInfo[0].sect, HardDiskInfo[0].head, HardDiskInfo[0].cyl);

	 for (i = 1; i < 5; i++)
	 {
		 ConsoleMsg("  PARTITION [%c:] start sect: %d size: %d type: %s\n",
			             hd[i].name, hd[i].lowsec,hd[i].nr_sects / 2048,  hd[i].type);
	 }
	 ConsoleMsg("\n");
}

//-------------------------------------------------------------------------------------------------------------------------------////  读取硬盘已激活分区信息函数////-------------------------------------------------------------------------------------------------------------------------------
static int FindActivePartition(struct partition *p, int i)
{
		if(p->indicator == 0x80){
			ConsoleMsg("  Active partition : %d \n", i);
			return 1;
		}
		return 0;
}

//-------------------------------------------------------------------------------------------------------------------------------////  读取硬盘分区类型名称函数////-------------------------------------------------------------------------------------------------------------------------------
static char* GetPartitionName(unsigned char type)
{
       struct partitiontypes *pp;
       for (pp = partition_types; pp->type<0xff; pp++)
            if (pp->type == type)
	          return pp->name;
       return "  bad file system or disk.we can't read it!!";
}

//-------------------------------------------------------------------------------------------------------------------------------////  读取硬盘分区信息函数////-------------------------------------------------------------------------------------------------------------------------------
int ReadPartition(void)
{
	int i = 0;
	int sector, head, cylinder;
	unsigned char buffer[512];
	struct partition* p;

#ifndef HD_BOOT_SECTOR
#define HD_BOOT_SECTOR 0
#endif

  ConsolePrintf("Check the hard disk partition\n");

	sector = HD_BOOT_SECTOR &0xff;
	cylinder = (HD_BOOT_SECTOR &0xffff00)>>8;
	head = (HD_BOOT_SECTOR &0xf000000)>>24;
  
	while(inb(HD_STATUS) & 0x80);
	io_wait();
	outb(0,HD_CMD);
	outb(1,0x1f2);                   ///////////读写的扇区数.这个端口应该是:0X1F2,下面开始增加一
	outb(HD_BOOT_SECTOR,0x1f3);      ////////开始扇区
	outb(cylinder,0x1f4);            ///////开始柱面
	outb(cylinder>>8,0x1f5);         ///////开始柱面高位
	outb(0xE0|(0 <<4)|head,0x1f6);   /////主磁盘
	outb(0x20,0x1F7);                ////read命令
  while(inb(HD_STATUS) & 0x80);
	insw(0x1F0, buffer, 256);

	if (buffer[510] != (unsigned char) 0x55 || buffer[511] != (unsigned char) 0xAA){
		ConsolePrintFault();
		ConsoleWarning("  read_partition(): Can't Read Harddisk(IDE) partition data\n");
		return -1;
	}
  
	ConsolePrintOK();
	for (i=1;i<5;i++)
	{

	   p = (struct partition*)&buffer[0x1be + (i-1)*0x10]; //partition table offset after 446 byte.
		 hd[i].start_sect = p->start_sec;  	                 // 从0算起的绝对扇区(分区表的起始扇区,不是FAT表的)
		 hd[i].start_head=p->start_head;
		 hd[i].start_cyl=p->start_cyl;
		 hd[i].nr_sects = p->size;                           // 分区扇区总数 
		 hd[i].flag = p->type;
		 hd[i].lowsec = p->lowsec;
		 hd[i].type = GetPartitionName( p->type);
	   hd[i].name = 0x42+i;
	   FindActivePartition(p, i);
	}

	ReadIDEInfo();

	return 0;
}

//-------------------------------------------------------------------------------------------------------------------------------////  硬盘中断处理函数////-------------------------------------------------------------------------------------------------------------------------------
void HardDiskHandle(void)
{

}


//-------------------------------------------------------------------------------------------------------------------------------////  硬盘读写处理函数////-------------------------------------------------------------------------------------------------------------------------------
void HardDiskRW(int RW, unsigned long sectors, void* buffer)
{
  unsigned __eflag;
	int sector, head, cylinder;

  save_eflags(&__eflag);

	sector   = sectors &0xff;
	cylinder = (sectors &0xffff00)>>8;
	head     = (sectors &0xf000000)>>24;

	while(inb(HD_STATUS) & 0x80);
	io_wait();
	outb(0,HD_CMD);

	outb(1,0x1f2);                 ///////////读写的扇区数.这个端口应该是:0X1F2,下面开始增加一
	outb(sector,0x1f3);            ////////开始扇区
	outb(cylinder,0x1f4);          ///////开始柱面
	outb(cylinder>>8,0x1f5);       ///////开始柱面高位
	outb(0xE0|(0 <<4)|head,0x1f6); /////主磁盘

	if (RW == READ)
	{                              ////read命令
	    outb(0x20,0x1F7);         
        while(inb(HD_STATUS) & 0x80);
	    insw(0x1F0, buffer, 256);
	}
	else if (RW == WRITE)
	{                             ////write命令

	if (inb(HD_STATUS & 0x01)) {
		ConsoleWarning("  issue write_command command error !\n");
		return;
	}

		 outb(0x30,0x1F7);   
	   while((inb(HD_STATUS) & 0x08) == 0);       //DRQ
	     outsw(0x1F0, buffer, 256);
     }
	else {
		ConsoleWarning("  Panic:bad command:you only can read or write on harddisk!");
	}
	restore_eflags(__eflag);
	return;
}



//-------------------------------------------------------------------------------------------------------------------------------////  硬盘初始化函数////-------------------------------------------------------------------------------------------------------------------------------
void HardDiskInit (void)
{
	
	ConsolePrintf("Set the hard disk driver");

	if(GetIDENum()==0) 
	{
		ConsolePrintFault();
		ConsoleMsg("\n");
		ConsoleMsg("  System had no hard disk!\n");
    ConsoleMsg("\n");
	  return;}
  
	ConsolePrintOK();

	ConsoleMsg("\n");

	if(NR_HD_DEV==1)
	ConsoleMsg("  System only one hard disk\n");
	else if(NR_HD_DEV==2)
	ConsoleMsg("  System have two hard disk\n");

	ConsoleMsg("  Hard disk Type: %s\n", HardDiskName );
	ConsoleMsg("\n");

	//for(i=0 ; i<NR_BLK_REQUEST ; i++) {
	//	hd_req[i].flag = -1;
	//	hd_req[i].next = NULL;
	//	semaphore_init (&(hd_req[i].sem), 0);
	//}

	//semaphore_init(&request_sem, NR_BLK_REQUEST);

	SetIntrGate(0x2E,(void*)HardDiskInterrupt);	outb_p(inb_p(0x21)&0xfb,0x21);	outb(inb_p(0xA1)&0xbf,0xA1);

  TickDelay(1);
	ReadPartition();                                            //Must before fs!!!
	TickDelay(1);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -