OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:33 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 59 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: Multitasking problem
PostPosted: Tue Jul 26, 2022 2:55 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Hello this post not about multitasking, but about paging.
The problem is: if i manually fill the page table for framebuffer it's works fine, but if i use the mapping function i got #PF
My mapping function:
Code:
void vmm_map(int *ptable,int phys,int virt) {
  write_serialString("I got: ");
  write_serialHex((int)ptable);
  write_serialString("\r\n");
  ptable[PAGE_TABLE_INDEX(virt)] = (phys) | 0x7;
  // update pointer
}

#GP info:
Code:
Page fault at 0xfd0f0000
Detailed info: Present: 1
RW: 0
User page: 0
Fetch: 0

What i do wrong?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Tue Jul 26, 2022 3:06 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
It's impossible to say what's wrong from just that code.

What kind of debugging have you done? Have you checked the contents of your page tables? (Try "info tlb" and "info mem" in the QEMU console.)


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Tue Jul 26, 2022 3:16 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Octocontrabass wrote:
It's impossible to say what's wrong from just that code.

What kind of debugging have you done? Have you checked the contents of your page tables? (Try "info tlb" and "info mem" in the QEMU console.)

Yeah i checked the content, by unknown to me reason it's no record about memory regions that i trying to map
"info tab" in bochs:
Code:
0x0000000000000000-0x00000000003fffff -> 0x000000000000-0x0000003fffff
0x00000000c0000000-0x00000000c03fffff -> 0x000000100000-0x0000004fffff

Also it's how i do the mapping:
Code:
int *fr = vmm_createTable(terminal_getBufferAddress());
   for (int i = terminal_getBufferAddress(); i < (terminal_getBufferAddress()+terminal_getBufferSize())+4096; i+=4096) {
    vmm_map(fr,i,i);
   }

vmm_createTable:
Code:
int *vmm_createTable(int addr) {
  int entry = current_dir[PAGE_DIRECTORY_INDEX(addr)];
  int *ret = 0;
  if ((entry & 1) != 1) {
    ret = (int *)pmml_alloc(true);
    current_dir[PAGE_DIRECTORY_INDEX(addr)] = ((unsigned int)ret)| 0x7;
  }
  return ret;
}

EDIT: I edited the current_dir to kdirectory, because current_dir setted to 0, but it's not the reason i still have #PF, i checked the memory, and i have strange addresses:
Code:
<bochs:4> info tab
cr3: 0x000000114000
0x0000000000000000-0x00000000003fffff -> 0x000000000000-0x0000003fffff
0x00000000c0000000-0x00000000c03fffff -> 0x000000100000-0x0000004fffff
0x00000000e03dc000-0x00000000e03dcfff -> 0x00001007e000-0x00001007efff
0x00000000e03dd000-0x00000000e03ddfff -> 0x00002007e000-0x00002007efff
0x00000000e03de000-0x00000000e03defff -> 0x00003007e000-0x00003007efff
0x00000000e03df000-0x00000000e03dffff -> 0x00004007e000-0x00004007efff
0x00000000e03e0000-0x00000000e03e0fff -> 0x00005007e000-0x00005007efff
0x00000000e03e1000-0x00000000e03e1fff -> 0x00006007e000-0x00006007efff
0x00000000e03e2000-0x00000000e03e2fff -> 0x00007007e000-0x00007007efff
0x00000000e03e3000-0x00000000e03e3fff -> 0x00008007e000-0x00008007efff
0x00000000e03e4000-0x00000000e03e4fff -> 0x00009007e000-0x00009007efff
0x00000000e03e5000-0x00000000e03e5fff -> 0x0000a007e000-0x0000a007efff
0x00000000e03e6000-0x00000000e03e6fff -> 0x0000b007e000-0x0000b007efff
0x00000000e03e7000-0x00000000e03e7fff -> 0x0000c007e000-0x0000c007efff
0x00000000e03e8000-0x00000000e03e8fff -> 0x0000d007e000-0x0000d007efff
0x00000000e03e9000-0x00000000e03e9fff -> 0x0000e007e000-0x0000e007efff
0x00000000e03ea000-0x00000000e03eafff -> 0x0000f007e000-0x0000f007efff
0x00000000e03eb000-0x00000000e03ebfff -> 0x00000007e000-0x00000007efff
0x00000000e03fc000-0x00000000e03fcfff -> 0x00001007e000-0x00001007efff
0x00000000e03fd000-0x00000000e03fdfff -> 0x00002007e000-0x00002007efff
0x00000000e03fe000-0x00000000e03fefff -> 0x00003007e000-0x00003007efff
0x00000000e03ff000-0x00000000e03fffff -> 0x00004007e000-0x00004007efff



Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Tue Jul 26, 2022 10:22 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
What values did you manually place in the page tables to make it work?

What values are your paging functions placing in the page tables?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Tue Jul 26, 2022 10:58 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1593
WinExperements wrote:
Code:
void vmm_map(int *ptable,int phys,int virt) {
  write_serialString("I got: ");
  write_serialHex((int)ptable);
  write_serialString("\r\n");
  ptable[PAGE_TABLE_INDEX(virt)] = (phys) | 0x7;
  // update pointer
}



That looks wrong because you have at the least two levels of page tables. Actually, with the types given here, it can only be 32-bit mode without PAE. So something closer to correct might be:
Code:
void vmm_map(uint32_t *ptable, uint32_t phys, uint32_t virt) {
  ptable += virt >> 22;
  if (!(*ptable & 1))
    *ptable = page_zalloc_or_die() | 7;
  ptable = (uint32_t*)(*ptable & 0xfffff000);
  ptable[(virt >> 12) & 0x3ff] = phys | 7;
}


Still not great, but some crucial improvements: First of all, if you want all those variables to be 32-bit types, make them 32-bit types. "int" can be anything. Even better would be to make dedicated types for physical addresses, which reduces the amount of work you have to do if you ever support PAE.

I am assuming an identity paged system up there. If you do not have that, the line where we move from page directory to page table must be changed accordingly. The page directory only tells you the physical address, and how you map it such that you can access it is for you to know.

Future improvements: You may want to have this function be capable of returning error, so you don't need to panic if you are out of memory. As I said, some more specific types would be great. Maybe don't assume the attributes but get them from parameters (at least whether the actual page at the end is writable or supervisor-only ought to be in there).

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Jul 27, 2022 1:43 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
nullplan wrote:
WinExperements wrote:
Code:
void vmm_map(int *ptable,int phys,int virt) {
  write_serialString("I got: ");
  write_serialHex((int)ptable);
  write_serialString("\r\n");
  ptable[PAGE_TABLE_INDEX(virt)] = (phys) | 0x7;
  // update pointer
}



That looks wrong because you have at the least two levels of page tables. Actually, with the types given here, it can only be 32-bit mode without PAE. So something closer to correct might be:
Code:
void vmm_map(uint32_t *ptable, uint32_t phys, uint32_t virt) {
  ptable += virt >> 22;
  if (!(*ptable & 1))
    *ptable = page_zalloc_or_die() | 7;
  ptable = (uint32_t*)(*ptable & 0xfffff000);
  ptable[(virt >> 12) & 0x3ff] = phys | 7;
}


Still not great, but some crucial improvements: First of all, if you want all those variables to be 32-bit types, make them 32-bit types. "int" can be anything. Even better would be to make dedicated types for physical addresses, which reduces the amount of work you have to do if you ever support PAE.

I am assuming an identity paged system up there. If you do not have that, the line where we move from page directory to page table must be changed accordingly. The page directory only tells you the physical address, and how you map it such that you can access it is for you to know.

Future improvements: You may want to have this function be capable of returning error, so you don't need to panic if you are out of memory. As I said, some more specific types would be great. Maybe don't assume the attributes but get them from parameters (at least whether the actual page at the end is writable or supervisor-only ought to be in there).

I write something like you post, but still i receive the #PF, can be that i incorrectly allocated the page table?
And it's how i manually fill the page table:
Code:
for (int i = terminal_getBufferAddress(); i < (terminal_getBufferAddress()+terminal_getBufferSize())+4096; i+=4096) {
    fr_pdir[PAGE_TABLE_INDEX(i)] = (i) | 7;
   }
   kdirectory[PAGE_DIRECTORY_INDEX(terminal_getBufferAddress())] = ((unsigned int)fr_pdir) | 7;

Defines and macroses used:
Code:
int fr_pdir[1024] __attribute__((aligned(4096))); // framebuffer
#define PAGE_DIRECTORY_INDEX(x) (((x) >> 22) & 0x3ff)
#define PAGE_TABLE_INDEX(x) (((x) >> 12) & 0x3ff)

EDIT: If i trying to use allocated page table and use it for manual filling it shows me the #PF, it seems like problem in my page allocator or no?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Jul 27, 2022 2:37 am 
Offline
Member
Member

Joined: Mon Dec 07, 2020 8:09 am
Posts: 212
One way to debug paging issues is to use this command in Qemu right after you've loaded CR3.

Quote:
gva2gpa addr

Print the guest physical address at which the guest’s virtual address addr is mapped based on the mapping for the current CPU.


If it prints 'Unmapped' or unexpected physical addresses, you'd know that something is wrong with the tables.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Jul 27, 2022 3:12 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
xeyes wrote:
One way to debug paging issues is to use this command in Qemu right after you've loaded CR3.

Quote:
gva2gpa addr

Print the guest physical address at which the guest’s virtual address addr is mapped based on the mapping for the current CPU.


If it prints 'Unmapped' or unexpected physical addresses, you'd know that something is wrong with the tables.

I found that if i don't use align attribute it's shows me #PF, it's works only if a add the align attribute.
And about this command it's shows me that that some addresses of framebuffer are unmapped
Do i need to add aligned allocation in my allocator?
EDIT: Yeah the problem in my table allocation, how i can do aligned allocation using page frame allocator?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Jul 27, 2022 10:52 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
WinExperements wrote:
EDIT: Yeah the problem in my table allocation, how i can do aligned allocation using page frame allocator?

Page frames are always aligned. If your allocator returns addresses that aren't aligned, your allocator is broken.

How does your allocator track free page frames?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Jul 27, 2022 11:01 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Octocontrabass wrote:
WinExperements wrote:
EDIT: Yeah the problem in my table allocation, how i can do aligned allocation using page frame allocator?

Page frames are always aligned. If your allocator returns addresses that aren't aligned, your allocator is broken.

How does your allocator track free page frames?

My allocator used bitmap for tracking pages. How i can check if address aligned?
Here how allocator allocate/freeing page, maybe you can found any bug here:
Code:
void *pmml_alloc(bool clear) {
   // found free block, if not panic
   uint64_t freeBlock = -1;
   for (int i = 0; i < max_blocks; i++) {
      if (!is_block_used(i)) {
         freeBlock = i;
         break;
      }
   }
   if (freeBlock == -1) {
      PANIC("Out of memory");
   }
   used_blocks++;
   set_block_used(freeBlock,true);
   void *addr = (void *)(mem_start + (freeBlock*PHYS_PAGE_SIZE));
   if (clear) {
      memset(addr,0,4096);
   }
   return addr;
}
int pmml_free(void *addr)
{
   int index = (int)(addr-mem_start)/PHYS_PAGE_SIZE;
   if (!is_block_used(index)) {
      printf("pmml_free: given address are not allocated\n");
      return false;
   }
   set_block_used(index,false);
   memset(addr,0,4096);
   if (is_block_used(index))
      PANIC("Free, bitmap set fail");
   return true;
}


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Jul 27, 2022 11:17 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
WinExperements wrote:
My allocator used bitmap for tracking pages.

How do you calculate the page frame address from the bit location?

WinExperements wrote:
How i can check if address aligned?

For 4kB alignment, the lowest 12 bits of the address are zero.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Wed Jul 27, 2022 12:56 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Octocontrabass wrote:
WinExperements wrote:
My allocator used bitmap for tracking pages.

How do you calculate the page frame address from the bit location?

WinExperements wrote:
How i can check if address aligned?

For 4kB alignment, the lowest 12 bits of the address are zero.

I re-check the allocation method and found that allocator return's address of reserved page, so i fixed that by marking reserved pages as used. And it's works. Thanks.


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Mon Aug 01, 2022 4:41 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Hello i have new problem, when my user program trying to use syscall i got PF with address 0xff0ff, what i do wrong?
There are my user program:
Code:
void module_main();
char *message = "HHELLLOOOO\n";
void _start() {
   module_main();
}
void module_main() {
   int res;
   int num = 1;
   asm volatile("int $0x80" : "=a" (res) : "0" (num), "b" ((int)message));
   for (;;) {}
}

This program starts at 0x400000


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Mon Aug 01, 2022 4:51 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
What are the CS:EIP, EFLAGS, and error code pushed on the stack by the CPU? What are the contents of the other registers upon entry to your #PF handler?


Top
 Profile  
 
 Post subject: Re: Multitasking problem
PostPosted: Tue Aug 02, 2022 2:13 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Octocontrabass wrote:
What are the CS:EIP, EFLAGS, and error code pushed on the stack by the CPU? What are the contents of the other registers upon entry to your #PF handler?

I have the QEMU log about exception:
Code:
51: v=80 e=0000 i=1 cpl=3 IP=001b:00400033 pc=00400033 SP=0023:0020e3f0 env->regs[R_EAX]=00000001
EAX=00000001 EBX=00ff00ff ECX=00000000 EDX=00ff00ff
ESI=00000000 EDI=00000000 EBP=0020e3f4 ESP=0020e3f0
EIP=00400033 EFL=00000282 [--S----] CPL=3 II=0 A20=1 SMM=0 HLT=0
ES =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
CS =001b 00000000 ffffffff 00cffa00 DPL=3 CS32 [-R-]
SS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
DS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
FS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
GS =0023 00000000 ffffffff 00cff300 DPL=3 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =002b 00111080 00000068 0000e900 DPL=3 TSS32-avl
GDT=     00111040 0000002f
IDT=     00111120 000007ff
CR0=80000011 CR2=00000000 CR3=00206000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=fffffffe CCO=DECL
EFER=0000000000000000
check_exception old: 0xffffffff new 0xe
    52: v=0e e=0000 i=0 cpl=0 IP=0008:001006ae pc=001006ae SP=0010:0020ef50 CR2=00ff00ff
EAX=00ff00ff EBX=00ff00ff ECX=00000000 EDX=00000020
ESI=00000000 EDI=00000000 EBP=0020ef68 ESP=0020ef50
EIP=001006ae EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =002b 00111080 00000068 0000e900 DPL=3 TSS32-avl
GDT=     00111040 0000002f
IDT=     00111120 000007ff
CR0=80000011 CR2=00ff00ff CR3=00206000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000018 CCD=0020ef50 CCO=SUBL
EFER=0000000000000000

And by there logs i can say that syscalls works fine, can that the message are unmapped?
Yeah i thing that message are unmapped because i see that address of message passed to syscall handler are the same that fault address, can be the problem in my incorrect ELF loading?
EDIT: The problem caused by the incorrect linking, and linker cannot find the entry point, i fixed that by editing entry point name in linker script.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 59 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], SemrushBot [Bot] and 66 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group