Re: wheee snapshot time...

David S. Miller (davem@caip.rutgers.edu)
Thu, 24 Aug 1995 09:20:39 -0400


Date: Thu, 24 Aug 95 07:41 EDT
From: hamish@border.ocunix.on.ca (Hamish Macdonald)

Since a lot of what I have to say falls under the generic-kernel issue
criterion, I have CC'd linux-kernel.

How much code re-use of the standard Linux kernel are you getting for
the keyboard and console (as in; using the files (possibly modified)
that are already there; *not* clone and twiddle)?

Well, I will say that my serial.c Zilog driver is a beast with it's
own nature, beside the prototypes for the usual functions (ie. open,
close, ioctl, start, stop, etc.) the code is completely on it's own.
As for the keyboard driver I have basically kept in line with the
'logic' of the i386 driver, the 'do_*' functions are all the same,
although I might add some for some nifty kernel info dumping
features. As for the console, since I don't have direct frame buffer
support as of yet this is tought to comment on (for the frame buffer
console, I use the boot monitor's 'put_char' to output characters),
except that using the serial line of the Sparc as console i/o (which
is common) causes con_init() to end up calling register_console() in a
different manner.

If you are doing so, what mechanism are you using. The m68k and sparc
ports appear to be the non-PC architecture Linux ports which are
furthest along. Things like the high level keyboard mapping
(functions/tables) and the console terminal emulation are things which
should really be shared amongst all the ports.

It seems to me that the kernel vt keyboard mechanism works just fine
for me as far as I can tell. All that was needed was to whip up a
defkeymap.map for the sun keyboard layout, use loadkeys to produce the
defkeymap.c in my tree, voila. A nag happened to be that the VT_*
defines for the leds just so happened to be the values you send to the
i386/alpha keyboards as the second byte of the 'SET_LED' command.
Thus I have a little conversion routine. Also, keyboard repeating has
to be determined via a timeout of some sort too. I am currently using
things like vc_screen.c, vt.c, vt_kern.h, kbd_kern.h, etc. as is in my
sources if that means anything. Also the generic n_tty.c, pty.c,
tty_io.c and friends are the same too.

I will admit that the serial.c and keyboard.c files were begun by
taking the i386 driver, re-using what I thought I could with just
minor Sparc specific modifications thrown in, and chucking out and
rewriting from scratch what I absolutely could not re-use. I could
probably document the entire process for either serial.c or
keyboard.c from my RCS logs, would have to check how thorough I was.

On another topic I have been trying to come up with a nice solution to
get the drivers/* directories 'multi-architecture' ready. One idea I
have come up with is the following.

Each makefile within each driver type does something similar to the
following:

--------------------
#
# drivers/char
#
# Generic
#

L_TARGET := char.a
M_OBJS :=
L_OBJS := tty_io.o n_tty.o \
tty_ioctl.o pty.o vt.o mem.o vc_screen.o \
defkeymap.o consolemap.o vesa_blank.o selection.o

# All architectures need an equivalent of the following
L_OBJS += $(DRIVER_ARCH)/serial.o $(DRIVER_ARCH)/console.o \
$(DRIVER_ARCH)/keyboard.o

include $(DRIVER_ARCH)/drivers.make

ifdef M
L_OBJS += mouse.o
endif

include $(TOPDIR)/Rules.make

fastdep: uni_hash.tbl

consolemap.o:

conmakehash: conmakehash.c
$(HOSTCC) -o conmakehash conmakehash.c

uni_hash.tbl: $(FONTMAPFILE) conmakehash
./conmakehash $(FONTMAPFILE) 641 283 6 > uni_hash.tbl
--------------------

the top-level makefile will do something like

--------------------
ifeq ($(ARCH), alpha)
DRIVER_ARCH = i386
else
DRIVER_ARCH = $(ARCH)
endif
--------------------

You get the idea. Now, in our example, we'd now have directories like
the following:

drivers/char/i386
drivers/char/sparc
drivers/char/m68k
drivers/char/mips

drivers/char/i386/drivers.make would contain all of the following arch
dependant garbage:

--------------------
ifdef CONFIG_CYCLADES
L_OBJS += i386/cyclades.o
endif

ifdef CONFIG_ATIXL_BUSMOUSE
M = y
L_OBJS += i386/atixlmouse.o
endif
--------------------

etc., again you get the idea... So, the run-down of this mechanism is

#Generic character driver logic
drivers/char/*.[ch]

#Architecture dependant driver files
drivers/char/$DRIVER_ARCH/$.[ch]

#Makefile code for that architecture.
drivers/char/$DRIVER_ARCH/drivers.$DRIVER_ARCH

#Top-level char driver tweaked to use above scheme
drivers/char/Makefile

This possibly needs some tweaks here and there, but seems to work out
ok for the most part, we'll see. Also note that I have been trying
very hard to work with Linus on adding all the necessary hooks to the
memory management so that you can plug almost anything into it, even
wacky hardware like the broken sun4c mmu and it's sorry excuse for an
extended tlb + borken virtual cache. (yes, borken)

Later,
David S. Miller
davem@caip.rutgers.edu