Page 2 of 2
Posted: Tue Jul 24, 2007 1:45 am
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.
Posted: Tue Jul 24, 2007 9:09 am
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.
Posted: Tue Jul 24, 2007 6:31 pm
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.
Posted: Tue Jul 24, 2007 6:53 pm
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.
Posted: Tue Jul 24, 2007 7:58 pm
by xyjamepa
No change
but thanx any way...
Posted: Tue Jul 24, 2007 9:21 pm
by pcmattman
One thing, why is CS 0? When you switch to the next task, are you sure that CS is being restored?
Also,
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.
Posted: Wed Jul 25, 2007 4:06 pm
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.
Posted: Wed Jul 25, 2007 10:50 pm
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).
do you have source code for the tutorial?
Posted: Tue Mar 04, 2008 7:25 pm
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.
Posted: Wed Mar 05, 2008 1:02 am
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?