memory management hack to achieve desired memory map

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This question was unanswered since Dec 2007 in the MM forum, someone can help?

http://forum.kernelnewbies.org/read.php?13,119

I am trying to access a 64KB block of NVRAM (BBR) placed at 0xe0000. For lack of a better method I am using a linker command script to define a new section for the BBR and hacking the kernel memory management so that a page fault to the BBR data virtual address will force a page table entry containing 0xe0000. I doubt this is the best way to achieve this, but after posting to various linux forums, I have not been made aware of a better way. Anyway, it seems to work - almost. The test application listed at the bottom of this post, shows how I can write to the NVRAM simply using;

BBR_char_data[0] = 'z';

However, attempting to reference the same variable to read the same location using;

printf("\nBBR_char_data = %X", (unsigned char)BBR_char_data[0]);

merely displays 0xff. I know am writing to the location with the first statement, because I can verify the new contents using another test utility.

I would be grateful for any advice on what I need to do to successfully read the variable BBR_char_data without using mmap.

Thanks

Mark

linker command script
====================
.
.
.
MEMORY
{
MAIN_MEM (RWX) : ORIGIN = 0x08048000 + 1024, LENGTH = 128M
BBRDATA (RW) : ORIGIN = 0x10048000, LENGTH = 64K
}
.
.
.
.bbrdata (NOLOAD) : { *(.bbrdata) } > BBRDATA
.
.
.
-------------------------------------------------------------------------------------
kernel-source-2.4.27/mm/memory.c
================================

static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, pte_t *page_table, int write_access, unsigned long addr)
{
pte_t entry;

/* Read-only mapping of ZERO_PAGE. */
entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));

/* ..except if it's a write access */
if (write_access) {
struct page *page;

/* Allocate our own private page. */
spin_unlock(&mm->page_table_lock);

page = alloc_page(GFP_HIGHUSER);

if (!page)
goto no_mem;
clear_user_highpage(page, addr);

spin_lock(&mm->page_table_lock);
if (!pte_none(*page_table)) {
page_cache_release(page);
spin_unlock(&mm->page_table_lock);
return 1;
}
mm->rss++;
flush_page_to_ram(page);

/* if( addr >= 0x10048000 && addr <= 0x10048800)
{
entry = pte_mkwrite(pte_mkdirty(mk_pte_phys(0xe0000,
vma->vm_page_prot))); // NVRAM is located at
// 0xe0000
}*/
else
{
entry = pte_mkwrite(pte_mkdirty(mk_pte(page,
vma->vm_page_prot)));
}
lru_cache_add(page);
mark_page_accessed(page);
}

set_pte(page_table, entry);

/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, addr, entry);
spin_unlock(&mm->page_table_lock);
return 1; /* Minor fault */

no_mem:
return -1;
}
--------------------------------------------------------------------------------------------------------------------------------------------------------
test utility
============

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


char BBR_char_data[0x10000] __attribute__ ((section (".bbrdata"winking smiley));

int main(int argc, char *argv[])
{
// this actually works and sets the first location of NVRAM to 'z'
BBR_char_data[0] = 'z';

// this doesn't work... it returns 0xff
printf("\nBBR_char_data = %X", (unsigned char)BBR_char_data[0]);

return EXIT_SUCCESS;
}


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux