Re: memory management hack to achieve desired memory map

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

 



On Fri, Apr 4, 2008 at 3:45 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote:
> 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
>
>
Just out of curiosity, why the conversion to an unsigned int and
translation to hex via the %X printf format parameter?  Are you
looking for the output '7A' (which is the hex value of 122... 122
being the base 10 value of 'z' on the ascii chart).  0XFF (255) can't
be an ascii value, but it is the max value of an unsigned char.
Just something I happened to come across in man (3) printf -


The length modifier
    Here, `integer conversion' stands for d, i, o, u, x, or X conversion.
    [...]
    z      A following integer conversion corresponds to a size_t or
ssize_t argument.  (Linux libc5 has Z with this meaning.  Don't use
it.)
    [...]

The conversion specifier
     A character that specifies the type of conversion to be applied.
The conversion specifiers and their meanings are:
     [...]
     o,u,x,X
     The unsigned int argument is converted to unsigned octal (o),
unsigned decimal (u), or unsigned hexadecimal (x and X) notation.  The
letters abcdef are used for x          conversions; the letters ABCDEF
are used for X conversions.  The precision, if any, gives the minimum
number of digits that must appear; if the converted value requires
fewer digits, it is padded on the left with zeros.  The default
precision is 1.  When 0 is printed with an explicit precision 0, the
output is empty.


I don't have enough time to look in to it (writing a paper on LDAP for
class... ugh), but I find the coincidence that 'z' is size_t, and
you're getting the correctly converted size_t of an unsigned char as
your output, extremely unlikely.  There seems to be quite a few notes
in man printf(3) talking about different glibc and libc problems, this
might also be something to look at....  Sorry I can't be of more help
ATM.  FWIW, I ran the test just fine on a Slackware-12 proper and it
seemed alright.  Perhaps you could try something besides 'z' and see
if it is indeed a library bug.
-- 
Peace and Blessings,
-Scott.

--
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