From: torvalds@cs.Helsinki.FI (Linus Torvalds) Subject: Re: Reading from memory Date: 28 Jun 1993 14:46:16 +0300
In article <C9BHA7.H2u@acsu.buffalo.edu> beers@cs.buffalo.edu (Andrew Beers) writes:
>
>I am attempting to implement a device driver for a frame-grabber device. It's
>buffers are accessed by reading high memory (ie. 0x00a00000). Reading high
>memory accesses the card's own memory.
>
>How can I access this memory from the kernel under linux? How do I ensure
>that when I access memory address 0x00a00000 that I am accessing that
>*physical* address, rather than that virtual address?
Is that 0x00a00000 a typo, or do you really mean to say that it maps
itself at the 10MB area? If so, it's actually easier to get at the area
from user space than from kernel space..
In case you really meant 0x000a0000 (the 640kB-1MB area), the way to
access it is simple: the kernel identity-maps the available RAM, and the
640kB-1MB area is marked reserved, so you don't even have to allocate it
or anything: just read/write to kernel virtual address 0x000a0000 and
you'll be all right.
If the frame-grabber really maps into the 10M+ area, it's actually
currently not mapped into the kernel space, so unless you want to muck
around with memory mappings, you should read it from user space by using
the newest ALPHA-diffs for 0.99.10 which allows these kinds of mappings
using mmap(). To get it working, you should:
- get a clean 0.99.10 kernel source tree:
# cd /usr/src
# rm -rf linux
# zcat <whatever>/linux-0.99.10.tar.gz | tar xvf -
- apply the latest alpha-diffs (June 27th or later) to it
# cd /usr/src
# zcat <whatever>/ALPHA-diff.gz | patch -p0
Both the sources and alpha-diffs can be found on nic.funet.fi:
pub/OS/Linux/PEOPLE/Linus
- compile the kernel (cd /usr/src/linux, edit the makefile, "make
config" etc..)
- write a program that does something like (error-checks removed for
brevity):
int fd = open("/dev/mem",O_RDWR);
char * bufer = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0x00a00000);
and reads/writes to the newly mmapped area to it's harts content.
Note that you really need the newest alpha-diffs for this: earlier
kernels did not support mmap() on "nonstandard" memory areas, and could
handle only MAP_FIXED mappings, while the new alpha-diffs should do all
this correctly (MAP_SHARED on normal files does not update the changes,
though).
Of course, the mmap() trick works for the 0x000a0000 area as well, so
even if you can write to that area from the kernel, a user program is
still an option (that's what XFree86 does, after all).
Linus