Hi, first post. I need a way to retrieve the physical address of a variable, such as an array or struct. I have paging enabled. My first attempt was to use ld to get the physical address of global arrays, then I use that address to cause a page fault, that I resolve. My thought was that I would then have a physical address to use. I'm not sure if that was the case because when I offer that address to a device, the device remains unresponsive. My guess is that my physical address is not a physical address, but maybe an offset?
An example of what I tried would be, let's say array BUFFER is at location 0x01000000. I find that address from ld and I cause a page fault using that address. My fault handler catches it and resolves the fault by mapping it to address 0x9ad000 (for example). I tested the mapping by writing to 0x01000000 and reading from 0x9ad000 and the results are the same. So, shouldn't I be correct to offer the device 0x01000000 after the mapping or am I thinking about this all wrong?
I am really confused. If not using paging, how do I get the physical address of a variable, array, or struct? I could just calc the address, store the address, turn on paging, then map it right? But, how to calc address?
oSDN LO
Physical Memory
Physical Memory
Yes, I see that you have proven it, but my question was, 'How did you know that would work?'.
- thepowersgang
- Member
- Posts: 734
- Joined: Tue Dec 25, 2007 6:03 am
- Libera.chat IRC: thePowersGang
- Location: Perth, Western Australia
- Contact:
Re: Physical Memory
Well, the first thing you could do is use the known physical base of your kernel (where GRUB loaded it) to get the physical base. Or you could write a method that walks the paging structures for you.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Re: Physical Memory
Does this apply for when paging is off? My loader loads the kernel at physical address 0x00100000. Do I use that as a base?thepowersgang wrote:Well, the first thing you could do is use the known physical base of your kernel (where GRUB loaded it) to get the physical base.
So, 0x00100000+&buffer = physical address? Assume that paging is turned off. Thanks.
Yes, I see that you have proven it, but my question was, 'How did you know that would work?'.
- thepowersgang
- Member
- Posts: 734
- Joined: Tue Dec 25, 2007 6:03 am
- Libera.chat IRC: thePowersGang
- Location: Perth, Western Australia
- Contact:
Re: Physical Memory
No, when paging is enabled, your kernel is linked at a certain virtual address (say 0xC0100000), but it is loaded at a physical address (say 0x100000) to get the physical address of a page in the initial kernel binary, you subtract the difference between these values from the address ((uint)&symbol - (0xc0100000 - 0x100000))
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Re: Physical Memory
&buffer = 0x00105000
ADDROF = &buffer
PTE_BASE = 0xC0000000
PHY_BASE = 0x00100000
VRT_BASE = PTE_BASE+PHY_BASE
ADDROF - (VRT_BASE - PHY_BASE) = ?physical? = 0x40105000
Does that look right?
ADDROF = &buffer
PTE_BASE = 0xC0000000
PHY_BASE = 0x00100000
VRT_BASE = PTE_BASE+PHY_BASE
ADDROF - (VRT_BASE - PHY_BASE) = ?physical? = 0x40105000
Does that look right?
Yes, I see that you have proven it, but my question was, 'How did you know that would work?'.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Physical Memory
If you feed in a physical address where a virtual address is expected, it obviously does not work.
You should start with linking your kernel to the virtual address, not the physical address.
You should start with linking your kernel to the virtual address, not the physical address.
Re: Physical Memory
Oh, I see. So, to clarify I should. Map 0x00105000 to 0xC0105000 and the math provided above basically works to strip it back down to 0x00105000 which is the physical address. Is that correct?Combuster wrote:You should start with linking your kernel to the virtual address, not the physical address.
Yes, I see that you have proven it, but my question was, 'How did you know that would work?'.
Re: Physical Memory
I really have no idea if I am doing this right. I know that there is a mapping done between this 0xC0105000 and 0x00105000, because if I do this...
Answer: 0xDEADBEEF
Although when I offer either address (i.e., 0xC0105000 | 0x00105000), the device complains about a Host System Access Error. If I can access those addresses (R/W) then surely the device should too. What am I doing wrong here? Am I thinking of this wrong? Am I still not getting the correct physical address and maybe only a virtual to virtual mapping and not the physical to virtual mapping I expect?
Code: Select all
char test[20]={0};
function test()
{
uint *ptr=(uint *)0xC0105000;
ptr[0]=0xDEADBEEF;
printf("\nTEST[0]: %X",test[0]);
}
Although when I offer either address (i.e., 0xC0105000 | 0x00105000), the device complains about a Host System Access Error. If I can access those addresses (R/W) then surely the device should too. What am I doing wrong here? Am I thinking of this wrong? Am I still not getting the correct physical address and maybe only a virtual to virtual mapping and not the physical to virtual mapping I expect?
Yes, I see that you have proven it, but my question was, 'How did you know that would work?'.