i need criticism and also help :)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
trash_
Posts: 5
Joined: Mon Jun 20, 2005 11:00 pm

i need criticism and also help :)

Post by trash_ »

hi,
i am a newbie and i am trying to learn osdev. i read many tutorials and now i'm dealing with a tutorial which i downloaded from http://my.execpc.com/~geezer/osd/. i need some help.

first of all, i want to learn floppy drivers. i read all tutorials in this forum but actually i could not apply them into my os trial. i'm stacked... i think my problem is about interrupts. also, i should add that i'm in protected mode.

this is my os, also included a floppy img. pls just look at my os trial and criticize me. am i doing write..?
http://code.google.com/p/froceos/downlo ... z&can=2&q=
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Looks good to me, nicely commented which is useful.
trash_
Posts: 5
Joined: Mon Jun 20, 2005 11:00 pm

Post by trash_ »

JamesM wrote:Looks good to me, nicely commented which is useful.
thanks, did you look at my codes_? (actually maybe %40 of them are mine :), the others are from the osd tutorial...).

i could not import a floppy driver.. can anybody tell me what is missing in my code...?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

I looked at your code. I haven't written a floppy driver, so don't know what could be wrong. I'm also at work, which limits my time. A good idea would be to post your floppy code on the forum, so people can see it without having to download your tarball.

JamesM
trash_
Posts: 5
Joined: Mon Jun 20, 2005 11:00 pm

Post by trash_ »

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;
}
Attachments
the screenshot of the error
the screenshot of the error
ss.png (16.19 KiB) Viewed 1991 times
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

Well it could be a number of things maybe you should use for( ;; ) loops to narrow the problem down. Of the things to look for are problems with your scheduler, stack corruption (make sure fbuff isn't corrupting the stack) and invalid IDT entries. It seems from the error output that somehow you are jumping to 0x00000000 and trying to execute code there until you hit an illegal operation.
trash_
Posts: 5
Joined: Mon Jun 20, 2005 11:00 pm

Post by trash_ »

frank wrote:. It seems from the error output that somehow you are jumping to 0x00000000 and trying to execute code there until you hit an illegal operation.
i'm trying to jmp because in floppy3.c there is a line

Code: Select all

set_dma(0x00000000, 512, 0, 2); 
. is there a problem? maybe my dma.c causes the problem.. it is also attached my previous post. one more thing that i should ask:
frank wrote: (make sure fbuff isn't corrupting the stack)
how can i check my stack?
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

trash_ wrote:
frank wrote:. It seems from the error output that somehow you are jumping to 0x00000000 and trying to execute code there until you hit an illegal operation.
i'm trying to jmp because in floppy3.c there is a line

Code: Select all

set_dma(0x00000000, 512, 0, 2); 
. is there a problem? maybe my dma.c causes the problem.. it is also attached my previous post. one more thing that i should ask:
I was thinking more in terms of your scheduler, try disabling it (if you can) until you figure out the problem. That way you can rule the scheduler out. Also I would make sure that all my IDT entries pointed to valid locations in memory.
trash_ wrote:
frank wrote: (make sure fbuff isn't corrupting the stack)
how can i check my stack?
I would move fbuff to a global variable and see if the problem continues. That way you know that it is not on the stack.
trash_
Posts: 5
Joined: Mon Jun 20, 2005 11:00 pm

Post by trash_ »

i found the problem, very interestingly, the problem was just caused by the definition of the problem. i moved the set_dma function into the floppy3.c then problem ended. i can't understand why that causes a problem.
Avarok
Member
Member
Posts: 102
Joined: Thu Aug 30, 2007 9:09 pm

Post by Avarok »

Glad you found it.

I personally think it's odd that EIP was at address 0x4C. That would have been where I'd have checked first. May I ask how you managed to get a debug output from Qemu?

That would be immensely useful to me.
There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.
- C. A. R. Hoare
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Theres a command line switch that allows GDB to connect to it.
Avarok
Member
Member
Posts: 102
Joined: Thu Aug 30, 2007 9:09 pm

Post by Avarok »

crap, because I'm actually developing it on windows after an emerge --sync && emerge -uD world somehow managed to bugger up some library critical to SciTE and firefox on my Gentoo partition.

I tend to be lazy and just wait for the day these things fix themselves. Usually takes about two weeks, and only has happened 3 or 4 times in a couple years.

Can't complain about it though, 'cause I get the latest software automatically updated and compiled to my system configuration while I sleep (when it *is* working)

: p

~~~~

ooo ooo! Wait!

Doesn't Qemu use the Bochs BIOS image? Doesn't that mean I can use the bochs debugger if I trigger it right?

~~~~

never mind... bloody thing has no good way of dumping the registers when it crashes. : (
There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.
- C. A. R. Hoare
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Get Cygwin, build Bochs with the GDB stub enabled, and then use GDB to debug your kernel (make sure you export debugging information).
Post Reply