William Bland <firstname.lastname@example.org> wrote:
| Harri Haataja wrote:
| > I find the desire some (esp Linux) people have to push things to
| > kernel space very strange. I would think everything that is
| > possible to do in the much more safe and managed user space,
| > should be kept there.
| I agree for most things, but I can't see a kernel exploration
| system / rapid driver development platform working particularly
| well in user space ;-)
Uh... It works *extremely* well, actually! And it's *much* easier
to do debugging when the code-under-test is in user mode! Building
a bringup environment for new (and often initially broken!) hardware
was precisely what I used Scheme for when I first started using it
back at SGI circa 1992!! All I had to do was add a few primitives
in C (dynamically-loadable into SCM, later MzScheme) for poking at
the system & hardware:
malloc & free ; Note: *Not* from GC'd space
mpin ; Pin a virtual address range of the process
; in physical memory, similar to unix v.7 "sys()".
vir->phys ; Once you've pinned it, where is it? [Needed for DMA]
mmap ; Map the hardware registers into process space.
peek & poke ; In 8/16/32/64-bit flavors
That was enough to let me do almost complete debugging in user mode of
several generations of networking cards -- multi-port FDDI, Ethernet,
ATM, and HIPPI, to name a few -- including testing of both PIO & DMA
transfers. (That's why you need to "pin" pages, so other processes' data
won't get paged into that spot while you're DMA'ing into it!) The code
looked a bit like this (pardon dusty memories for any mistakes):
(define bridge-path "/hw/module/1/slot/io3/pci/controller")
(define big0-path "/hw/module/1/slot/io3/pci/0/usrpci/mem32")
(define brj (mmap bridge-path 0 #x1000000 1))
(define dev0cf (+ brj #x20000))
(define dev0 'notyet)
(define dev0m 'notyet)
(let ((tmp (r32 dev0cf)))
(if (= tmp #x210a9)
(print "FOO present on device 0 - Enabling mem space")
(w32 (+ dev0cf 4) (logior PCCSR_MASTER_EN PCCSR_MEM_SPACE))
(print "Mapping a big window")
(set! dev0 (mmap big0-path (r32 (+ dev0cf #x10)) #x8000000 1))
(set! dev0m (+ dev0 #x7800000)))))
At that point, "dev0" contained the process-virtual address of the
device's on-board registers, and "dev0m" pointed to its shared memory
buffers. Peeking (r32) and poking (w32) at those addresses, one could
put the device through all of its paces (except interrupts! -- but every
bit that could cause an interrupt had a corresponding pollable flag bit,
so in practice that wasn't a serious limitation).
| You may well be right but I can imagine things like rapidly
| prototyping a new file-system might be fun in Scheme?
You can do *that* in user mode, too! It wasn't in Scheme (would have
been easier had it been!), but when consulting for AMD in the late 80's,
I reimplemented the IBM CMS filesystem (at least well enough to
read/allocate/write CMD "mini-disk" user files with that "interesting"
B-tree filesystem they had) completely in user space under Amdahl's UTS-5.
You can do the same in modern Unixes/Linux, too. Just write a user-mode
NFS daemon (one easy way to hook a user process into the filesystem
dispatch) that munges raw partitions into whatever filesystem you like
(the way database vendors do for performance).
IMHO and IME, anything that *can* be done in user mode *should* be done
in user-mode, at least during development.
Rob Warnock, PP-ASEL-IA <email@example.com>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607