I am releasing this document early due to a perceived need by the community.
Specifically, it shows how to use the mbuff driver from "pure" Linux space
(i.e. without any real time modules) with fully documented and commented
code.
+===========
TO DO / COMMENTS:
1. In a recent message, Tomasz wrote ... "In cleanup_module call mbuff_free".
In the Kmem.c code example presented here, you will see that I call the
mbuff_free function inside the init_module ... when I put the function in
the cleanup_module, I would hang the system once the Umem program
terminated. I'll try to verify the behaviour to make that comment more
specific.
2. I want to create a module Rmem which is the real time analogue of Kmem so
that you can also see the shared memory used in real time.
3. Edit these notes after feedback from A N Other et al.
Phil
NOTES ON INSTALLING MBUFF-0.6.4 AND MBUFFEX-0.6.4 WITH Linux Kernel v2.2.13
===========================================================================
Copyright (C) 1999 Philip N Daly ([EMAIL PROTECTED])
These instructions were tested on a dual Pentium III 500 MHz,
256Mb, 18Gb running Red Hat v6.1, kernel v2.2.13.
Your mileage may vary. For best results, print this document.
0. Login as root and watch your typing!
CHECK HERE WHEN OK ______
1. Get the mbuff v0.6.4 driver:
% cd /usr/src
% netscape http://crds.chemie.unibas.ch/PCI-MIO-E/mbuff-0.6.4.tar.gz &
Once connected, a "Save As ..." dialogue box should appear, click on OK.
CHECK HERE WHEN OK ______
2. Unpack the release:
% gunzip -c ./mbuff-0.6.4.tar.gz | tar xvf -
% cd mbuff-0.6.4
% lpr README
CHECK HERE WHEN OK ______
3. Edit the Makefile to comment out -DSHM_DEMO on line 13.
Also edit out the -DSHM_DEMO from the tester, mbuff_alloc, mbuff_dealloc
and demo targets.
CHECK HERE WHEN OK ______
4. Make the driver. These should complete without errors.
% make clean
% make all
CHECK HERE WHEN OK ______
5. Check it loads OK. Note that the kernel log says v0.6.3 and not v0.6.4!
% /sbin/insmod -f ./mbuff.o
% /sbin/lsmod
Module Size Used by
mbuff 5260 0 (unused)
% /sbin/rmmod mbuff
% dmesg | tail -5
mbuff: kernel shared memory driver v0.6.3
mbuff: (C) Tomasz Motylewski et al., GPL
mbuff: registered as MISC device minor 254
unloading mbuff
mbuff device deregistered
CHECK HERE WHEN OK ______
6. Test the driver:
% make tests
% make test1
The following output is *normal* (including the core dump):
/usr/src/linux assumed to be your kernel source directory.
do 'make tests' to build all mbuff demo programs.
rmmod mbuff
rmmod: module mbuff not loaded
make: [test1] Error 1 (ignored)
insmod -f mbuff.o
./mbuff_alloc default 409600
default shared memory area is 409600 bytes long now
./tester
success, 12288 bytes mmaped at 0x40013000
memory set
closed
set again to CD
unmapping in 1s
unmapped
trying to write again
make: *** [test1] Segmentation fault (core dumped)
Note that the module is still being "used":
% /sbin/lsmod
Module Size Used by
mbuff 5260 1
Do the second test:
% make test2
The following output is *normal*:
/usr/src/linux assumed to be your kernel source directory.
do 'make tests' to build all mbuff demo programs.
rmmod mbuff
rmmod: mbuff: Device or resource busy
make: [test2] Error 1 (ignored)
insmod -f mbuff.o
mbuff.o: a module named mbuff already exists
make: [test2] Error 1 (ignored)
(./tester &); sleep 2; (./tester &); ./mbuff_dealloc default
success, 12288 bytes mmaped at 0x40013000
memory set
default shared memory area was 409600 bytes long
[yourhost] # memory set
closed
closed
set again to CD
set again to CD
unmapping in 1s
unmapped
unmapping in 1s
unmapped
trying to write again
trying to write again
Note that the module is no longer being "used":
% /sbin/lsmod
Module Size Used by
mbuff 5260 0
CHECK HERE WHEN OK ______
7. If you wish to see an example of vanilla Linux exercising the mbuff driver,
get the latest version:
% netscape ftp://orion.tuc.noao.edu/pub/pnd/mbuffex-0.6.4.tgz &
Once downloaded, click on File -> Save As ... and click on the OK button.
This code shows you how to:
a) parses the command line to determine if you want bytes,
kilobytes, megabytes or gigabytes in both kernel mode and
user mode;
b) uses a structure as the basic memory unit and so provides
a template for more complex data structures in shared memory;
c) checks that an integer number of structures fit within the
required memory area; if not, the area will be dynamically
increased to get to a structure boundary;
d) allocates the memory, saving the initial pointer(s);
e) re-schedules the kernel as required;
f) uses double ring buffers;
CHECK HERE WHEN OK ______
8. Unpack the release:
% gunzip -c mbuffex-0.6.4.tgz | tar xvf -
% cd mbuffex-0.6.4
CHECK HERE WHEN OK ______
9. The defaults for these programs are 100 iterations at 1 Hz (1000000 usec).
If you want to change these, edit the Mem.h file definitions of LOOPS and
SLEEP respectively. Edit the Makefile to check the MBUFF_INC directory and
make the exerciser.
% make clean
% make all
This exerciser should create a kernel module (Kmem) and a user program
(Umem). The idea is that both map a section of memory and the kernel
module re-schedules at 1 Hz and writes the alphabet in upper case to
the kernel area and reads the user area. Meanwhile the Umem program,
also running at 1 Hz, writes the alphabet in lower case to the user
area and reads the kernel area. Both use ring buffers. Both use the
same structure for data - edit this as you see fit in Mem.h and
write what you like in Kmem.c, Umem.c. In pseudo-code:
Kmem:
checks command line arguments for amount of memory to allocate;
allocates kernel memory;
allocates user memory;
loops N-times {
re-sets ring buffer before memory overflow;
re-sets character to write into memory;
writes character to kernel memory;
increments kernel pointers;
reads character from user memory;
increments user pointer;
sleeps for 1 second;
}
de-allocates kernel buffer;
de-allocates user buffer;
Umem:
checks command line arguments for amount of memory to allocate;
allocates user memory;
allocates kernel memory;
loops N-times {
re-sets ring buffer before memory overflow;
re-sets character to write into memory;
writes character to user memory;
increments user pointers;
reads character from kernel memory;
increments kernel pointer;
sleeps for 1 second;
}
de-allocates user buffer;
de-allocates kernel buffer;
CHECK HERE WHEN OK ______
10. Test the exerciser. Create 3 new terminals (xterms if you wish):
Terminal 1: insert the module, run Kmem allocating 208 bytes
% /sbin/insmod -f /usr/src/mbuff-0.6.4/mbuff.o
% cd /usr/src/mbuffex-0.6.4
% /sbin/insmod -f Kmem b=208
Terminal 2: start the program, allocating 208 bytes
% cd /usr/src/mbuffex-0.6.4
% ./Umem -b208 >> Umem.dat 2>&1
Terminal 3: repeat the following ad infinitum:
% dmesg | tail
or
% tail /var/log/messages
CHECK HERE WHEN OK ______
11. The kernel module will produce lines like (in terminal 3, and assuming
you left the -DDEBUG in the Makefile):
Allocation is sufficient to hold 26 data sets
Kmem: Allocating 208 bytes in "Kmem"
Kmem: Allocated 208 bytes in "Kmem"
Kmem: Initial kernel pointer is d0861000
Kmem: Allocating 208 bytes in "Umem"
Kmem: Allocated 208 bytes in "Umem"
Kmem: Initial user pointer is d0863000
Kmem: [100] Wrote "A" to "Kmem" at d0861000 { 0}
Kmem: Inconsistent magic number in "Umem" at d0863000
Kmem: [ 99] Wrote "B" to "Kmem" at d0861008 { 0}
Kmem: Inconsistent magic number in "Umem" at d0863008
Kmem: [ 98] Wrote "C" to "Kmem" at d0861010 { 0}
Kmem: Inconsistent magic number in "Umem" at d0863010
.
.
.
Note the "Inconsistent magic number" message which is normal during the
early parts of the test. Once the ring buffers are re-set (by the module
and/or program), you should see lines like:
Kmem: Re-setting memory pointer in "Kmem" from d08610d0 to d0861000
Kmem: Re-setting memory pointer in "Umem" from d08630d0 to d0863000
Kmem: Re-setting character to "A"
Kmem: [ 48] Wrote "A" to "Kmem" at d0861000 {1344456749}
Kmem: [ 48] Read "a" from "Umem" at d0863000 {1492860137}
Kmem: [ 47] Wrote "B" to "Kmem" at d0861008 {1344456749}
Kmem: [ 47] Read "b" from "Umem" at d0863008 {1492860137}
Kmem: [ 46] Wrote "C" to "Kmem" at d0861010 {1344456749}
Kmem: [ 46] Read "c" from "Umem" at d0863010 {1492860137}
.
.
.
The user program will produce lines like (assuming you left the
-DDEBUG in the Makefile):
Allocation is sufficient to hold 26 data sets
Umem: Allocating 208 bytes in "Umem"
Umem: Allocated 208 bytes in "Umem"
Umem: Initial user pointer is 0x40014000
Umem: Allocating 208 bytes in "Kmem"
Umem: Allocated 208 bytes in "Kmem"
Umem: Initial kernel pointer is 0x40015000
Umem: [100] Wrote "a" to "Umem" at 0x40014000 { 0}
Umem: [100] Read "A" from "Kmem" at 0x40015000 {1344456749}
Umem: [ 99] Wrote "b" to "Umem" at 0x40014008 { 0}
Umem: [ 99] Read "B" from "Kmem" at 0x40015008 {1344456749}
Umem: [ 98] Wrote "c" to "Umem" at 0x40014010 { 0}
Umem: [ 98] Read "C" from "Kmem" at 0x40015010 {1344456749}
.
.
.
Note that, since the kernel is started first, the user program can
read the kernel memory straight away and should not return the
"Inconsistent magic number" message. Once the buffers have been
reset, the magic numbers should be OK:
Umem: Re-setting memory pointer in "Umem" from 0x400140d0 to 0x40014000
Umem: Re-setting memory pointer in "Kmem" from 0x400150d0 to 0x40015000
Umem: Re-setting character to "a"
Umem: [ 74] Wrote "a" to "Umem" at 0x40014000 {1492860137}
Umem: [ 74] Read "A" from "Kmem" at 0x40015000 {1344456749}
Umem: [ 73] Wrote "b" to "Umem" at 0x40014008 {1492860137}
Umem: [ 73] Read "B" from "Kmem" at 0x40015008 {1344456749}
Umem: [ 72] Wrote "c" to "Umem" at 0x40014010 {1492860137}
Umem: [ 72] Read "C" from "Kmem" at 0x40015010 {1344456749}
.
.
.
CHECK HERE WHEN OK ______
12. Remove the module
% /sbin/rmmod Kmem
CHECK HERE WHEN OK ______
+==================================================================+
Phil Daly, NOAO/AURA, 950 N. Cherry Avenue, Tucson AZ 85719, U S A
E-mail: [EMAIL PROTECTED] V-mail: (520) 318 8438 Fax: (520) 318 8360
--- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
----
For more information on Real-Time Linux see:
http://www.rtlinux.org/~rtlinux/