📄 bios_hd.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 + -