Page 1 of 1

Multitasking and Paging

Posted: Fri Feb 09, 2007 9:47 am
by hunter
Hello all,

i've a big problem ... in my os there is a problem with multitaking ... i have paging on ... if i create a RING0 task all works fine but now i want to create RING3 tasks ... but there is a strange error ... every time i want to create a new RING3 task there is a page fault ... here is the bochsout file ... But if i turned off paging it works and no page fault is show ... i hope somebody could help me ...

Code: Select all

00000000000i[     ] Bochs x86 Emulator 2.1.1
00000000000i[     ]   February 08, 2004
00000000000i[     ] System configuration
00000000000i[     ]   processors: 1
00000000000i[     ]   A20 line support: yes
00000000000i[     ]   APIC support: no
00000000000i[     ] CPU configuration
00000000000i[     ]   level: 5
00000000000i[     ]   fpu support: yes
00000000000i[     ]   paging support: yes, tlb enabled: yes
00000000000i[     ]   mmx support: yes
00000000000i[     ]   sse support: no
00000000000i[     ]   v8086 mode support: yes
00000000000i[     ]   3dnow! support: no
00000000000i[     ]   PAE support: no
00000000000i[     ]   PGE support: no
00000000000i[     ]   PSE support: no
00000000000i[     ]   x86-64 support: no
00000000000i[     ]   SEP support: no
00000000000i[     ] Optimization configuration
00000000000i[     ]   Guest2HostTLB support: yes
00000000000i[     ]   RepeatSpeedups support: yes
00000000000i[     ]   Icache support: yes
00000000000i[     ]   Host Asm support: yes
00000000000i[MEM0 ] allocated memory at 00CC0020. after alignment, vector=00CC1000
00000000000i[MEM0 ] 64,00MB
00000000000i[MEM0 ] rom at 0xf0000/65536 ('BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/29664 ('VGABIOS-lgpl-latest')
00000000000i[CMOS ] Using local time for initial clock
00000000000i[CMOS ] Setting initial clock to: Fri Feb 09 16:52:09 2007 (time0=1171036329)
00000000000i[DMA  ] channel 4 used by cascade
00000000000i[DMA  ] channel 2 used by Floppy Drive
00000000000i[FDD  ] fd0: 'staticos.img' ro=0, h=2,t=80,spt=18
00000000000i[WGUI ] IME disabled
00000000000i[VGA  ] interval=300000
00000000000i[VGA  ] VBE Bochs Display Extension Enabled
00000000000i[     ] init_mem of 'harddrv' plugin device by virtual method
00000000000i[     ] init_mem of 'keyboard' plugin device by virtual method
00000000000i[     ] init_mem of 'serial' plugin device by virtual method
00000000000i[     ] init_mem of 'parallel' plugin device by virtual method
00000000000i[     ] init_mem of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_mem of 'gameport' plugin device by virtual method
00000000000i[     ] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD   ] CD on ata0-1: 'D:\Laptop_Alt\Neue\test.iso'
00000000000i[CD   ] load cdrom with path=D:\Laptop_Alt\Neue\test.iso
00000000000i[CD   ] Opening image file as a cd
00000000000i[CD   ] Using direct access for CDROM
00000000000i[HD   ] Media present in CD-ROM drive
00000000000i[HD   ] Boot device will be 'a'
00000000000i[HD   ] Floppy boot signature check is enabled
00000000000i[     ] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD  ] will paste characters every 1000 keyboard ticks
00000000000i[     ] init_dev of 'serial' plugin device by virtual method
00000000000i[SER  ] com1 at 0x03f8 irq 4
00000000000i[     ] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR  ] parallel port 1 at 0x378 irq 7
00000000000i[     ] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[     ] init_dev of 'gameport' plugin device by virtual method
00000000000i[     ] reset of 'harddrv' plugin device by virtual method
00000000000i[     ] reset of 'keyboard' plugin device by virtual method
00000000000i[     ] reset of 'serial' plugin device by virtual method
00000000000i[     ] reset of 'parallel' plugin device by virtual method
00000000000i[     ] reset of 'extfpuirq' plugin device by virtual method
00000000000i[     ] reset of 'gameport' plugin device by virtual method
00000004325i[BIOS ]  rombios.c,v 1.103.2.2 2004/02/02 22:39:22 cbothamy Exp $
00000318066i[KBD  ] reset-disable command received
00000321865i[VBIOS] VGABios $Id: vgabios.c,v 1.38 2003/11/05 23:21:19 cbothamy Exp $
00000322096i[VGA  ] VBE known Display Interface b0c2
00000322181i[VGA  ] VBE known Display Interface b0c0
00000325126i[VBIOS] VBE Bios $Id: vbe.c,v 1.35 2003/11/03 20:57:01 vruppert Exp $
00000325241i[VGA  ] VBE known Display Interface b0c2
00000527577i[VGA  ] VBE known Display Interface b0c2
00000600000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
00000614487e[HD   ] device set to 0 which does not exist
00001053649i[VGA  ] VBE known Display Interface b0c2
00001171079i[VGA  ] VBE known Display Interface b0c2
00001230875i[VGA  ] VBE known Display Interface b0c2
00001295142i[VGA  ] VBE known Display Interface b0c2
00001359414i[VGA  ] VBE known Display Interface b0c2
00001423700i[VGA  ] VBE known Display Interface b0c2
00001488000i[VGA  ] VBE known Display Interface b0c2
00001552338i[VGA  ] VBE known Display Interface b0c2
00001616660i[VGA  ] VBE known Display Interface b0c2
00001681015i[VGA  ] VBE known Display Interface b0c2
00001745403i[VGA  ] VBE known Display Interface b0c2
00001809736i[VGA  ] VBE known Display Interface b0c2
00001874122i[VGA  ] VBE known Display Interface b0c2
00001938521i[VGA  ] VBE known Display Interface b0c2
00002002872i[VGA  ] VBE known Display Interface b0c2
00002067256i[VGA  ] VBE known Display Interface b0c2
00002131673i[VGA  ] VBE known Display Interface b0c2
00002196094i[VGA  ] VBE known Display Interface b0c2
00002260546i[VGA  ] VBE known Display Interface b0c2
00002329845i[VGA  ] VBE known Display Interface b0c2
00002330949i[VGA  ] VBE known Display Interface b0c2
00002331354i[VGA  ] VBE set xres (1024)
00002331396i[VGA  ] VBE set yres (768)
00002331440i[VGA  ] VBE set bpp (32)
00002331527i[VGA  ] VBE enabling x 1024, y 768, bpp 32, 3145728 bytes visible
00002331527i[WGUI ] dimension update x=1024 y=768 fontheight=0 fontwidth=0 bpp=32

After the Page Fault i turned off Bochs

00369594000p[WGUI ] >>PANIC<< POWER button turned off.
00369594000i[SYS  ] Last time is 1171036698
00369594000i[CPU  ] protected mode
00369594000i[CPU  ] CS.d_b = 32 bit
00369594000i[CPU  ] SS.d_b = 32 bit
00369594000i[CPU  ] | EAX=00000009  EBX=00000000  ECX=00010204  EDX=00000027
00369594000i[CPU  ] | ESP=0073e904  EBP=0073e90c  ESI=00000000  EDI=00000000
00369594000i[CPU  ] | IOPL=3 NV UP DI PL NZ NA PO NC
00369594000i[CPU  ] | SEG selector     base    limit G D
00369594000i[CPU  ] | SEG sltr(index|ti|rpl)     base    limit G D
00369594000i[CPU  ] |  DS:0023( 0004| 0|  3) 00000000 000fffff 1 1
00369594000i[CPU  ] |  ES:0023( 0004| 0|  3) 00000000 000fffff 1 1
00369594000i[CPU  ] |  FS:0023( 0004| 0|  3) 00000000 000fffff 1 1
00369594000i[CPU  ] |  GS:0023( 0004| 0|  3) 00000000 000fffff 1 1
00369594000i[CPU  ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00369594000i[CPU  ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00369594000i[CPU  ] | EIP=00101110 (00101110)
00369594000i[CPU  ] | CR0=0xe0000011 CR1=0x00000000 CR2=0x00109338
00369594000i[CPU  ] | CR3=0x00300000 CR4=0x00000000
00369594000i[     ] restoring default signal behavior
00369594000i[CTRL ] quit_sim called with exit code 1
Hunter

Posted: Fri Feb 09, 2007 11:48 am
by Otter
Could you give some code ? Maybe that for setting up the tss ... does your ring 3 task use the same page directory as your ring 0 task ? If not, is all important mapped into userspace ( idt, gdt, isr code ) ? What happens if you do only a simple loop ( 0xebfe ) in userspace ?

Posted: Fri Feb 09, 2007 12:55 pm
by hunter
Here is the code where the TSS was set:

Code: Select all

void Set_GDT()
{
    gp.limit=6*(sizeof(struct gdt_entry))-1;
    
    
    gp.base = (unsigned int) &gdt;
    set_a_gdt(0, 0, 0, 0, 0);
    set_a_gdt(1, 0x00000000, 0xffffffff, 0x9a, 0xCF);
    set_a_gdt(2, 0x00000000, 0xffffffff, 0x92, 0xCF);
    
    set_a_gdt(3, 0x00000000, 0xffffffff, 0xfa, 0xCF);
    set_a_gdt(4, 0x00000000, 0xffffffff, 0xf2, 0xCF);
    
    set_a_gdt(5, (unsigned long)&sys_tss, 104, 0x89, 0xCF);

    setup_gdt();
}
...

The PageDirectory in Ring0 is 0x300000 ... i print the PageDirectory when the page fault is on screen and it shows 0x2FFEC5 ?!

...
What happens if you do only a simple loop ( 0xebfe ) in userspace ?
The Ring3 task is a simple while(1);

Code: Select all

void testtask( void )
{
	while( 1 );
}
I hope you can help me ... Thanks ...

Hunter

Posted: Fri Feb 09, 2007 1:52 pm
by AJ
Hi,

In your page directory and page table entries, are the 'user' bits set? If not, your ring 3 task will not be able to access these pages - even just to execute a while loop.

Cheers,
Adam

Posted: Fri Feb 09, 2007 1:59 pm
by hunter
I don't know if the user bit is set ... could you give me a example, please ...

Hunter

Posted: Fri Feb 09, 2007 2:08 pm
by AJ
Not really an example, but to give you an idea, I use the following bit definitions:

Code: Select all

#define PAGE_PRESENT 	   0x001
#define	PAGE_WRITE	     0x002
#define PAGE_USER	      0x004
#define PAGE_ACCESSED 	 0x020
#define	PAGE_DIRTY	      0x040
#define PAGE_4MB               0x080
#define PAGE_GLOBAL         0x100
I assume when you add a PTE, for example you do something like:

Code: Select all

PTE = (address to page in) | PAGE_PRESENT | PAGE_WRITE;

//this is the same as
PTE = (address to page in) | 0x03;
Now, if you want to access those same pages (whether they contain code or data) in ring 3, you will have to add the following:

Code: Select all

PTE = (address to page in) | PAGE_PRESENT | PAGE_WRITE | PAGE_USER;

//this is the same as
PTE = (address to page in) | 0x07;
Hope that helps,
Adam

Posted: Fri Feb 09, 2007 2:19 pm
by hunter
Thank you very much AJ ... this was the problem ... thanks thanks thanks ...

Posted: Fri Feb 09, 2007 2:33 pm
by ces_mohab
That what really happened to me.
Page fault error code has a different format from other error codes.
this is a decode for page fault error code:

Code: Select all

enum PAGEF_ERROR_CODE
{
	PEC_P    = 0x00000001 ,
	PEC_RW = 0x00000002 ,
	PEC_US  = 0x00000004 ,
	PEC_RS  = 0x00000008 ,
	PEC_IF   = 0x00000010 ,
} ;

if( error_code & PEC_P )
		printf("page-level protection violation,") ;
	else
		printf("non-present page,") ;
	
	if( error_code & PEC_RW )
		printf("write,") ;
	else
		printf("read,") ;
	
	if( error_code & PEC_US )
		printf( "user mode," ) ;
	else
		printf("supervisor mode,") ;

Posted: Sun Feb 11, 2007 9:48 am
by AJ
hunter wrote:Thank you very much AJ ... this was the problem ... thanks thanks thanks ...
No problem - glad it did the trick!