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