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