My understanding is that the page table is already specified somewhere in memory, so I just need the page number to get frame number so I can get the physical address. How do i implement the page table so I can look up the frame number?
Given a virtual address
page_number = (virtual >> page_bits);
page_offset = (virtual & page_size);
physical = page_table[page_number] + page_offset;
How is the page table implemented?
Related
I Would like to understand, memory covered at each level by page tables in AARCH64 with 4k granularity.
With 47 bit of VA, One could have level 0 to level 3.
At level 0 there could be one table which describes 512 Level 1 Page tables,
Now each level 1 page table can describes 512 Level 2 page tables and further each level 2 page table can describes 512 Level 3 page tables.
So at level 3 there are 512 page tables of size 4k each and memory covered is 512*4k = 2MB , this is what only one page table of level 2 can cover and if we have 512 such level page tables at level 2 then total memory covered is 512*2MB = 1GB, right ?
Similar way, each table at level 1 points to 512 level 2 page tables( where each level 2 page tale covers 2MB).
So, 512*2MB= 1GB and if we have 512 level 1 page table and total memory covered is 512 GB , right ?
Similar way , Total memory covered at level 0 is 1024 GB, right ?
You seem to have mixed up single page table entries with entire page tables at one point, lost one level somehow and added a bit rather than subtracted it.
Single page: 4'096
Level 3 table: 4096*512 = 2'097'152 = 2MB
Level 2 table: 4096*512*512 = 1'073'741'824 = 1GB
Level 1 table: 4096*512*512*512 = 549'755'813'888 = 512GB
Level 0 table: 4096*512*512*512*512 = 281'474'976'710'656 = 256TB
Note though that the above applies to a 48-bit address. That is, from the address 12 bits are used for the page offset, and 4 times 9 bits each as page table index (12 + 4*9 = 48).
For 47 bits, you simply only have 256 entries in the level 0 table, so you end up with 128TB of addressable memory.
I'm reading the book "Understanding the linux kernel", and this is what it says about the __count field of the page descriptor (struct page) :
_count:
A usage reference counter for the page. If it is set to - 1, the corresponding page
frame is free and can be assigned to any process or to the kernel itself. If it is set
to a value greater than or equal to 0, the page frame is assigned to one or more
processes or is used to store some kernel data structures. The page_count() func-
tion returns the value of the _count field increased by one, that is, the number of
users of the page.
My question is, if the same page is assigned to two processes, can't one process access memory assigned to the other by just decrementing/incrementing the linear address by a value smaller than PAGE_SIZE?
MSDN says here: msdn maximums that max datafile size is "16 Terabytes" - not sure if their definition of terabyte is 1024^4 or 1000^4 - so valid max page number might be 2,147,483,648 (for 1024 basis) or 1,953,125,000 (for 1000 basis) or perhaps something else - does anyone know with certainty?
I have heard that this limit should be increasing with future releases - right now I'm using 2012.
Yes it is based on 1024 which is a kilobyte. Multiply that by 1024 and you get a megabyte. And so on.
Your also correct that newer versions have larger maximums.
The minimum unit required for storing any type of data in SQL Server is a Page, a page is 8 KB in size.i.e exactly 8192 Bytes , pages are stored in logical Extents.
Page Header
Yet not all of the 8192 Bytes is available for data storage, some of the space from 8192 Bytes is used to store information about the page itself. It is called Page Header and it is about 96 Bytes.
Row Set
This is another section on the page containing information about the rows on that page, it begins at the end of the page taking another 36 Bytes from the total page size 8192 Bytes.
Total Space Available for Data Storage
8912 Total space on a page
- 96 Space taken by the page header
- 36 Space taken by the Row set
----------------------------------------------
8060 Total Space Available for Data Storage
So if you are trying to calculate the amount of data you will be able to store in a database and especially when you are talking in Terabytes, dont forget to take Page header and row set into consideration.
When trying to set up virtual memory I'm a bit confused about where to go regarding mapping a given virtual address to a physical address. When working with x86 architecture and using IA-32E mode I have a function to map a new virtual page
int allocate_page(page_table_entry* p)
{
//Get Physical Block for this page table entry to point to
void* phys = getFreeBlock();
//Here I need to map the virtual entry to this physical page frame
}
According to the Intel Manual For a 4 level page table, the first 4 bits of the virtual address should give the Page Directory Table Pointer, the next 9 bits should give the Page Directory, the next 9 bits are used to find the Page Table, and the last 12 bits are used for the offset in the page frame, for a total of 52 bits. Does anybody have any resources or a suggestion of how I can get started implementing the rest of this function so that I can take a given virtual address and map it to a free page frame?
How can we determine the base address of the L2 page table? (Using ARM Cortex-A9)
For example, if I have a programme which requires 7KB of data space and starts at the address 0x0, I need two pages of 4KB.
To do that, I add an entry in the L1 page table which points to the L2 page table base address.
Then I add two entries in the L2 page table like that (with addr = 0x0 for the first page and 0x1000 for the second one)
u32 *ptr;
u32 small_page;
small_page = addr / 0x1000;
ptr = small_page + L2_table_base_addr;
*ptr = (addr & 0xFFFFF) | attributes;
Now there is one thing that I still do not understand.
How can I determine the L2 page table base address? Should I put the table right after the L1 page table?
Where can I store the address? I know that the base address of the L1 page table is stored in a coprocessor register but I did not find any register to store the L2 base address.
Another question to be sure, both coprocessor register TTBR0 and TTBR1 holds the base address of a L1 page. Each to its own. It is not TTBR0 for L1 and TTBR1 for L2, does it ?
I would recommend to read Chapter 9 Memory Management Unit of the Cortex-A Series Programmers Guide. There you will find clear explanation about base address storage. The base address of Level 1 TTB is stored in one of the two base registers (TTRB 0/1 depending upon whether table locates OS code or user process code). These two base registers are helpful while context switching.
The address of the L2 translation table entry that required is calculated by taking the (1KB aligned) base address of the level 2 translation table (given by the level 1 translation table entry) and using 8 bits of the virtual address (bits [19:12]) to index within the 256 entries in the L2 translation table (256 because its 4 byte per index so total bytes are 256*4bytes=1KB).