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

📄 bios_hd.c

📁 linux下面直接读硬盘扇区的程序
💻 C
字号:
#include <bios_hd.h>
#include <bios_io.h>
extern int printk(const char * fmt, ...);
typedef void (*fn_t)(void);
extern int put_irq_handler(int irq, fn_t fn);

#define SECTOR_SIZE 512

#define ide_batch_read(port,buf,nr) \
__asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr))

#define ide_batch_write(port,buf,nr) \
__asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr))

hd_id id; 

unsigned char ide_sector_read_buffer[SECTOR_SIZE];
unsigned char ide_sector_write_buffer[SECTOR_SIZE];

int reading = 0; /* indicate whether is reading */

void ide_init(void);
void ide_interrupt(void);
void ide_read_sector(int sector_no,unsigned char *);
void ide_write_sector(int sector_no,unsigned char *);
void ide_test(void);

static void get_ide_info(void);
static void ide_send_command(int ide_command);
static void ide_write_to_port(unsigned char *pbuffer);
static void ide_read_from_port(unsigned char *pubuffer);

static void get_ide_info(void)
{
	outb(0xA0, Drive_Register);
	outb(Identify_Drive, Status_Register);

	while (inb(Status_Register) & Drive_Busy) ;
	ide_batch_read(Data_Register, &id, sizeof(id)/2);
}

void ide_init(void)
{
	put_irq_handler(14, ide_interrupt);
	get_ide_info();
	printf("your harddisk model : %s\n", id.model);
	printf("your harddisk capacity : %s\n",id.capacity);
	ide_read_sector(0, ide_sector_read_buffer);
	return;
}

void ide_interrupt(void)
{
	/* the main IDE handler */
	printf(" there is a ide interrupt occuring !\n");
	if (reading)
	{
    	reading = 0; /* processed */
		ide_read_from_port(ide_sector_read_buffer);
		printf("read from io port !\n");
	}
	return;
}

void ide_read_sector(int sector_no, unsigned char *buff)
{
	int c, h, s;
	unsigned char status;

	cli();
	s = sector_no & 0xFF;
	c = (sector_no & 0xFFFF00) >> 8;
	h = (sector_no & 0xF000000) >> 24;

	reading = 1;
	while (inb(Status_Register) & Drive_Busy) ;
#if 0
	printf("pass STATUS_REG ! \n");

	outb(1, Sector_Number_Register); /* the number of sectors to read */
	outb(sector_no, Sector_Register); /* the no of the sector to read */
	outb(c, Cylinder_Register_Low); /* low 8 bits of cylinder */
	outb(c >> 8, Cylinder_Register_High); /* high 2 bits of cylinder */
	outb(0xE0 | (0 << 4) | h, Drive_Register); /* d765 = 101 , ecc, 512B/SECTOR */

	outb(Read_Sector, Command_Register);

	while ((status = inb(Status_Register)) & Drive_Busy) ;
#if 0
	printf("pass inb(Status_Register)) IS BUSY ? \n");
#endif

	ide_read_from_port(buff);
	sti();
	return;
}

static void ide_read_from_port(unsigned char *pbuffer)
{
#if 0
	printf(" enter ide_read_from_port \n");
#endif
	ide_batch_read(Data_Register, pbuffer, SECTOR_SIZE/2);
	return;
}

void ide_write_sector(int sector_no, unsigned char *buff)
{
	int c, h, s;
#if 0
	unsigned char status;
#endif

	cli();
	s = sector_no & 0xFF;
	c = (sector_no & 0xFFFF00) >> 8;
	h = (sector_no & 0xF000000) >> 24;

	while (inb(Status_Register) & Drive_Busy) ;
	/* printk("pass STATUS_REG ! \n"); */

	outb(1, 0x1F2); /* the number of sectors to read */
	outb(sector_no, 0x1F3); /* the no of the sector to read */
	outb(c, 0x1F4); /* low 8 bits of cylinder */
	outb(c>>8, 0x1F5); /* high 2 bits of cylinder */
	outb(0xE0 | (0 << 4) | h, 0x1F6); /* d765 = 101 , ecc, 512B/SECTOR */

	outb(IDE_WRITE_COMMAND, 0x1F7);

	if (inb(STATUS_REG & 0x01)) {
		printk(" issue write_command command error !\n");
		return;
	}
	/* wait for DRQ */
	while (!(inb(STATUS_REG) & 0x08))
		;

#if 0
	printk("pass while(!(inb(STATUS_REG) & 0x08) \n");
#endif

	/* ok , let's pass data */
	ide_write_to_port(buff);
	sti();
	return;
}

⌨️ 快捷键说明

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