📄 main.c
字号:
/*
nexOS: nexos generic ata driver - generic ata driver
Copyright 2004 nexOS development team
This file is part of nexOS.
nexOS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
nexOS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with nexOS; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Include nexOS mlibc integrated C library headers only */
#include <stdio.h>
#include <stdlib.h>
#include <libnexos-module/nexos-module.h>
#include "../../../io/io.h"
#include "ata.h"
#include "fat32.h"
const char ata_cmderr[][15] = {
"no error",
"timeout",
"not supported"
};
const char ata_errors[][40] = {
"unknown error"
};
void *ModuleInit(int argc, char *argv[], NEXOS_FUNC *funcs);
int ModuleFini();
int ata_probedevices(int argc, char *argv[]);
int ata_bootsect(int argc, char *argv[]);
const char *ata_map_sysid(BYTE sysid);
/* global variables */
int ModuleShellCommandID[3];
/* our identification */
const NEXOS_MODULE_ID ModuleID = {
"nexOS development team",
"generic ATA/IDE driver",
CREATEVERSION(0,0,1),
NEXOS_MOD_NONE,
ModuleFini
};
void *ModuleInit(int argc, char *argv[], NEXOS_FUNC *funcs)
{
ModuleImportFunctions(funcs);
ModuleShellCommandID[0] = shell_register_command(ata_probedevices,"ataprobe");
ModuleShellCommandID[1] = shell_register_command(ata_bootsect,"atambr");
ModuleShellCommandID[2] = shell_register_command(fat32_readdir,"fat32dir");
irq_register_handler(14,ata_irqhandler);
irq_register_handler(15,ata_irqhandler);
ata_irq[0] = 0;
ata_irq[1] = 0;
return (void*)&ModuleID;
}
int ModuleFini()
{
int i;
for( i=0; i<3; i++ )
shell_unregister_command(ModuleShellCommandID[i]);
return NEXOS_MOD_SUCCESS;
}
int ata_probedevices(int argc, char *argv[])
{
int timeout;
char status;
char sector[512];
char model[41];
char serial[21];
char revision[9];
ATA_DRIVE drv;
kmemset(model,0,41);
kmemset(serial,0,21);
kmemset(revision,0,9);
/* probes devices */
kprintf("Probing devices ... please wait ...\n");
/* timeout after 10 sec */
timeout = multitask_get_ticks() + 10000;
/* wait until controller is ready */
while ((status = inb (ATA_PRIM_CONT|ATA_CMD_REG)) != 0x50
&& multitask_get_ticks() < timeout);
if( status == 0x50 )
{
kprintf("Primary controller found ...\n");
/* timeout after 10 sec */
timeout = multitask_get_ticks() + 10000;
/* select drive and send command */
kmemset(sector,0,512);
kmemset(&drv,0,sizeof(ATA_DRIVE));
drv.controller = 0;
drv.drive = 0;
ata_select(&drv);
if( ata_identify(&drv,sector) == ATA_ERR_NONE )
{
kprintf("Master drive found ...\n");
kmemcpy(model,§or[54],40);
kmemcpy(serial,§or[20],20);
kmemcpy(revision,§or[46],8);
kprintf("Model: %s\nSerial: %s\nRevision: %s\n",model,serial,revision);
kprintf("LBA: %s\tDMA: %s\n",
(drv.caps[0] & ATA_CAPS_LBA) ? "Yes" : "No",
(drv.caps[0] & ATA_CAPS_DMA) ? "Yes" : "No");
}
else
{
kprintf("No master drive found!\n");
}
/* timeout after 10 sec */
timeout = multitask_get_ticks() + 10000;
/* select drive and send command */
kmemset(sector,0,512);
kmemset(&drv,0,sizeof(ATA_DRIVE));
drv.controller = 0;
drv.drive = 1;
ata_select(&drv);
if( ata_identify(&drv,sector) == ATA_ERR_NONE )
{
kprintf("Slave drive found ...\n");
kmemcpy(model,§or[54],40);
kmemcpy(serial,§or[20],20);
kmemcpy(revision,§or[46],8);
kprintf("Model: %s\nSerial: %s\nRevision: %s\n",model,serial,revision);
kprintf("LBA: %s\tDMA: %s\n",
(drv.caps[0] & ATA_CAPS_LBA) ? "Yes" : "No",
(drv.caps[0] & ATA_CAPS_DMA) ? "Yes" : "No");
}
else
{
kprintf("No slave drive found!\n");
}
}
else
{
kprintf("No primary controller found!\n");
}
/* try secondary controller */
/* timeout after 10 sec */
timeout = multitask_get_ticks() + 10000;
/* wait until controller is ready */
while ((status = inb (0x177)) != 0x50 && multitask_get_ticks() < timeout);
if( status == 0x50 )
{
kprintf("Secondary controller found ...\n");
/* timeout after 10 sec */
timeout = multitask_get_ticks() + 10000;
/* select drive and send command */
kmemset(sector,0,512);
kmemset(&drv,0,sizeof(ATA_DRIVE));
drv.controller = 1;
drv.drive = 0;
ata_select(&drv);
if( ata_identify(&drv,sector) == ATA_ERR_NONE )
{
kprintf("Master drive found ...\n");
kmemcpy(model,§or[54],40);
kmemcpy(serial,§or[20],20);
kmemcpy(revision,§or[46],8);
kprintf("Model: %s\nSerial: %s\nRevision: %s\n",model,serial,revision);
kprintf("LBA: %s\tDMA: %s\n",
(drv.caps[0] & ATA_CAPS_LBA) ? "Yes" : "No",
(drv.caps[0] & ATA_CAPS_DMA) ? "Yes" : "No");
}
else
{
kprintf("No master drive found!\n");
}
/* timeout after 10 sec */
timeout = multitask_get_ticks() + 10000;
/* select drive and send command */
kmemset(sector,0,512);
kmemset(&drv,0,sizeof(ATA_DRIVE));
drv.controller = 1;
drv.drive = 1;
ata_select(&drv);
if( ata_identify(&drv,sector) == ATA_ERR_NONE )
{
kprintf("Slave drive found ...\n");
kmemcpy(model,§or[54],40);
kmemcpy(serial,§or[20],20);
kmemcpy(revision,§or[46],8);
kprintf("Model: %s\nSerial: %s\nRevision: %s\n",model,serial,revision);
kprintf("LBA: %s\tDMA: %s\n",
(drv.caps[0] & ATA_CAPS_LBA) ? "yes" : "no",
(drv.caps[0] & ATA_CAPS_DMA) ? "yes" : "no");
}
else
{
kprintf("No slave drive found!\n");
}
}
else
{
kprintf("No secondary controller found!\n");
}
return NEXOS_MOD_SUCCESS;
}
int ata_bootsect(int argc, char *argv[])
{
if( argc < 3 )
{
kprintf("usage: %s <controller> <drive>\n",argv[0]);
kprintf("Controller: 0-1\tDrive: 0-1\n");
kprintf("example: %s 0 0\nreads bootsector on primary master (MBR)\n",argv[0]);
return 0;
}
if( argv[1][0] < '0' || argv[1][0] > '1' || argv[2][0] < '0' || argv[2][0] > '1' )
{
kprintf("usage: %s <controller> <drive>\n",argv[0]);
kprintf("Controller: 0-1\tDrive: 0-1\n");
kprintf("example: %s 0 0\nreads bootsector on primary master (MBR)\n",argv[0]);
return 0;
}
ATA_DRIVE drv;
BLOCK blk;
int status;
char sector[512];
MBR *mbr = (MBR*)sector;
int i;
/* load data into struct */
drv.controller = argv[1][0] - 0x30;
drv.drive = argv[2][0] - 0x30;
/* the blk struct uses 64-bit LBA adresses (for future use) */
blk.lownum = 0;
blk.highnum = 0;
blk.len = 1;
blk.buf = sector;
/* select drive and read blocks */
/* we need to identify the drive first to get its capabilities */
ata_select(&drv);
ata_identify(&drv,sector);
if( (status = ata_readblocks(&drv,blk)) == ATA_ERR_NONE )
{
/* print information contained in the bootsector */
/* we assume that sector 1 is the MBR */
for( i=0; i<4; i++ )
{
if( mbr->partitions[i].begcyl +
mbr->partitions[i].begsect +
mbr->partitions[i].beghead != 0 &&
mbr->partitions[i].endcyl +
mbr->partitions[i].endsect +
mbr->partitions[i].endhead != 0 &&
mbr->partitions[i].numsect != 0 )
{
kprintf("Partition %d:\n",i);
kprintf("Bootable: %s\t",
(mbr->partitions[i].bootid == 0x80) ? "yes" : "no");
kprintf("OS-ID: %X (%s)\n",mbr->partitions[i].systid,
ata_map_sysid(mbr->partitions[i].systid));
kprintf("Starting sector: %X\t",mbr->partitions[i].relsect);
kprintf("Number of sectors: %X\t",mbr->partitions[i].numsect);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -