Hi,
I am following the OS development tutorial and I am at the Physical Memory Manager section.
I have a query related to the function for allocation a block of memory.
void* pmmngr_alloc_block () {
if (pmmngr_get_free_block_count() <= 0)
return 0; //out of memory
int frame = mmap_first_free ();
if (frame == -1)
return 0; //out of memory
mmap_set (frame);
physical_addr addr = frame * PMMNGR_BLOCK_SIZE;
_mmngr_used_blocks++;
return (void*)addr;
}
I am not understanding how does this return the actual physical address. As far as I understand the value of 'frame' is the number of the first free bit from
the beginning of bitmap. So how does multiplying this value by block size gives the physical address of the block ? It might be a stupid question but my confusion is that in the bitmap only first bit was set to occupied while the kernel itself starts at 1MB. So many more bits should be set. I am not understanding which frame is the first frame in bitmap. Is it the first frame of memory or the first frame after kernel ends? If it is the first frame of memory then the bit(s) corresponding to frame(s) occupied by kernel should also be set. However if it is the first frame starting from the end of kernel then the
above computation doesn't make sense. Please explain.
Please help.
Physical Memory Manger
Moderator:Moderators
-
- Posts:92
- Joined:Thu May 27, 2010 8:54 pm
- Location:Netherlands
Re: Physical Memory Manger
Each bit in the bitmap represents a region of 4KB in memory, so multiplying the bit by the block size (4096) will produce the desired address.vjain20 wrote:As far as I understand the value of 'frame' is the number of the first free bit from
the beginning of bitmap. So how does multiplying this value by block size gives the physical address of the block?
For example, the 32nd bit in the bitmap refers to the 32nd block in memory, which is at address 32 * 4096 = 0x20000.
after initializing the Physical Memory manager, Mike calls the function pmm_deinit_region(start, end).vjain20 wrote:It might be a stupid question but my confusion is that in the bitmap only first bit was set to occupied while the kernel itself starts at 1MB. So many more bits should be set. I am not understanding which frame is the first frame in bitmap. Is it the first frame of memory or the first frame after kernel ends? If it is the first frame of memory then the bit(s) corresponding to frame(s) occupied by kernel should also be set. However if it is the first frame starting from the end of kernel then the
above computation doesn't make sense. Please explain.
What this does is mark the region starting at the address specified by the first argument, until the address specified by the second argument as already in use, thus preventing it from ever being allocated. By specifying the memory region in use by the kernel as the arguments to this function, all necessary bits will be set/unset where needed.
Re: Physical Memory Manger
Thanks a lot! I was wondering about marking the kernel region as occupied. It is not mentioned in the tutorial but it's there in the source
code. There's one more thing I would like to ask. Could you please tell how the kernel size is calculated and why is it multiplied by 512
when passing it to pmm_deinit_region.
code. There's one more thing I would like to ask. Could you please tell how the kernel size is calculated and why is it multiplied by 512
when passing it to pmm_deinit_region.
-
- Posts:92
- Joined:Thu May 27, 2010 8:54 pm
- Location:Netherlands
Re: Physical Memory Manger
When the bootloader is reading the kernel into memory, it does that one sector (512 bytes) at a time.vjain20 wrote:Could you please tell how the kernel size is calculated and why is it multiplied by 512
when passing it to pmm_deinit_region.
It keeps track of the amount of sectors that it read, and passes that value to the kernel in the DX register.
The kernel saves it in the kernelSize variable, and multiplies it by 512 to get the kernel size in bytes.
Re: Physical Memory Manger
Thanks!!halofreak1990 wrote: When the bootloader is reading the kernel into memory, it does that one sector (512 bytes) at a time.
It keeps track of the amount of sectors that it read, and passes that value to the kernel in the DX register.
The kernel saves it in the kernelSize variable, and multiplies it by 512 to get the kernel size in bytes.