add support for building drivers as either modules or linked into kernel
---
 dev/Makefile                  |    2 +-
 dev/arch/arm/gba/Makefile     |    2 +-
 dev/arch/i386/nommu/Makefile  |    2 +-
 dev/arch/i386/pc/Makefile     |    2 +-
 dev/core/Makefile             |    2 +-
 dev/gen/Makefile              |    3 +-
 dev/power/Makefile            |    2 +-
 mk/Makefile.inc               |   98 ++++++++++++++++++++++++++++++++++++++---
 sys/Makefile                  |    3 +-
 sys/arch/arm/gba/kernel.ld    |    6 +++
 sys/arch/i386/nommu/kernel.ld |    6 +++
 sys/arch/i386/pc/kernel.ld    |    6 +++
 sys/include/device.h          |    2 +
 sys/kern/device.c             |   31 ++++++++++++-
 14 files changed, 150 insertions(+), 17 deletions(-)

diff --git a/dev/Makefile b/dev/Makefile
index bc92034..c212e18 100755
--- a/dev/Makefile
+++ b/dev/Makefile
@@ -1,4 +1,4 @@
-TARGET = dev.ko
+TARGET = dev.o
 TYPE   = DRIVER
 SUBDIRS = arch core gen power
 OBJS   = \
diff --git a/dev/arch/arm/gba/Makefile b/dev/arch/arm/gba/Makefile
index 5ce78ac..b0068b6 100755
--- a/dev/arch/arm/gba/Makefile
+++ b/dev/arch/arm/gba/Makefile
@@ -1,4 +1,4 @@
 TARGET = dev.o
 TYPE   = OBJECT
-OBJS   = platform.o keypad.o console.o swkbd.o
+OBJS-m = platform.o keypad.o console.o swkbd.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/arch/i386/nommu/Makefile b/dev/arch/i386/nommu/Makefile
index 59478e0..387a20f 100755
--- a/dev/arch/i386/nommu/Makefile
+++ b/dev/arch/i386/nommu/Makefile
@@ -1,5 +1,5 @@
 TARGET = dev.o
 TYPE   = OBJECT
-OBJS   = ../pc/dma.o ../pc/rtc.o ../pc/kbd.o ../pc/console.o \
+OBJS-m = ../pc/dma.o ../pc/rtc.o ../pc/kbd.o ../pc/console.o \
        ../pc/fdd.o ../pc/mouse.o ../i386/cpu.o ../pc/platform.o ../i386/delay.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/arch/i386/pc/Makefile b/dev/arch/i386/pc/Makefile
index be566f1..6fd4294 100755
--- a/dev/arch/i386/pc/Makefile
+++ b/dev/arch/i386/pc/Makefile
@@ -1,5 +1,5 @@
 TARGET = dev.o
 TYPE   = OBJECT
-OBJS   = dma.o rtc.o kbd.o console.o fdd.o mouse.o \
+OBJS-m = dma.o rtc.o kbd.o console.o fdd.o mouse.o \
        ../i386/cpu.o platform.o ../i386/delay.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/core/Makefile b/dev/core/Makefile
index 176e97e..b5dd907 100755
--- a/dev/core/Makefile
+++ b/dev/core/Makefile
@@ -1,4 +1,4 @@
 TARGET = core.o
 TYPE   = OBJECT
-OBJS   = main.o
+OBJS-m = main.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/gen/Makefile b/dev/gen/Makefile
index a1a4273..2d8fd37 100755
--- a/dev/gen/Makefile
+++ b/dev/gen/Makefile
@@ -1,4 +1,5 @@
 TARGET = gen.o
 TYPE   = OBJECT
-OBJS   = null.o zero.o ramdisk.o
+OBJS-m = null.o zero.o ramdisk.o
+
 include $(PREX_SRC)/mk/dev.mk
diff --git a/dev/power/Makefile b/dev/power/Makefile
index d39e68f..e60cc57 100755
--- a/dev/power/Makefile
+++ b/dev/power/Makefile
@@ -1,4 +1,4 @@
 TARGET = power.o
 TYPE   = OBJECT
-OBJS   = pm.o cpufreq.o dvs.o
+OBJS-m = pm.o cpufreq.o dvs.o
 include $(PREX_SRC)/mk/dev.mk
diff --git a/mk/Makefile.inc b/mk/Makefile.inc
index 02d64d5..6ebf6b8 100755
--- a/mk/Makefile.inc
+++ b/mk/Makefile.inc
@@ -22,12 +22,28 @@
 #  TYPE                ... Traget type
 #                  e.g. OBJECT,LIBRARY,KERNEL,BINARY,EXEC,DRIVER,OS_IMAGE
 #  SUBDIRS     ... List of subdirectories
-#  OBJS                ... Object files
+#  OBJS                ... Object files (not for drivers)
+#  OBJS-y      ... Object files
+#  OBJS-m      ... Object files for modular driver (only for drivers)
+#  OBJS-       ... Disabled Object files
+#  OBJS-$(CONFIG_FOO) ... Object enabled / disabled by conf/ARCH-PLATFORM.conf
 #  LIBS                ... Libraries
 #  MAP         ... Name of map file
 #  DISASM      ... Disassemble list file
 #  SYMBOL      ... Symbol files
 
+# Variables in conf/make.conf (override in conf/ARCH-PLATFORM.conf)
+#
+# DRIVER       ... path to driver modules or undefined for no modules
+# TASKS                ... tasks included in kernel image
+# RDFILES      ... Files in RAM disk
+
+# Variables in conf/ARCH-PLATFORM.conf
+#
+# CONFIG_FOO=y ... enable feature FOO / build driver FOO into kernel
+# CONFIG_FOO=m ... build driver FOO as a module
+# CONFIG_FOO=* ... set config parameter FOO to *
+
 #
 # Option for cross compile
 #
@@ -142,13 +158,60 @@ $(SUBDIRS): dummy
 endif
 
 #
-# Rules to compile a set of .o files into one .o file
+# Rules to link a set of .o files into one .o file
 #
 ifeq ($(TYPE),OBJECT)
-$(TARGET): $(OBJS)
-       $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(OBJS) $(LIBS)
+ifeq (,$(findstring __DRIVER__,$(CFLAGS)))
+#
+# normal objects
+#
+# OBJS   unconditionally linked objects
+# OBJS-y conditionally linked based on a CONFIG_* variable
+# OBJS-  disabled objects - associated CONFIG_* variable undefined
+
+$(TARGET): $(OBJS) $(OBJS-y)
+       $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $^ $(LIBS)
+
+ifneq (,$(strip $(OBJS-m)))
+$(error $(OBJS-m) must not be OBJ-m, this is only for drivers)
+endif
+
+else
+#
+# driver objects
+#
+# OBJS-y link objects for static drivers (typically set via CONFIG_*)
+# OBJS-m link objects for modular drivers
+# OBJS-  disabled objects
+# OBJS   is no longer used for drivers
+ifneq (,$(strip $(OBJS)))
+$(error $(OBJS) must not be OBJS, this is _not_ for drivers)
+endif
+
+# additional target for modular drivers
+all: $(TARGET:.o=.mo)
+
+# static driver objects
+ifneq (,$(strip $(OBJS-y)))
+$(TARGET): $(OBJS-y)
+       $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $^
+else # ensure an object file always exists
+$(TARGET): dummy
+       $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $@
 endif
 
+# modular driver objects
+ifneq (,$(strip $(OBJS-m)))
+$(TARGET:.o=.mo): $(OBJS-m)
+       $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $^
+else
+$(TARGET:.o=.mo): dummy
+       $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $@
+endif
+
+endif # driver objects
+endif # type opject
+
 #
 # Rules to compile library
 #
@@ -177,13 +240,20 @@ endif
 # Rules to compile device driver
 #
 ifeq ($(TYPE),DRIVER)
-$(TARGET):  $(OBJS) $(LD_SCRIPT)
-       $(LD) $(LDFLAGS) -T $(LD_SCRIPT) -o $@ $(OBJS) $(LIBS)
+# additional target for modular drivers
+all: $(TARGET:.o=.ko)
+
+$(TARGET:.o=.ko):  $(OBJS:.o=.mo) $(LD_SCRIPT)
+       $(LD) $(LDFLAGS) -T $(LD_SCRIPT) -o $@ $(OBJS:.o=.mo) $(LIBS)
        $(ASMGEN)
 ifdef SYMBOL
        cp $@ $(SYMBOL)
 endif
        $(STRIP) --strip-debug --strip-unneeded $@
+
+# staticly linked drivers
+$(TARGET): $(OBJS)
+       $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $^
 endif
 
 #
@@ -272,8 +342,22 @@ ifdef SUBDIRS
        done);
 endif
        $(RM) -f Makefile.dep
-       $(RM) -f $(OBJS)
+ifneq (,$(strip $(OBJS) $(OBJS-y) $(OBJS-m) $(OBJS-)))
+       $(RM) -f $(sort $(OBJS) $(OBJS-y) $(OBJS-m) $(OBJS-))
+endif
+ifneq (,$(strip $(TARGET)))
        $(RM) -f $(TARGET)
+endif
+ifeq ($(TYPE),DRIVER)
+ifneq (,$(strip $(TARGET:.o=.ko) $(OBJS:.o=.mo)))
+       $(RM) -f $(sort $(TARGET:.o=.ko) $(OBJS:.o=.mo))
+endif
+endif
+ifeq ($(TYPE),OBJECT)
+ifneq (,$(findstring __DRIVER__,$(CFLAGS)))
+       $(RM) -f $(TARGET:.o=.mo)
+endif
+endif
 ifdef DISASM
        $(RM) -f $(DISASM)
 endif
diff --git a/sys/Makefile b/sys/Makefile
index 9ab521e..f8e6cd3 100755
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -6,7 +6,8 @@ OBJS    = \
        ./kern/kern.o \
        ./mem/mem.o \
        ./ipc/ipc.o \
-       ./sync/sync.o
+       ./sync/sync.o \
+       ../dev/dev.o
 LIBS   = ./lib/libkern.a
 #MAP   = prex.map
 #DISASM        = prex.lst
diff --git a/sys/arch/arm/gba/kernel.ld b/sys/arch/arm/gba/kernel.ld
index a684582..cd6118e 100755
--- a/sys/arch/arm/gba/kernel.ld
+++ b/sys/arch/arm/gba/kernel.ld
@@ -32,6 +32,12 @@ SECTIONS
                *(.ksymtab)
        } : text
 
+       .driver_table ALIGN(4) : {
+               __driver_table = . ;
+               *(.driver_table)
+               __driver_table_end = . ;
+       } : text
+
        .data ALIGN(4) : {
                *(.data)
        } : data = 0xff
diff --git a/sys/arch/i386/nommu/kernel.ld b/sys/arch/i386/nommu/kernel.ld
index 20385b0..7c7490f 100755
--- a/sys/arch/i386/nommu/kernel.ld
+++ b/sys/arch/i386/nommu/kernel.ld
@@ -33,6 +33,12 @@ SECTIONS
                *(.ksymtab)
        } : text
 
+       .driver_table ALIGN(4) : {
+               __driver_table = . ;
+               *(.driver_table)
+               __driver_table_end = . ;
+       } : text
+
        . = ALIGN(32);
        .data : {
                *(.data)
diff --git a/sys/arch/i386/pc/kernel.ld b/sys/arch/i386/pc/kernel.ld
index 9ef79c6..f8d57e8 100755
--- a/sys/arch/i386/pc/kernel.ld
+++ b/sys/arch/i386/pc/kernel.ld
@@ -33,6 +33,12 @@ SECTIONS
                *(.ksymtab)
        } : text
 
+       .driver_table ALIGN(4) : {
+               __driver_table = . ;
+               *(.driver_table)
+               __driver_table_end = . ;
+       } : text
+
        . = ALIGN(32);
        .data : {
                *(.data)
diff --git a/sys/include/device.h b/sys/include/device.h
index be0c227..fbeddb5 100755
--- a/sys/include/device.h
+++ b/sys/include/device.h
@@ -48,6 +48,8 @@ struct driver {
 };
 typedef struct driver *driver_t;
 
+extern struct driver __driver_table, __driver_table_end;
+
 /*
  * Device I/O table
  */
diff --git a/sys/kern/device.c b/sys/kern/device.c
index 6c262ca..5315a89 100755
--- a/sys/kern/device.c
+++ b/sys/kern/device.c
@@ -57,7 +57,7 @@
 #include <system.h>
 
 /* Forward declarations */
-static device_t device_create(const devio_t io, const char *name);
+extern device_t device_create(const devio_t io, const char *name);
 static int device_delete(device_t dev);
 static int device_broadcast(int event, int force);
 static void system_bootinfo(struct boot_info **info);
@@ -192,7 +192,7 @@ static device_t device_lookup(const char *name)
  * I/O services to applications.
  * Returns device ID on success, or 0 on failure.
  */
-static device_t device_create(const devio_t io, const char *name)
+device_t device_create(const devio_t io, const char *name)
 {
        device_t dev;
        size_t len;
@@ -521,6 +521,31 @@ static void system_bootinfo(struct boot_info **info)
        return;
 }
 
+static void driver_init(void)
+{
+       struct driver *drv;
+       int order, err;
+
+       printk("Load staticly linked drivers\n");
+
+       /*
+        * Call init routine for all device drivers with init order.
+        * Smaller value will be run first.
+        */
+       for (order = 0; order < 16; order++) {
+               for (drv = &__driver_table; drv != &__driver_table_end;
+                    drv++) {
+                       ASSERT(drv->order < 16);
+                       if (drv->order == order) {
+                               if (drv->init) {
+                                       printk("Initializing %s\n", drv->name);
+                                       err = drv->init();
+                               }
+                       }
+               }
+       }
+}
+
 /*
  * Initialize device driver module.
  */
@@ -529,6 +554,8 @@ void device_init(void)
        struct img_info *img;
        void (*drv_entry)(void);
 
+       driver_init();
+
        img = &boot_info->driver;
        if (img == NULL)
                return;
-- 
1.5.0.3.GIT




-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Prex-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/prex-devel

Reply via email to