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

📄 main.c

📁 c语言编的网络操作系统。具备网络操作系统基本功能。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
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,&sector[54],40);
            kmemcpy(serial,&sector[20],20);
            kmemcpy(revision,&sector[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,&sector[54],40);
            kmemcpy(serial,&sector[20],20);
            kmemcpy(revision,&sector[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,&sector[54],40);
            kmemcpy(serial,&sector[20],20);
            kmemcpy(revision,&sector[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,&sector[54],40);
            kmemcpy(serial,&sector[20],20);
            kmemcpy(revision,&sector[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 + -