i'm trying to setup my floppy driver but my kernel gives an error when i try to access the floppy... i could not find the problem... pls help?
This is the floppy driver(from limonos)
Code: Select all
/*
* los/drivers/floppy/floppy.c
*
* Copyright (C) 2007 Andrew Davis
*/
/* I know, I know, this code is strategically uncommented so google
code searchers can't find errors: HACK FIX ME EXPLOIT !!! */
void set_dma(unsigned char *buff, short size, int read, int channel);
#include <_krnl.h> /* regs_t */
#include <x86.h>
#include <force/floppy3.h>
#include <funcs.h>
#include <string.h> /* memcpy(), memsetw() */
#define DISK_PARAMETER_ADDRESS 0x000FEFC7
#define error 1
int first;
int second;
int current_track = -1;
short base_used;
volatile int irq6_state = 0;
int motor_on = 0;
int sr0 = 0;
char *floppy_types[] =
{
"None.",
"360kB 5.25: Unsupported.",
"1.2MB 5.25: Unsupported.",
"720KB 3.5: Unsupported.",
"1.44MB 3.5.",
"2.88MB 3.5: Unsupported."
};
void get_floppy_type()
{
unsigned char data;
outportb(0x70, 0x10);
data = inportb(0x71);
first = data >> 4;
second = data & 0xF;
}
void irq6_handler(void)
{
irq6_state = 1;
kprintf("\nirq geldi");
}
void wait_irq6()
{
while(irq6_state == 0);
irq6_state = 0;
}
void start_motor()
{
outportb((base_used + 0x2), 0x1C);
delay(2);
motor_on = 1;
}
void stop_motor()
{
outportb((base_used + 0x2), 0x00);
delay(1);
motor_on = 0;
}
/* from intel manual */
void sendbyte(char byte)
{
volatile int msr;
int tmo;
for(tmo = 0; tmo < 128; tmo++)
{
msr = inportb((base_used + 0x04));
if ((msr & 0xC0) == 0x80)
{
outportb((base_used + 0x05), byte);
return;
}
inportb(0x80);
}
}
/* from intel manual */
int getbyte()
{
volatile int msr;
int tmo;
for (tmo = 0; tmo < 128; tmo++)
{
msr = inportb((base_used + 0x04));
if ((msr & 0xd0) == 0xd0)
return inportb((base_used + 0x05));
inportb(0x80);
}
return -1;
}
void waitfdc()
{
kprintf("\nirq bekler");
wait_irq6();
//kprintf("Now Recalibrate(1a)");
sendbyte(0x08);
//kprintf("Now Recalibrate(1b)");
sr0 = getbyte();
//kprintf("Now Recalibrate(1c)");
(void)getbyte();
//kprintf("Now Recalibrate(1d)");
}
int fdc_seek(char track)
{
if(current_track == track)
return 0;
sendbyte(0x0F);
sendbyte(0x00);
sendbyte(track);
delay(1);
waitfdc();
if(sr0 != 0x20)
{
kprintf("\nTrack seek error");
return error;
}
current_track = track;
return 0;
}
void fdc_recalibrate()
{
start_motor();
sendbyte(0x07);
sendbyte(0x00);
waitfdc();
stop_motor();
}
void fdc_reset()
{
outportb((base_used + 0x02), 0); // stop everything
motor_on = 0;
outportb((base_used + 0x04), 0); // data rate (500K/s)
outportb((base_used + 0x02), 0x0C); // restart ints
delay(1);
//kprintf("Now Recalibrate(1)");
waitfdc();
// delay(500);
//kprintf("Now Recalibrate(2)");
sendbyte(0x03); // timing
sendbyte(0xDF); // timing
sendbyte(0x02); // timing
delay(1);
//kprintf("Now Recalibrate()");
while(fdc_seek(1) == error); // set track
fdc_recalibrate();
}
void init_floppy()
{
base_used = 0x3F0;
get_floppy_type();
}
void floppy_ident()
{
kprintf("\nAndrew Davis Floppy Driver initalized\n");
kprintf("_First Floppy: %s\n",floppy_types[first]);
kprintf("_Second Floppy: %s\n",floppy_types[second]);
}
void floppy_read_sectors(unsigned char *buf, int pos, int count)
{
int sec, cyl, head, max_pos = pos + count;
start_motor();
for(; pos < max_pos; pos++)
{
sec = (pos % 18) + 1;
cyl = pos / 36;
head = (pos / 18) % 2;
outportb((base_used + 0x7), 0);
while(fdc_seek((char)cyl) == error);
set_dma(0x00000000, 512, 0, 2);
delay(1);
// if(inportb(base_used + 0x4) != 0x80)
// {
// puts("The DMA bit wasn't set\n");
//// stop_motor();
// return;
// }
sendbyte(0xE6);
sendbyte((unsigned char)head << 2);
sendbyte((unsigned char)cyl);
sendbyte((unsigned char)head);
sendbyte((unsigned char)sec);
sendbyte(0x02);
sendbyte(0x12);
sendbyte(0x1B);
sendbyte(0xFF);
wait_irq6();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
memcpy((unsigned int *)buf, (unsigned int *)0x00000000, 128);
buf += 0x200;
}
stop_motor();
}
void floppy_write_sector(unsigned char *buf, int pos, int read)
{
int sec, cyl, head, stat = error;
sec = (pos % 18) + 1;
cyl = (pos / 18) / 2;
head = cyl % 2;
start_motor();
outportb((base_used + 0x7), 0);
while(stat == error)
stat = fdc_seek((char)cyl);
set_dma(buf, 512, 1, 2);
if(inportb(base_used + 0x4) != 0x80)
{
kprintf("\nThe DMA bit wasn't set");
return;
}
sendbyte(0xC5);
sendbyte((unsigned char)head << 2);
sendbyte((unsigned char)cyl);
sendbyte((unsigned char)head);
sendbyte((unsigned char)sec);
sendbyte(0x02);
sendbyte(0x12);
sendbyte(0x1B);
sendbyte(0xFF);
wait_irq6();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
(void)getbyte();
stop_motor();
}
this is my code to set dma
Code: Select all
/*
* los/drivers/dma/dma.c
*
* Copyright (C) 2005 Andrew Davis
*/
#include <x86.h>
// put in header later
#define LOW_BYTE(x) (x & 0x00FF)
#define HI_BYTE(x) ((x & 0xFF00) >> 8)
// the folowing is a simple look up table for channel and its ports
unsigned char maskport[8] = { 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4 };
unsigned char modeport[8] = { 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6 };
unsigned char clearport[8] = { 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8 };
unsigned char pageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A };
unsigned char addrport[8] = { 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC };
unsigned char countport[8] = { 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE };
// dma xfer for floppy
void set_dma(unsigned char *buff, short size, int read, int channel)
{
char page = 0;
char mode = 0;
short offset = 0;
if(read)
mode = 0x48 + (char)channel;
else
mode = 0x44 + (char)channel;
page = (char)((int)buff >> 16);
offset = (short)((int)buff & 0xFFFF);
size--;
disable();
outportb(maskport[channel], (0x04 | channel)); // mask channel
outportb(clearport[channel], 0x00); // stop trans
outportb(modeport[channel], mode); // type of trans
outportb(addrport[channel], LOW_BYTE(offset)); // send address
outportb(addrport[channel], HI_BYTE(offset)); // send address
outportb(pageport[channel], page); // send page
outportb(countport[channel], LOW_BYTE(size)); // send size
outportb(countport[channel], HI_BYTE(size)); // send size
outportb(maskport[channel], channel); // unmask channel
enable();
}
this is my main.c
Code: Select all
/*============================================================================
MAIN KERNEL CODE
EXPORTS:
void kprintf(const char *fmt, ...);
int main(void);
============================================================================*/
#include <stdarg.h> /* va_list, va_start(), va_end() */
#include <string.h> /* NULL */
#include <x86.h> /* disable() */
#include <_printf.h> /* do_printf() */
#include <grub.h>
#include <stringp.h>
#include <_krnl.h> /* regs_t */
#include <funcs.h>
#include <force/floppy3.h>
//#include <asm/main_asm.h>
//from me
void irq_remap(void);
void floppy_irq();
/* IMPORTS
from KSTART.ASM */
void getvect(vector_t *v, unsigned vect_num);
void setvect(vector_t *v, unsigned vect_num);
//floppydriver.c
void floppy_detect_drives(void);
/* from VIDEO.C */
extern console_t _vc[];
void change_color(int color);
void timer_irq(void);
void putch(unsigned c);
void init_video(void);
/* from KBD.C */
void keyboard_irq(void);
int init_keyboard(void);
/* from SCHED.C */
void schedule(void);
void init_tasks(void);
/* from DEBUG.C */
void dump_regs(regs_t *regs);
/*****************************************************************************
*****************************************************************************/
static int kprintf_help(unsigned c, void **ptr)
{
putch(c);
return 0;
}
/*****************************************************************************
*****************************************************************************/
void kprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
(void)do_printf(fmt, args, kprintf_help, NULL);
va_end(args);
}
/*****************************************************************************
*****************************************************************************/
void panic(const char *fmt, ...)
{
va_list args;
disable(); /* interrupts off */
va_start(args, fmt);
(void)do_printf(fmt, args, kprintf_help, NULL);
while(1)
/* freeze */;
}
/*****************************************************************************
*****************************************************************************/
void floppy_irq()
{
outportb(0x20, 0x20);
}
void fault(regs_t *regs)
{
static const char * const msg[] =
{
"divide error", "debug exception", "NMI", "INT3",
"INTO", "BOUND exception", "invalid opcode", "no coprocessor",
"double fault", "coprocessor segment overrun",
"bad TSS", "segment not present",
"stack fault", "GPF", "page fault", "??",
"coprocessor error", "alignment check", "??", "??",
"??", "??", "??", "??",
"??", "??", "??", "??",
"??", "??", "??", "??",
"IRQ0", "IRQ1", "IRQ2", "IRQ3",
"IRQ4", "IRQ5", "IRQ6", "IRQ7",
"IRQ8", "IRQ9", "IRQ10", "IRQ11",
"IRQ12", "IRQ13", "IRQ14", "IRQ15",
"syscall"
};
/**/
switch(regs->which_int)
{
case 0x20: /* timer IRQ 0 */
timer_irq();
/* reset hardware interrupt at 8259 chip */
outportb(0x20, 0x20);
break;
/* floppy (IRQ 6) */
case 0x26:
irq6_handler();
outportb(0x20, 0x20);
break;
case 0x21:
kprintf("\n Interrupt 0x21");
outportb(0x20, 0x20);
break;
default:
kprintf("Exception #%u", regs->which_int);
if(regs->which_int <= sizeof(msg) / sizeof(msg[0]))
kprintf(" (%s)", msg[regs->which_int]);
kprintf("\n");
dump_regs(regs);
panic("Goodbye (system halted, use reset button to end)");
}
}
/*****************************************************************************
*****************************************************************************/
void irq_remap(void)
{
outportb(0x20, 0x11);
outportb(0xA0, 0x11);
outportb(0x21, 0x20);
outportb(0xA1, 0x28);
outportb(0x21, 0x04);
outportb(0xA1, 0x02);
outportb(0x21, 0x01);
outportb(0xA1, 0x01);
outportb(0x21, 0x0);
outportb(0xA1, 0x0);
}
static void init_8259s(void)
{
//static const unsigned irq0_int = 0x20, irq8_int = 0x28;
/**/
/* Initialization Control Word #1 (ICW1) */
/* ICW2:
route IRQs 0-7 to INTs 20h-27h */
// outportb(0x21, irq0_int);
/* route IRQs 8-15 to INTs 28h-2Fh */
// outportb(0xA1, irq8_int);
/* ICW3 */
// outportb(0x21, 0x04);
// outportb(0xA1, 0x02);
/* ICW4 */
// outportb(0x21, 0x01);
// outportb(0xA1, 0x01);
/* enable IRQ0 (timer) and IRQ1 (keyboard) */
// outportb(0x21, ~0x03);
// outportb(0xA1, ~0x00);
irq_remap();
}
/*****************************************************************************
for MinGW32
*****************************************************************************/
#ifdef __WIN32__
#if __GNUC__<3
#error Do not use MinGW GCC 2.x with NASM
#endif
int __main(void) { return 0; }
void _alloca(void) { }
#endif
/*****************************************************************************
*****************************************************************************/
int main(multiboot_info_t *boot_info)
{
vector_t v;
//vector_t v2;
init_video();
change_color(3);
kprintf("Loading kernel\n");
change_color(7);
kprintf("Boot device:\t\t%d\n",boot_info->boot_device);
kprintf("Memory Map L:\t\t%d\n",boot_info->mmap_length);
kprintf("Memory Map Addr:\t%02X\n",boot_info->mmap_addr);
kprintf("Cmdline:\t\t%s\n",boot_info->cmdline);
kprintf("Memory:\t\t\t%d/%d\n",boot_info->mem_lower,boot_info->mem_upper);
kprintf("Flags:\t\t\t%d/%d\n",boot_info->flags);
v.eip = (unsigned)keyboard_irq;
v.access_byte = 0x8E; /* present, ring 0, '386 interrupt gate */
//v2.eip = (unsigned)irq6_handler;
//v2.access_byte = 0x8E; /* present, ring 0, '386 interrupt gate */
//setvect(&v2, 0x26);
kprintf("Enabling hardware interrupts...\n");
setvect(&v, 0x21);
init_8259s();
init_tasks();
enable();
init_floppy();
fdc_reset();
//Floppy drive detection...
//floppy_detect_drives();
floppy_ident();
if (init_keyboard())
kprintf("Keyboard initalized.\n");
kprintf("Keyboard interrupt handler initalized.\n");
/* we don't save the old vector */
unsigned char fbuff[2048] = " ";
floppy_read_sectors(fbuff,1, 1);
//kprintf("%d\n",floppy_read_track(1,1));
console_start("root");
/* idle task/thread */
while(1)
{
schedule();
}
return 0;
}