how to:hard disk I/O and file system

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.
User avatar
hegde1997
Member
Member
Posts: 40
Joined: Mon Jan 30, 2012 7:36 am
Location: Bangalore, India
Contact:

how to:hard disk I/O and file system

Post by hegde1997 »

Hello everyone,

My os is still in very primitive stage. It hasn't gone beyond idt and gdt. I simply have no idea about IO with hard disk. However i can't use the BIOS interrupts and also want to do on my own but know very very less. Can i get some help?

1)I want to do hard disk IO may not be at this stage but a little while later. But i have no idea how to do IO with hdds. To be more specific i don't know how to detect a hard disk that is already connected to the computer and connect to it and read some sectors. What connect i mean to say is to exchange data or such sorts so that i can send commands it can receive them.

2)In OSDev wiki i read about NTFS where there was a table that tells the contents of bootsector in NTFS file system. Boot sector only contains the bootloader right, the 512 bytes one with boot signature right?
Walking my way in making my OS
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: how to:hard disk I/O and file system

Post by Nessphoro »

Hi,

Most of your questions have already been answered, so in the future we( the community) would appreciate if you wouldn't ask redundant questions.
As to the answers:

1: ATA PIO Mode or LBA HDD Access via PIO

2: As a rule of thumb, proprietary file systems (NTFS) are not used is OS development as they lack documentation on their inner workings, so IMO you should start out with something like FAT32. Hard Drive boot sectors, for the most part at least, contain the partition information along with the Stage 1 boot loader. Special care should be taken when overwriting.

With best regards,

Ness.
User avatar
hegde1997
Member
Member
Posts: 40
Joined: Mon Jan 30, 2012 7:36 am
Location: Bangalore, India
Contact:

Re: how to:hard disk I/O and file system

Post by hegde1997 »

thank you so much.
Walking my way in making my OS
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: how to:hard disk I/O and file system

Post by Nessphoro »

You welcome.
User avatar
hegde1997
Member
Member
Posts: 40
Joined: Mon Jan 30, 2012 7:36 am
Location: Bangalore, India
Contact:

irq problem

Post by hegde1997 »

i am not being able to receive any irqs own my own unless i do asm volatile("int $<int_no>");
I have remapped the irqs 0-15 to 32-47 as told in many places.

1)Now the thing is that until i make an software int from my kernel, the keyboard handler or PIT handler never gets called and after i call int 32 or 33 both kbd and timer start working. When i make a software interrupt which is 32 or above i start getting general protection fault :(

2)One more thing is that my OS restarts probably due to machine reset at some point of time usually when timer's ticks go around 1000 and i have set frequency of timer as 100hz.
Walking my way in making my OS
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: how to:hard disk I/O and file system

Post by turdus »

hegde1997 wrote:However i can't use the BIOS interrupts and also want to do on my own but know very very less.
You probably are looking for initial ramdisk (or initrd). You can load it with BIOS calls or make grub to load it for you. No need for hdd and interrupt knowledge, just keep in mind that block size is 4096. Later, after you get the required knowledge to write a hdd driver, you can easily put it on that ramdisk (either micro or modular kernel is your choice).
http://wiki.osdev.org/Initrd
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: irq problem

Post by Nessphoro »

hegde1997 wrote:i am not being able to receive any irqs own my own unless i do asm volatile("int $<int_no>");
I have remapped the irqs 0-15 to 32-47 as told in many places.

1)Now the thing is that until i make an software int from my kernel, the keyboard handler or PIT handler never gets called and after i call int 32 or 33 both kbd and timer start working. When i make a software interrupt which is 32 or above i start getting general protection fault :(

2)One more thing is that my OS restarts probably due to machine reset at some point of time usually when timer's ticks go around 1000 and i have set frequency of timer as 100hz.
I Cant Get Interrupts Working
User avatar
hegde1997
Member
Member
Posts: 40
Joined: Mon Jan 30, 2012 7:36 am
Location: Bangalore, India
Contact:

Re: how to:hard disk I/O and file system

Post by hegde1997 »

i visited that page already. there they had told that i will get general protection fault if irqs are outside idt but how can that happen? i have put my irq routines from 32-47 in idt which call interrupt handler present in my C program and then whatever is to be done will be done.

But what about my problem number 2? any idea why there would be restart?
Walking my way in making my OS
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: how to:hard disk I/O and file system

Post by Nessphoro »

Triple fault probably.
Hard to say without any code.
User avatar
hegde1997
Member
Member
Posts: 40
Joined: Mon Jan 30, 2012 7:36 am
Location: Bangalore, India
Contact:

Re: how to:hard disk I/O and file system

Post by hegde1997 »

finally keyboard and timer are working but something wrong.

Getting hell lot of general protection fault. and the os will halt with screen full of text telling general protection fault. if i make the interrupt handling routine not to print the fault messages on screen and proceed with keyboard, i can type and what i typed appears on screen but very soon machine resets :(

any ideas why i'm getting so many general protection fault ?
Walking my way in making my OS
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: how to:hard disk I/O and file system

Post by Nessphoro »

Stack overflow?
Or you're overwriting something important.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: how to:hard disk I/O and file system

Post by Combuster »

hegde1997 wrote:any ideas why i'm getting so many general protection fault ?
Your code is buggy, and you haven't got anything to show.

I have a hunch that simply adding

Code: Select all

-Wall -Wextra -Werror -pedantic
to your compiler arguments will lead to a lot of magical fixes. At the very least it will make gcc much more honest about your actual programming skills, and if you have never seen these switches before, I suggest you brace yourself for the confrontation that follows.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: how to:hard disk I/O and file system

Post by zhiayang »

berkus wrote:Buckle up, Dorothy. We're not in Kansas anymore!
Ahahahahaha.

But on a serious note, any problem that is not solely theoretical needs to be accompanied by some form of code. Let us see how you set up your IDT and interrupts, then we can help. http://wiki.osdev.org/How_To_Ask_Questions
User avatar
hegde1997
Member
Member
Posts: 40
Joined: Mon Jan 30, 2012 7:36 am
Location: Bangalore, India
Contact:

Re: how to:hard disk I/O and file system

Post by hegde1997 »

build.bat

Code: Select all

nasm -f elf -o output/loader.o src/loader.s
nasm -f elf -o output/asm_funcs.o src/io/asm_funcs.asm
i586-elf-gcc -o output/kernel.o -c src/kernel.c -Wall -Wextra -Werror -nostdlib -fno-builtin -nostartfiles -nodefaultlibs 

i586-elf-gcc -o output/keyboard.o -c src/io/keyboard.c -Wall -Wextra -Werror -nostdlib -fno-builtin -nostartfiles -nodefaultlibs
i586-elf-gcc -o output/idt_gdt_isr.o -c src/idt_gdt_isr.c -Wall -Wextra -Werror -nostdlib -fno-builtin -nostartfiles -nodefaultlibs 

cd output
i586-elf-ld -T imp_files/linker.ld -o kernel.bin loader.o kernel.o asm_funcs.o idt_gdt_isr.o keyboard.o
cat imp_files/stage1 imp_files/stage2 imp_files/pad kernel.bin > Manu_OS.img



i have compressed and attached the files too. but have pasted the code which deals with idt, gdt and interrupts
idt_gdt.h

Code: Select all

#include "include/types.h"

struct idt_entry_s{
   uint16 base_low;    // The lower 16 bits of the address to jump to when this interrupt occures: offset 0-15
   uint16 selector;      // Kernel segment selector in IDT
   uint8  zero;          // This must always be zero.
   uint8  flags;    //gate types, atttribute types etc.
   uint16 base_high;   // The upper 16 bits of the address to jump to. offset 16-31
} __attribute__((packed));

typedef struct idt_entry_s idt_entry_t;

struct idt_ptr_s_ {
    uint16 limit;
    uint32 base;     
} __attribute__((packed));
typedef struct idt_ptr_s_ idt_ptr_t;

struct gdt_entry_s
{
   uint16 limit_low;           // The lower 16 bits of the limit.
   uint16 base_low;            // The lower 16 bits of the base.
   uint8  base_middle;         // The next 8 bits of the base.
   uint8  access;              // Access flags, determine what ring this segment can be used in.
   uint8  granularity;         // eg: 4kb means 32 bit opcodes
   uint8  base_high;           // The last 8 bits of the base.
} __attribute__((packed));
typedef struct gdt_entry_s gdt_entry_t;

struct gdt_ptr_s_
{
   uint16 limit;               // The upper 16 bits of all selector limits.
   uint32 base;                // The address of the first gdt_entry_t struct.
}
 __attribute__((packed));
typedef struct gdt_ptr_s_ gdt_ptr_t; 

typedef struct registers_s
{
    unsigned int ds;
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; //for popa
    unsigned int int_no, err_code;
    unsigned int eip, cs, eflags, useresp, ss;
} regs_t; 


#define _colours
#ifdef _colours

/**
00 Black       on Black
01 Blue        on Black
02 Green       on Black
03 Cyan        on Black
04 Red         on Black
05 Magenta     on Black
06 Brown       on Black
07 light Grey        on Black
08 dark Grey        on Black
09 Brt Blue    on Black
0A Brt Green   on Black
0B Brt Cyan    on Black
0C Brt Red     on Black
0D Brt Magenta on Black
0E Brt Yellow  on Black
0F Brt White   on Black
*/
#define _black 0x00
#define _blue 0x01
#define _green 0x02
#define _cyan 0x03
#define _red 0x04
#define _magneta 0x05
#define _brown 0x06
#define _brt_grey 0x07
#define _dark_grey 0x08
#define _brt_blue 0x09
#define _brt_green 0x0A
#define _brt_cyan 0x0B
#define _brt_red 0x0C
#define _brt_magneta 0x0D
#define _brt_yellow 0x0E
#define _brt_white 0x0F

#define _colour(frgd,bckg) ((bckg<<4)|frgd) 
#endif

#define sequence "/" 
#define _sequence '/' //character before the letter in an escape sequence

#define newline sequence"n"
#define htab sequence"t"
#define linefeed sequence"r"
#define bkspace sequence"b"

extern void mprintf(char *fmt,int colour);
extern void print_int(int a, int colour);
extern void print_int_(int a);
extern void secDelay(int secs);
void init_idt_gdt();
void print_regs(regs_t r);
extern uchar in(ushort _port);
extern void out(ushort _port, uchar _data);
#define outb(port,data) out(port,data)
#define outportb(port,data) out(port,data)
#define inb(port) in(port)
#define to_offset(x,y) ((y*80*2)+x)
#define screen_bcg_colour _colour(_brt_white,_black)

#define _keyboard
#define idt_gdt_proto
#define _irqs
#define _isrs
#define _idt
#define _gdt


#ifdef idt_gdt_proto

#ifdef _keyboard 

#ifndef keyboard_internal
extern void irq1_keyb(regs_t regs);
extern void init_keyboard();
#endif

#endif

#ifdef _idt
 typedef void (*isr_t)(regs_t);
 extern void idt_set_1();
 extern void idt_set_2(uint32);
  
 void *memset(void *s,int val,size_t size);
 static void init_idt();
 static void idt_set_gate(uint8 pos,uint32 base,uint16 sel,uint8 flags);
 void interrupt_handler(regs_t regs);
 void isr_handler(regs_t regs);
 void remap_irqs();
 void send_EOI(int num);
 void set_irq_handler(int pos, isr_t handler);
 void set_isr_handler(int pos, isr_t handler);
 
#endif

#ifdef _gdt
 extern void gdt_set_1();
 extern void gdt_set_2(uint32);
 
 void intit_idt_gdt();
 static void init_gdt();
 static void gdt_set_gate(int pos,uint32 base,uint32 limit,uint8 access,uint8 _granularity);
#endif

#define _isrs
#ifdef _isrs

  extern void _isr0();
  extern void _isr1();
  extern void _isr2();
  extern void _isr3();
  extern void _isr4();
  extern void _isr5();
  extern void _isr6();
  extern void _isr7();
  extern void _isr8();
  extern void _isr9();
  extern void _isr10();
  extern void _isr11();
  extern void _isr12();
  extern void _isr13();
  extern void _isr14();
  extern void _isr15();
  extern void _isr16();
  extern void _isr17();
  extern void _isr18();
  extern void _isr19();
  extern void _isr20();
  extern void _isr21();
  extern void _isr22();
  extern void _isr23();
  extern void _isr24();
  extern void _isr25();
  extern void _isr26();
  extern void _isr27();
  extern void _isr28();
  extern void _isr29();
  extern void _isr30();
  extern void _isr31();

#endif
#define _irqs
#ifdef _irqs
  extern void irq_0();
  extern void irq_1();
  extern void irq_2();
  extern void irq_3();
  extern void irq_4();
  extern void irq_5();
  extern void irq_6();
  extern void irq_7();
  extern void irq_8();
  extern void irq_9();
  extern void irq_10();
  extern void irq_11();
  extern void irq_12();
  extern void irq_13();
  extern void irq_14();
  extern void irq_15();

#endif

#endif

#define _timer
#ifdef _timer
  extern unsigned long timer_ticks;
  extern int time_cur_pos;
  
  extern void set_cursor_pos(int offset);
  extern void print_long_(unsigned long a);
  static void timer_handler(regs_t regs);
  void timer_handler_();
  void init_timer(uint32 frequency);
  
#endif

idt_gdt.c

Code: Select all

#include "idt_gdt_isr.h"
#define irq0_int 0x20
#define irq8_int 0x28
gdt_entry_t GDT[5];
gdt_ptr_t gdt_ptr;
idt_entry_t IDT[256];
idt_ptr_t idt_ptr;

isr_t ihandlers[16];

void init_idt_gdt()
{
	init_gdt();
	init_idt();
	set_irq_handler(1,irq1_keyb);
}

static void init_gdt()
{
	mprintf(newline " Initiating GDT",screen_bcg_colour);
	gdt_ptr.limit=(sizeof(gdt_entry_t)*5)-1;
	gdt_ptr.base=(uint32)&GDT;
	mprintf(newline htab " setting 0-4 gates of GDT",screen_bcg_colour);
	gdt_set_gate(0, 0, 0, 0, 0);
	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
	gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
	gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
	mprintf(newline htab " successfully set 0-4 gates of GDT",screen_bcg_colour);
	gdt_set_2((uint32)&gdt_ptr);
	mprintf(newline " GDT initialised : 5 entries",screen_bcg_colour);
}

static void gdt_set_gate(int pos,uint32 base,uint32 limit,uint8 access,uint8 _granularity)
{
	GDT[pos].base_low=(base&0xffff);  //first 16 bits
	GDT[pos].base_middle=(base>>16)&0xff; //next 8 bits
	GDT[pos].base_high=(base>>24)&0xff;//last 8 bits
	
	GDT[pos].limit_low=(limit&0xffff);
	GDT[pos].granularity=(limit>>16)&0x0f;
	GDT[pos].granularity|= _granularity&0xf0;
	GDT[pos].access=access;		
}



static void init_idt()
{
	
	mprintf(newline " Initiating IDT",screen_bcg_colour);
	idt_ptr.limit=(sizeof(idt_entry_t)*256)-1;
	idt_ptr.base=(uint32)&IDT;
	
	memset(&IDT,0,sizeof(idt_entry_t)*256);
	mprintf(newline htab " setting 0-31 gates of IDT",screen_bcg_colour);
	idt_set_gate( 0, (uint32)_isr0 , 0x08, 0x8E);
	idt_set_gate( 1, (uint32)_isr1 , 0x08, 0x8E);
	idt_set_gate( 2, (uint32)_isr2 , 0x08, 0x8E);
	idt_set_gate( 3, (uint32)_isr3 , 0x08, 0x8E);
	idt_set_gate( 4, (uint32)_isr4 , 0x08, 0x8E);
	idt_set_gate( 5, (uint32)_isr5 , 0x08, 0x8E);
	idt_set_gate( 6, (uint32)_isr6 , 0x08, 0x8E);
	idt_set_gate( 7, (uint32)_isr7 , 0x08, 0x8E);
	idt_set_gate( 8, (uint32)_isr8 , 0x08, 0x8E);
	idt_set_gate( 9, (uint32)_isr9 , 0x08, 0x8E);
	idt_set_gate( 10, (uint32)_isr10 , 0x08, 0x8E);
	idt_set_gate( 11, (uint32)_isr11 , 0x08, 0x8E);
	idt_set_gate( 12, (uint32)_isr12 , 0x08, 0x8E);
	idt_set_gate( 13, (uint32)_isr13 , 0x08, 0x8E);
	idt_set_gate( 14, (uint32)_isr14 , 0x08, 0x8E);
	idt_set_gate( 15, (uint32)_isr15 , 0x08, 0x8E);
	idt_set_gate( 16, (uint32)_isr16 , 0x08, 0x8E);
	idt_set_gate( 17, (uint32)_isr17 , 0x08, 0x8E);
	idt_set_gate( 18, (uint32)_isr18 , 0x08, 0x8E);
	idt_set_gate( 19, (uint32)_isr19 , 0x08, 0x8E);
	idt_set_gate( 20, (uint32)_isr20 , 0x08, 0x8E);
	idt_set_gate( 21, (uint32)_isr21 , 0x08, 0x8E);
	idt_set_gate( 22, (uint32)_isr22 , 0x08, 0x8E);
	idt_set_gate( 23, (uint32)_isr23 , 0x08, 0x8E);
	idt_set_gate( 24, (uint32)_isr24 , 0x08, 0x8E);
	idt_set_gate( 25, (uint32)_isr25 , 0x08, 0x8E);
	idt_set_gate( 26, (uint32)_isr26 , 0x08, 0x8E);
	idt_set_gate( 27, (uint32)_isr27 , 0x08, 0x8E);
	idt_set_gate( 28, (uint32)_isr28 , 0x08, 0x8E);
	idt_set_gate( 29, (uint32)_isr29 , 0x08, 0x8E);
	idt_set_gate( 30, (uint32)_isr30 , 0x08, 0x8E);
	idt_set_gate( 31, (uint32)_isr31 , 0x08, 0x8E);
    mprintf(newline htab " successfull in setting 0-31 gates of IDT",screen_bcg_colour);
	
	
	mprintf(newline htab " Remapping IRQ 0-15 from 0x0-0xF to 0x20-0x2F",screen_bcg_colour);
	remap_irqs();
	mprintf(newline htab " IRQ remapping successful",screen_bcg_colour);
	
	
	mprintf(newline htab " setting 32-47 gates of IDT",screen_bcg_colour);
	idt_set_gate( 32, (uint32)irq_0 , 0x08, 0x8E);
	idt_set_gate( 33, (uint32)irq_1 , 0x08, 0x8E);
	idt_set_gate( 34, (uint32)irq_2 , 0x08, 0x8E);
	idt_set_gate( 35, (uint32)irq_3 , 0x08, 0x8E);
	idt_set_gate( 36, (uint32)irq_4 , 0x08, 0x8E);
	idt_set_gate( 37, (uint32)irq_5 , 0x08, 0x8E);
	idt_set_gate( 38, (uint32)irq_6 , 0x08, 0x8E);
	idt_set_gate( 39, (uint32)irq_7 , 0x08, 0x8E);
	idt_set_gate( 40, (uint32)irq_8 , 0x08, 0x8E);
	idt_set_gate( 41, (uint32)irq_9 , 0x08, 0x8E);
	idt_set_gate( 42, (uint32)irq_10, 0x08, 0x8E);
	idt_set_gate( 43, (uint32)irq_11, 0x08, 0x8E);
	idt_set_gate( 44, (uint32)irq_12, 0x08, 0x8E);
	idt_set_gate( 45, (uint32)irq_13, 0x08, 0x8E);
	idt_set_gate( 46, (uint32)irq_14, 0x08, 0x8E);
	idt_set_gate( 47, (uint32)irq_15, 0x08, 0x8E);
	mprintf(newline htab " successfull in setting 32-47 gates of IDT",screen_bcg_colour);	
	
	
	idt_set_2((uint32)&idt_ptr);
	mprintf(newline htab " 47 entries done",screen_bcg_colour);
	mprintf(newline htab " 209 null entries done",screen_bcg_colour);
    mprintf(newline " IDT initialised :256 entries done",screen_bcg_colour);
	
}

static void idt_set_gate(uint8 pos,uint32 base,uint16 sel,uint8 flags)
{
	IDT[pos].base_low=base&0xffff;
	IDT[pos].base_high=(base>>16)&0xffff;
	
	IDT[pos].selector=sel;
	IDT[pos].zero=0;
	
	IDT[pos].flags=flags;
}

void remap_irqs()
{
	outportb(0x20, 0x11);
	outportb(0xA0, 0x11);
	outportb(0x21, irq0_int);
	outportb(0xA1, irq8_int);
	outportb(0x21, 0x04);
	outportb(0xA1, 0x02);
	outportb(0x21, 0x01);
	outportb(0xA1, 0x01);
	outportb(0x21, ~0x03);
	outportb(0xA1, ~0x00);
}


void interrupt_handler(regs_t regs)
{
	if(ihandlers[regs.err_code]!=0)// the IRQ number is somehow getting 
	                              // popped into err_code variable  
	{
		isr_t ihandler=ihandlers[regs.err_code];print_long_(regs.err_code);
		ihandler(regs);
	}
	else
	{
		mprintf(" Sorry no handler has been set yet for IRQ ",screen_bcg_colour);
		print_long_(regs.err_code); mprintf(newline,screen_bcg_colour);
		print_regs(regs);
		break;
		
	}

	send_EOI(regs.int_no);
	
}

void print_regs(regs_t r)
{
	mprintf(newline,screen_bcg_colour);
	print_long_(r.ds);mprintf(", ",screen_bcg_colour);
	print_long_(r.edi);mprintf(", ",screen_bcg_colour);
	print_long_(r.esi);mprintf(", ",screen_bcg_colour);
	print_long_(r.ebp);mprintf(", ",screen_bcg_colour);
	print_long_(r.esp);mprintf(", ",screen_bcg_colour);
	print_long_(r.ebx);mprintf(", ",screen_bcg_colour);
	print_long_(r.edx);mprintf(", ",screen_bcg_colour);
	print_long_(r.ecx);mprintf(", ",screen_bcg_colour);
	print_long_(r.eax);mprintf(", ",screen_bcg_colour);
	mprintf(" int_no= ",screen_bcg_colour);
	print_long_(r.int_no);mprintf(", ",screen_bcg_colour);
	print_long_(r.err_code);mprintf(", ",screen_bcg_colour);
	print_long_(r.eip);mprintf(", ",screen_bcg_colour);
	print_long_(r.cs);mprintf(", ",screen_bcg_colour);
	print_long_(r.eflags);mprintf(", ",screen_bcg_colour);
	print_long_(r.useresp);mprintf(", ",screen_bcg_colour);
	print_long_(r.ss);mprintf(", ",screen_bcg_colour);
}
char *isr_faults[]={" Division By Zero",
    "Debug",
    "Non Maskable Interrupt",
    "Breakpoint",
    "Into Detected Overflow",
    "Out of Bounds",
    "Invalid Opcode",
    "No Coprocessor",

    "Double Fault",
    "Coprocessor Segment Overrun",
    "Bad TSS",
    "Segment Not Present",
    "Stack Fault",
    "General Protection Fault",
    "Page Fault",
    "Unknown Interrupt",

    "Coprocessor Fault",
    "Alignment Check",
    "Machine Check",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",

    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved",
    "Reserved"};
    
uint32 fault=0;
void isr_handler(regs_t regs)
{
	
	//print_int(regs.int_no,screen_bcg_colour);
	//mprintf(newline,screen_bcg_colour);
	set_cursor_pos(0);
	mprintf(isr_faults[regs.int_no],screen_bcg_colour);
	//print_regs(regs);
	send_EOI(regs.int_no);
}

void set_irq_handler(int pos, isr_t handler)
{
	ihandlers[pos]=handler;
}
void set_isr_handler(int pos, isr_t handler)
{
	ihandlers[pos]=handler;
}

void send_EOI(int num)
{
	 if(num >= 8)
	  outb(0xA0, 0x20);
	 outb(0x20, 0x20);
}

void *memset(void *s,int val,size_t size)
{
	char *a=(char *)s;
	while(size--)
	 *a++=val;
	return s;
}


#ifdef _timer

static void timer_handler(regs_t regs)
{
	mprintf("",screen_bcg_colour);
	timer_ticks++;
	set_cursor_pos(time_cur_pos);
	print_long_(timer_ticks);
	if(regs.int_no==0)
	{}	
}

void timer_handler_()
{
	mprintf("",screen_bcg_colour);
	timer_ticks++;
	set_cursor_pos(time_cur_pos);
	print_long_(timer_ticks);
}

void init_timer(uint32 frequency)
{
	uint32 divisor; uint8 l,h;
	set_irq_handler(0,timer_handler);
	divisor=1193180/frequency;
	outb(0x43,0x36);	
	l=(uint8)(divisor&0xFF);
	h=(uint8)((divisor>>8)&0xFF);
	outb(0x40,l);
	outb(0x40,h);
}
#endif
asm_funcs.asm

Code: Select all

; external references to the C kernel:
; idt_ptr
; gdt_ptr
; interrupt_handler

[BITS 32]
;======externally referred functions/ global functions=========================
global idt_set_1
global idt_set_2
global gdtflush
global Sum
global gdt_set_1
global gdt_set_2
global isr_h
global irq_h
;==============================================================================

;======external references=====================================================
extern interrupt_handler
extern isr_handler
extern irq1_keyb
extern timer_handler_
extern send_EOI

extern gdt_ptr
extern idt_ptr
;==============================================================================

idt_set_1:
     lidt [idt_ptr]

idt_set_2:
     mov eax,[esp+4]
     lidt [eax]
     ret

gdtflush:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp 0x08:flush2
flush2:
    ret

Sum:
     push    ebp             ; create stack frame
     mov     ebp, esp
     mov     eax, [ebp+8]    ; grab the first argument
     mov     ecx, [ebp+12]   ; grab the second argument
     add     eax, ecx        ; sum the arguments
     mov     ecx, [ebp+16]
     add     eax,ecx
     pop     ebp             ; restore the base pointer
     ret


gdt_set_1:
    lgdt [gdt_ptr]
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp 0x08:flush2_
flush2_:
    ret

gdt_set_2:
     mov eax,[esp+4]
     lgdt [eax]
     mov ax, 0x10
     mov ds, ax
     mov es, ax
     mov fs, ax
     mov gs, ax
     mov ss, ax
     jmp 0x08:flush3
flush3:
     ret

isr_h:
   pusha                    ; push edi,esi,ebp,esp,ebx,edx,ecx,eax

   mov ax, ds               ; Lower 16-bits of eax = ds.
   push eax

   mov ax, 0x10  ;kernel data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   call isr_handler

   pop eax        ;original data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   popa
   add esp, 8
   sti
   iret

irq_h:
   pusha                    ; push edi,esi,ebp,esp,ebx,edx,ecx,eax

   mov ax, ds               ; Lower 16-bits of eax = ds.
   push eax

   mov ax, 0x10  ;kernel data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   call interrupt_handler

   pop eax        ;original data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   popa
   add esp, 8
   sti
   iret


;======IRQS====================================================================

;======externally referred functions/ global functions=========================
global irq_0
global irq_1
global irq_2
global irq_3
global irq_4
global irq_5
global irq_6
global irq_7
global irq_8
global irq_9
global irq_10
global irq_11
global irq_12
global irq_13
global irq_14
global irq_15
;==============================================================================
 extern irq1_keyb
extern timer_handler_
;==IRQ routines================================================================

irq_2250:
   cli
   pusha                    ; push edi,esi,ebp,esp,ebx,edx,ecx,eax

   mov ax, ds               ; Lower 16-bits of eax = ds.
   push eax

   mov ax, 0x10  ;kernel data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   call timer_handler_
   push word 0
   call send_EOI
   pop eax        ;original data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   popa
   add esp, 8
   sti
   iret

irq_2251:
   cli
   pusha                    ; push edi,esi,ebp,esp,ebx,edx,ecx,eax

   mov ax, ds               ; Lower 16-bits of eax = ds.
   push eax

   mov ax, 0x10  ;kernel data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   call irq1_keyb
   push word 1
   call send_EOI

   pop eax        ;original data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   popa
   add esp, 8
   sti
   iret



irq_0:
  cli
  push byte 0 ;error
  push byte 0 ;interrupt number
  call irq_h

irq_1:
  cli
  push byte 0 ;error
  push byte 1 ;interrupt number
  call irq_h

irq_2:
  cli
  push byte 0 ;error
  push byte 2 ;interrupt number
  call irq_h

irq_3:
  cli
  push byte 0 ;error
  push byte 3 ;interrupt number
  call irq_h

irq_4:
  cli
  push byte 0 ;error
  push byte 4 ;interrupt number
  call irq_h

irq_5:
  cli
  push byte 0 ;error
  push byte 5 ;interrupt number
  call irq_h

irq_6:
  cli
  push byte 0 ;error
  push byte 6 ;interrupt number
  call irq_h

irq_7:
  cli
  push byte 0 ;error
  push byte 7 ;interrupt number
  call irq_h

irq_8:
  cli
  push byte 0 ;error
  push byte 8 ;interrupt number
  call irq_h

irq_9:
  cli
  push byte 0 ;error
  push byte 9 ;interrupt number
  call irq_h

irq_10:
  cli
  push byte 0  ;error
  push byte 10 ;interrupt number
  call irq_h

irq_11:
  cli
  push byte 0  ;error
  push byte 11 ;interrupt number
  call irq_h

irq_12:
  cli
  push byte 0  ;error
  push byte 12 ;interrupt number
  call irq_h

irq_13:
  cli
  push byte 0  ;error
  push byte 13 ;interrupt number
  call irq_h

irq_14:
  cli
  push byte 0  ;error
  push byte 14 ;interrupt number
  call irq_h

irq_15:
  cli
  push byte 0  ;error
  push byte 15 ;interrupt number
  call irq_h
;==============================================================================
;==============================================================================


;======ISRS====================================================================

;======externally referred functions/ global functions=========================
global _isr0
global _isr1
global _isr2
global _isr3
global _isr4
global _isr5
global _isr6
global _isr7
global _isr8
global _isr9
global _isr10
global _isr11
global _isr12
global _isr13
global _isr14
global _isr15
global _isr16
global _isr17
global _isr18
global _isr19
global _isr20
global _isr21
global _isr22
global _isr23
global _isr24
global _isr25
global _isr26
global _isr27
global _isr28
global _isr29
global _isr30
global _isr31
;==============================================================================
;======fault and exception handlers============================================
;  0: Divide By Zero Exception
_isr0:
    cli
    push byte 0
    push byte 0
    jmp isr_h

;  1: Debug Exception
_isr1:
    cli
    push byte 0
    push byte 1
    jmp isr_h

;  2: Non Maskable Interrupt Exception
_isr2:
    cli
    push byte 0
    push byte 2
    jmp isr_h

;  3: Int 3 Exception
_isr3:
    cli
    push byte 0
    push byte 3
    jmp isr_h

;  4: INTO Exception
_isr4:
    cli
    push byte 0
    push byte 4
    jmp isr_h

;  5: Out of Bounds Exception
_isr5:
    cli
    push byte 0
    push byte 5
    jmp isr_h

;  6: Invalid Opcode Exception
_isr6:
    cli
    push byte 0
    push byte 6
    jmp isr_h

;  7: Coprocessor Not Available Exception
_isr7:
    cli
    push byte 0
    push byte 7
    jmp isr_h

;  8: Double Fault Exception (With Error Code!)
_isr8:
    cli
    push byte 8
    jmp isr_h

;  9: Coprocessor Segment Overrun Exception
_isr9:
    cli
    push byte 0
    push byte 9
    jmp isr_h

; 10: Bad TSS Exception (With Error Code!)
_isr10:
    cli
    push byte 10
    jmp isr_h

; 11: Segment Not Present Exception (With Error Code!)
_isr11:
    cli
    push byte 11
    jmp isr_h

; 12: Stack Fault Exception (With Error Code!)
_isr12:
    cli
    push byte 12
    jmp isr_h

; 13: General Protection Fault Exception (With Error Code!)
_isr13:
    cli
    push byte 13
    jmp isr_h

; 14: Page Fault Exception (With Error Code!)
_isr14:
    cli
    push byte 14
    jmp isr_h

; 15: Reserved Exception
_isr15:
    cli
    push byte 0
    push byte 15
    jmp isr_h

; 16: Floating Point Exception
_isr16:
    cli
    push byte 0
    push byte 16
    jmp isr_h

; 17: Alignment Check Exception
_isr17:
    cli
    push byte 0
    push byte 17
    jmp isr_h

; 18: Machine Check Exception
_isr18:
    cli
    push byte 0
    push byte 18
    jmp isr_h

; 19: Reserved
_isr19:
    cli
    push byte 0
    push byte 19
    jmp isr_h

; 20: Reserved
_isr20:
    cli
    push byte 0
    push byte 20
    jmp isr_h

; 21: Reserved
_isr21:
    cli
    push byte 0
    push byte 21
    jmp isr_h

; 22: Reserved
_isr22:
    cli
    push byte 0
    push byte 22
    jmp isr_h

; 23: Reserved
_isr23:
    cli
    push byte 0
    push byte 23
    jmp isr_h

; 24: Reserved
_isr24:
    cli
    push byte 0
    push byte 24
    jmp isr_h

; 25: Reserved
_isr25:
    cli
    push byte 0
    push byte 25
    jmp isr_h

; 26: Reserved
_isr26:
    cli
    push byte 0
    push byte 26
    jmp isr_h

; 27: Reserved
_isr27:
    cli
    push byte 0
    push byte 27
    jmp isr_h

; 28: Reserved
_isr28:
    cli
    push byte 0
    push byte 28
    jmp isr_h

; 29: Reserved
_isr29:
    cli
    push byte 0
    push byte 29
    jmp isr_h

; 30: Reserved
_isr30:
    cli
    push byte 0
    push byte 30
    jmp isr_h

; 31: Reserved
_isr31:
    cli
    push byte 0
    push byte 31
    jmp isr_h

;==============================================================================
;==============================================================================
Attachments
Manu_OS.tar.gz
(10.4 KiB) Downloaded 114 times
Walking my way in making my OS
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: how to:hard disk I/O and file system

Post by Combuster »

Code: Select all

   push word 1
   call send_EOI
   pop eax         ; eax = 1
   mov ds, ax      ; ds = 1 = null selector
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply