Maybe a Stupid Question

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

Re:Maybe a Stupid Question

Post by ich_will »

k srry, was my mistake, i've changed something in the code for testing and have forgotten to rechange it.
ich_will

Re:Maybe a Stupid Question

Post by ich_will »

but even though i get no page fault :-(

EDIT:

i also tried:
asm volatile("invlpg %0" :: "m"(PAGE_TABLES));

but i doesn't understand inline assembler of gcc so i can't say anything about it.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Maybe a Stupid Question

Post by Pype.Clicker »

with GCC, the appropriate rule is in http://www.osdev.org/osfaq2/index.php/S ... eFunctions

note that you don't pass the address of some table entry, but instead a memory reference that would have used that page entry. For instance if you just cleared entry #3 in page #4 with a 0-based data segment, you should have

Code: Select all

  pgFlushOneTLB((void*)(3*4096+4*4096*1024));
ich_will

Re:Maybe a Stupid Question

Post by ich_will »

that means if I have 1:1 PageMapping i can use this address of PAGE_TABLE or?

--> pgFlushOneTLB((void*)(3*4096+4*4096*1024));
means PAGE_DIR_ENTRY 4 --> PAGE 3 or?

but isn't there the base address of the page dir needed?

pgFlushOneTLB((void*)((3*4096+4*4096*1024) + base));

else that means to me:

pgFlushOneTLB((void*)( ( ((unsigned long)&PAGE_TABLE) + ((unsigned long)&PAGE_DIRECTORY[DIR_WHERE_THE_PAGE_IS_IN]) ) - ((unsigned long)PAGE_DIRECTORY) );
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Maybe a Stupid Question

Post by Pype.Clicker »

let's state it in another way: if you wish to disable access to virtual address X, you must
1. locate page table entry for X and clear the present bit
2. pgFlushOneTlb(X)
ich_will

Re:Maybe a Stupid Question

Post by ich_will »

in my case that means simply (i have mapped pages 1:1 and a zero based cs):

unsigned long virtual_address = CLR_L12_BITS(PAGE_TABLES);

CLR_L12_BITS == f.e. (PAGE_TABLES | 0xFFF) ^ 0xFFF

_invlpg(virtual_address);

or missunderstood i everything?

With X you mean the virtual address a page is assigned to, or?
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Maybe a Stupid Question

Post by distantvoices »

aha ... so this would mean:I have a virtual address range 0xa0000000 - 0xa0001fff, and I want to clear it and get rid of the first 4 kb, then I'd issue something like this, provided that the pages are actually mapped in:

Code: Select all

  PTE(0xa0000000)&=~PRESENT_BIT;
  //or PTE(0xa0000000)=0;
  //and then - pseudocode:
  invlpg 0xa0000000 
 
Hm ... one shouldna do complicated stuff when low on coffee
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
ich_will

Re:Maybe a Stupid Question

Post by ich_will »

srry, but thats what i do above except:

Code: Select all

PTE(0xa0000000)&=~PRESENT_BIT; <-- is done before
  //or PTE(0xa0000000)=0;
  //and then - pseudocode:
  invlpg 0xa0000000                        <-- _invlpg(CLR_L12_BITS(PAGE_TABLES[i])); = some thing like this except that it calls: invlpg [ X ]
so X is the same as CLR_L12_BITS(PAGE_TABLES)

or am I wrong, tell me were is the problem?
I try to explain what i have to do/i do:

1. I've to set the PRESENT_BIT of the Page Entry with the address X to 0.:

Code: Select all

   PTE(0xa0000000)&=~PRESENT_BIT;
or

Code: Select all

  PAGE_TABLES[i] =  (PAGE_TABLES[i] | 0x1) ^ 0x1;

I think its both the same thing.

2. I've to call invlpg the following way:

Code: Select all

  invlpg [ X ] <-- i do it this way
should i do ?

Code: Select all

  invlpg X
That's all, but it doesn't work. have I understood it wrong? ok than explain it to me one's again --> say me explicitly where you think I do something wrong, please.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Maybe a Stupid Question

Post by distantvoices »

please put your code pieces in [ code ] [ / code ], so that we can read it ;-). Then we shall look further.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
ich_will

Re:Maybe a Stupid Question

Post by ich_will »

Code: Select all

[GLOBAL __invlpg]
...

__invlpg:
        push ebp
        mov ebp, esp
        push ebx

        mov ebx, [ebp + 8]???; page_dir
        invlpg [ebx]            ; Invalidate Translation Look-Aside Buffer Entry: WARNING 486+ only

        pop ebx
        pop ebp
        ret

Code: Select all

unsigned int paging_set_pages(unsigned long from_addr, unsigned long to_addr, unsigned short flags)
{
  unsigned long i, limit;
  // round addresses
  from_addr = MAKE_4K_ALIGN_DOWN(from_addr);
  to_addr  = MAKE_4K_ALIGN_DOWN(to_addr);
  
  if(from_addr > to_addr || VIRTUAL_ADDRESS_TO_PAGE_INDEX(to_addr) > glb_pages_count)
  {
    puts("\tpaging_set_pages: invalid address range");
    return to_addr;
  }
  
  for(i = VIRTUAL_ADDRESS_TO_PAGE_INDEX(from_addr),
      limit = VIRTUAL_ADDRESS_TO_PAGE_INDEX(to_addr); i <= limit; i++)
  {
    PAGE_TABLES[i] = CLR_L12_BITS(PAGE_TABLES[i]);
    PAGE_TABLES[i] |= (flags ^ CLR_L12_BITS(flags));
    _invlpg(CLR_L12_BITS(PAGE_TABLES[i]));
  }
  
  PAGE_DIRECTORY[i/PAGES_PER_DIR] = CLR_L12_BITS(PAGE_DIRECTORY[i/PAGES_PER_DIR]);
  PAGE_DIRECTORY[i/PAGES_PER_DIR] |= flags|PAGE_FLAG_PRESENT; // <--this is only for this time, later i will check if any page in the directory is present, and if not, i will disable the dir
  
  return 0;
}

Code: Select all

#define CLR_L12_BITS(VALUE) ((((unsigned long)VALUE)|0xFFF) ^ 0xFFF)

Code: Select all

#define VIRTUAL_ADDRESS_TO_PAGE_INDEX(ADDRESS) (MAKE_4K_ALIGN_DOWN((unsigned long)ADDRESS)/4096)

Code: Select all

#define MAKE_4K_ALIGN_DOWN(NUM) ( MAKE_ALIGN_DOWN(NUM,4096) )

Code: Select all

#define MAKE_ALIGN_DOWN(NUM, ALIGN) (((unsigned long)NUM) - (((unsigned long)NUM) % ALIGN))
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Maybe a Stupid Question

Post by distantvoices »

Hm. I'd rather shove a VIRTUAL address to invlpg - as Pype has stated (didn't know this detail nor read about it in the googled info), and not a page table entry.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Maybe a Stupid Question

Post by distantvoices »

Have you got the knack?
does it work?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
ich_will

Re:Maybe a Stupid Question

Post by ich_will »

srry, no, bochs doesn't restart anymore, but there is no page fault, though they have one to be
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Maybe a Stupid Question

Post by Pype.Clicker »

ich_will wrote:

Code: Select all

  for(i = VIRTUAL_ADDRESS_TO_PAGE_INDEX(from_addr),
      limit = VIRTUAL_ADDRESS_TO_PAGE_INDEX(to_addr); i <= limit; i++)
  {
    PAGE_TABLES[i] = CLR_L12_BITS(PAGE_TABLES[i]);
    PAGE_TABLES[i] |= (flags ^ CLR_L12_BITS(flags));
    _invlpg(CLR_L12_BITS(PAGE_TABLES[i]));
  }
  
Your data segment is zero-based, right ? in that case, "from_addr" is your virtual address while CLR_L12_BITS(PAGE_TABLE)) is a page frame number...

I suggest you use

Code: Select all

_invlpg(from_addr + i*4096);
or something equivalent ...

(yeah, i know: that's something nasty)
ich_will

Re:Maybe a Stupid Question

Post by ich_will »

Yes my data segment is zero-based and from address and

Code: Select all

CLR_L12_BITS(PAGE_TABLES[0])
is the same

k, here a few debug infos:

System Memory: 128MB
PAGE_DIRECTORY: 0x207000 to 0x208000
PAGE_TABLES: 0x208000 to 0x228000
Global page count: 32768
Initialize the memory manager
memblocks are stored at: 0x228000 to 0x616BF0
and map memory from: 0x617000 to 0x83EEE00
--> memblocks are for the mmanager.

The first address which is returned from kmalloc is 0x617000 this is the same than the physical-address 0x617000 (pages are mapped 1:1).

f.e. if the page with the virtual_address 0x617000 is set (page-index 1559):

from_addr + i*4096 is 0xC30000
0x617000 + 1559*4096 --> 0xC30000 (you shouldn't use this address for invlpg, i think)

CLR_L12_BITS(PAGE_TABLES) is 0x617000

and it doesn't work ???
Post Reply