paging problem

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.
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 »

abuashraf wrote:Hi...
frank wrote:You have to set the user bit(4th bit) on all of the pages that the VM86 task is expected to access.
I've done this

page_table= address | 7 ;

now the page table is user read/write present,also I've done the
same with the first page directory entry,after that my virtual task
worked fine but after executing BIOS int and when tring to go back to pm
using IRET bochs panic this message:

task_switch: CS not valid executable seg


Thanx.


Just as a side note, you have to do the same for the page table's entry too.

Also, these are what I use:

Code: Select all

#define PF_PRESENT		0x1
#define PF_READWRITE	0x2
#define PF_SUPERVISOR	0x0
#define PF_USER			0x4
I had the same problem but I can't remember how I fixed it. Show us your task initialization code.
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Post by xyjamepa »

Hi...

Here's my init_task

Code: Select all

void init_task()
{
 disable();
 memcpy((void *)0x1000,(dword)&task,1000);
 unsigned int i=0;
 for(i;i<max_tasks;i++)
  {
   tss[i].trace=0;
   tss[i].io_map_addr=sizeof(TSS);
   tss[i].ldtr=0;
   if (i) {
   tss[i].fs=tss[i].gs=0;
   tss[i].ds=tss[i].es=0;
   tss[i].ss=0x2000;	
   tss[i].cs=0;
   tss[i].eflags=0x23202L; // VM=1 virtual mode 
   tss[i].esp=0x3000;	   //points to task() stack top
   tss[i].ss0=0x10;
   tss[i].esp0=(dword)&pl0_stack[i];	//stack for kernel
   tss[i].cr3=0x4000;		//page directory
   }
  }

 tss[1].eip=(dword *)0x1000;
 ltr(0x28);
 enable();
}
Also ...

Code: Select all

void init_paging()
{
 
 printf("enabling paging...");

 
 page_directory = 0x4000;
 page_table = 0x5000;

 
 
 dword address=0;
 dword i;
 
 for(i=0;i<1024;i++)
  {
    page_table[i]= address | 7 ; //user ,read/write ,present
    address= address+4096 ;
  }
 
 page_directory[0]= page_table;
 page_directory[0]= page_directory[0] | 7; 
 
 for(i=1;i<1024;i++)
  page_directory[i]= 0 | 2;

 
 write_cr3(page_directory);         // put that page directory address into CR3
 write_cr0(read_cr0() | 0x80000000); // set the paging bit in CR0 to 1
 
 printf("[Done]\n");
 
}
Please note my virtual mode monitor works fine but when I enable paging
I can't go back to pmode,I mean I execute bios int successfuly and after that
bochs panic that message,without paging everything works perfect.

Thanx.
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Post by xyjamepa »

Hi...

I think we're getting closer to solve the problem,
I've changed the page_directory and page_table definition
from dword to unsigned long ....so after executing bios int
and when tring to go back I've got "bad Tss exception".
so here's my tss struct:

Code: Select all

struct tss_t
{
 dword  link,
	esp0,
	ss0,
	esp1,
	ss1,
	esp2,
	ss2,
	cr3,
	eip,
	eflags,
	eax,
	ecx,
	edx,
	ebx,
	esp,
	ebp,
	esi,
	edi,
	es,
	cs,
	ss,
	ds,
	fs,
	gs,
	ldtr;
 word	trace,
	io_map_addr;
	
};

typedef struct tss_t TSS;

#define max_tasks	2

TSS tss[max_tasks];
Thanx.
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 »

Here's the TSS struct I use:

Code: Select all

// tss type
typedef volatile struct __tagTSS_t { 
    unsigned short   link;
    unsigned short   link_h;

    unsigned int   esp0;
    unsigned short   ss0;
    unsigned short   ss0_h;

    unsigned int   esp1;
    unsigned short   ss1;
    unsigned short   ss1_h;

    unsigned int   esp2;
    unsigned short   ss2;
    unsigned short   ss2_h;

    unsigned int   cr3;
    unsigned int   eip;
    unsigned int   eflags;

    unsigned int   eax;
    unsigned int   ecx;
    unsigned int   edx;
    unsigned int    ebx;

    unsigned int   esp;
    unsigned int   ebp;

    unsigned int   esi;
    unsigned int   edi;

    unsigned short   es;
    unsigned short   es_h;

    unsigned short   cs;
    unsigned short   cs_h;

    unsigned short   ss;
    unsigned short   ss_h;

    unsigned short   ds;
    unsigned short   ds_h;

    unsigned short   fs;
    unsigned short   fs_h;

    unsigned short   gs;
    unsigned short   gs_h;

    unsigned short   ldt;
    unsigned short   ldt_h;

    unsigned short   trap;
    unsigned short   iomap;

} __attribute((packed)) TSS_t ;
It looks to be pretty much the same as yours. I'm sorry, I can't help you any more - these waters are pretty much uncharted for me.
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Post by xyjamepa »

No change :( but thanx any way...
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 »

One thing, why is CS 0? When you switch to the next task, are you sure that CS is being restored?

Also,

Code: Select all

tss[i].cr3=0x4000;
Have you got a page directory at 0x4000? If not, you'll get a page fault as there is no valid information to be read (or worse, will write to an unknown location).

I'd suggest that you use the kernel page directory for now. Once you've figured all this out you can then switch back to generating your own. Also - nothing for v86 has to be physically under 1 MB - the virtual addresses must be though.

You might try mapping then the IVT 1:1 and then 0x5000 (or something else) to other physical memory.
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Post by xyjamepa »

Hi...
Have you got a page directory at 0x4000?
Yes


unsigned long *page_directory=(unsigned long *)0x4000;
I'd suggest that you use the kernel page directory for now
I'm using the same page directory for my two tasks,just to make
things simpler.

Could you please debug this IMG for me,may be you'll be more lucky
than me to figuer out what's wrong ...

Thanx.
Attachments
a.tar.gz
IMG
(48.01 KiB) Downloaded 74 times
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 »

Try changing

Code: Select all

 page_directory = 0x4000; 
 page_table = 0x5000; 
To

Code: Select all

 page_directory = (unsigned long*) 0x9C000; 
 page_table = (unsigned long*) 0x9D000; 
They are still under 1 MB (even though they don't need to be) and in a safe location.

One more thing: take a look at my kernel's source (here, syscore/paging.cc and reloc/reloc_elf.cc - the reloc_elf.cc file has an example of loading an ELF image and mapping it.)

One more thing... A page table's entry only addresses 4 kb of physical memory - one page table has 1024 entries which is 4 mb of physical memory. By the looks of it though this shouldn't be your problem.

You should also probably cast all pointers if you want their address. For example:

Code: Select all

unsigned long* pagedir = (unsigned long*) 0x40000;
kprintf( "Page directory location is at 0x%x\n", (unsigned long) pagedir );
I'd do the above code with just the pointer (no cast) and then see if 0x40000 is still printed (not at my development PC so I can't test this for myself).
aflores
Posts: 1
Joined: Tue Mar 04, 2008 7:21 pm

do you have source code for the tutorial?

Post by aflores »

The link to the source is broken, see http://osdev.neopages.net/downloads/tut ... source.zip

I think i'd just like to see how page_table and page_directory are defined.
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 »

Code: Select all

unsigned long* page_directory = (unsigned long*) 0x9c000;
unsigned long* page_table = (unsigned long*) 0x9d000;
I would've though that'd be obvious from the casting in my post, are you sure you know the language well enough to be doing osdev?
Post Reply