Hi, I am trying to port an homemade operating system in Dom0 but I have a problem with mmu operation. I have read Xen docs and mailling lists archives and I still do not understand well how mmu works on Xen. My need is to simply perform an identity mapping at 0xb8000 to allow my operating system to access the vga frammebuffer. So my first idea was to use HYPERVISOR_mmu_update like this : mmu_update_t mmu; uint8_t *buf = (uint8_t *) 0xb8000; mmu.ptr = 0xb8000 | MMU_MACHPHYS_UPDATE mmu.val = 0xb8000 HYPERVISOR_mmu_update(&mmu, 1, NULL, DOMID_SELF); buf[0] = ''a''; buf[1] = 0x7; But it does not work :/ After that I was think that I need to put in mmu.val the exact entry for the PTE (add R/W flags, present flags etc...) So I have replaced mmu.val = 0xb8000 by mmu.val = 0xb8003 but it still not work.... Can you help me please, I am stuck :/ -- Sylvestre Gallon _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Hi, I am trying to port an homemade operating system in Dom0 but I have a problem with mmu operation. I have read Xen docs and mailling lists archives and I still do not understand well how mmu works on Xen. My need is to simply perform an identity mapping at 0xb8000 to allow my operating system to access the vga frammebuffer. So my first idea was to use HYPERVISOR_mmu_update like this : mmu_update_t mmu; uint8_t *buf = (uint8_t *) 0xb8000; mmu.ptr = 0xb8000 | MMU_MACHPHYS_UPDATE mmu.val = 0xb8000 HYPERVISOR_mmu_update(&mmu, 1, NULL, DOMID_SELF); buf[0] = ''a''; buf[1] = 0x7; But it does not work :/ After that I was think that I need to put in mmu.val the exact entry for the PTE (add R/W flags, present flags etc...) So I have replaced mmu.val = 0xb8000 by mmu.val = 0xb8003 but it still not work.... Can you help me please, I am stuck :/ -- Sylvestre Gallon _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 18/05/2010 09:01, "Sylvestre Gallon" <syl@pmbsd.org> wrote:> My need is to simply perform an identity mapping at 0xb8000 to allow > my operating system to access the vga frammebuffer. So my first idea > was to use HYPERVISOR_mmu_update like this : > > mmu_update_t mmu; > uint8_t *buf = (uint8_t *) 0xb8000; > > mmu.ptr = 0xb8000 | MMU_MACHPHYS_UPDATE > mmu.val = 0xb8000 > HYPERVISOR_mmu_update(&mmu, 1, NULL, DOMID_SELF);You need to use MMU_NORMAL_PT_UPDATE command, passing a pointer to a pte (pagetable entry) in mmu.ptr and the value to write to that pte in mmu.val. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On Wed, Jun 2, 2010 at 10:07 PM, Keir Fraser <keir.fraser@eu.citrix.com> wrote:> On 18/05/2010 09:01, "Sylvestre Gallon" <syl@pmbsd.org> wrote: > >> My need is to simply perform an identity mapping at 0xb8000 to allow >> my operating system to access the vga frammebuffer. So my first idea >> was to use HYPERVISOR_mmu_update like this : >> >> mmu_update_t mmu; >> uint8_t *buf = (uint8_t *) 0xb8000; >> >> mmu.ptr = 0xb8000 | MMU_MACHPHYS_UPDATE >> mmu.val = 0xb8000 >> HYPERVISOR_mmu_update(&mmu, 1, NULL, DOMID_SELF); > > You need to use MMU_NORMAL_PT_UPDATE command, passing a pointer to a pte > (pagetable entry) in mmu.ptr and the value to write to that pte in mmu.val. > > -- Keir >Thanks for you response. If I understand I need to do something like that : mmu_update_t mmu; addr = get_cr3(); // getting page directory addr &= 0xfffff000; // remove pdir flags addr = ((uint32_t*) addr_[0]; // get address of first page dir (0xb8000 is in the first pdir) addr += 0xb8 * 4; // 0xb8000 must be the pte 0xb8 into pdir 0 mmu.ptr = pte | MMU_NORMAL_PT_UPDATE; mmu.val = 0xb8000 | 0x3; // 0x3 for pte present and rw flags HYPERVISOR_mmu_update(&mmu, 1, NULL, DOMID_SELF); while(42); But when I try this code I get an unhandled page fault :/ Do I have misunderstood something ? Thanks a lot for your time, Cheers, -- Sylvestre Gallon _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 03/06/2010 14:16, "Sylvestre Gallon" <syl@pmbsd.org> wrote:> addr = get_cr3(); // getting page directory > addr &= 0xfffff000; // remove pdir flags > addr = ((uint32_t*) addr_[0]; // get address of first page dir > (0xb8000 is in the first pdir) > addr += 0xb8 * 4; // 0xb8000 must be the pte 0xb8 into pdir > 0 > > mmu.ptr = pte | MMU_NORMAL_PT_UPDATE; > mmu.val = 0xb8000 | 0x3; // 0x3 for pte present and rw flags > > HYPERVISOR_mmu_update(&mmu, 1, NULL, DOMID_SELF); > > while(42); > > But when I try this code I get an unhandled page fault :/ > > Do I have misunderstood something ?This is closer, but page table entries will be 64 bits not 32 bits (hence use uint64_t). And also the page tables will have three or four levels (depending on whether your guest is 32-bit PAE or 64-bit). So in the 64-bit case for example, you would read cr3 to get pagedir_1, then index into pagedir_1 to get pagedir_2, then index into pagedir_2 to get pagedir_3, then index into pagedir_3 to get the pagetable. And mmu.ptr would point at an entry in that pagetable. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On Thu, Jun 3, 2010 at 3:29 PM, Keir Fraser <keir.fraser@eu.citrix.com> wrote:> > > > On 03/06/2010 14:16, "Sylvestre Gallon" <syl@pmbsd.org> wrote: > >> addr = get_cr3(); // getting page directory >> addr &= 0xfffff000; // remove pdir flags >> addr = ((uint32_t*) addr_[0]; // get address of first page dir >> (0xb8000 is in the first pdir) >> addr += 0xb8 * 4; // 0xb8000 must be the pte 0xb8 into pdir >> 0 >> >> mmu.ptr = pte | MMU_NORMAL_PT_UPDATE; >> mmu.val = 0xb8000 | 0x3; // 0x3 for pte present and rw flags >> >> HYPERVISOR_mmu_update(&mmu, 1, NULL, DOMID_SELF); >> >> while(42); >> >> But when I try this code I get an unhandled page fault :/ >> >> Do I have misunderstood something ? > > This is closer, but page table entries will be 64 bits not 32 bits (hence > use uint64_t). And also the page tables will have three or four levels > (depending on whether your guest is 32-bit PAE or 64-bit). So in the 64-bit > case for example, you would read cr3 to get pagedir_1, then index into > pagedir_1 to get pagedir_2, then index into pagedir_2 to get pagedir_3, then > index into pagedir_3 to get the pagetable. And mmu.ptr would point at an > entry in that pagetable. >OK , I see. I still have a question, does I need to compile my kernel with -m64 ? If not how can I use 64bits addresses ? Thanks for your help. Cheers, -- Sylvestre Gallon _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 03/06/2010 16:23, "Sylvestre Gallon" <syl@pmbsd.org> wrote:>> This is closer, but page table entries will be 64 bits not 32 bits (hence >> use uint64_t). And also the page tables will have three or four levels >> (depending on whether your guest is 32-bit PAE or 64-bit). So in the 64-bit >> case for example, you would read cr3 to get pagedir_1, then index into >> pagedir_1 to get pagedir_2, then index into pagedir_2 to get pagedir_3, then >> index into pagedir_3 to get the pagetable. And mmu.ptr would point at an >> entry in that pagetable. >> > > OK , I see. > > I still have a question, does I need to compile my kernel with -m64 ? > > If not how can I use 64bits addresses ?That''s not something I can answer in a short email. Suffice to say, if your kernel is 32-bit PAE then the pagetables are 3-level, with 64-bit entries, and the steps I outline above would be suitably modified for that structure. This is all x86 architectural stuff, so you can go look in manuals and books and other code to get an idea of how it all works. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel