Proof of Concept: Writing a Linux Kernel Module in D

I thought it best today to post this in a QA format just to ease you into it.

Alright, what narcotics are you on? Seriously…
I’d like to start this post with answering a few prejudiced questions before anyone asks. No, I’m not on narcotics. Yes, this can be done. No I don’t recommend it, and no, I’m not that crazy, but I do have quite a bit of time on my hands.

Why?
Try asking yourself, why not?

D is a horrible language. It’s made more horrible by the fact that a lot of substandard programmers use it, to the point where it’s much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do *nothing* but keep the D programmers out, that in itself would be a huge reason to use C.
I think you are confusing D with C++. ;-)

Everyone happy? OK, I’ll continue then.

You actually wrote a kernel module using only D?
OK. First I’d like to clarify, I am not using pure D here, but instead a utilising D’s capability of Interfacing to C. The glue itself is in C, and the interfacing code is wrapped in “extern (C)”, so the kernel can call the functions. But given the capability, you can mixin D with C.

OK, so you’re faking it. Somehow I’ve lost interest in this.
Suit yourself, bet you don’t want to see the code either.

Fine, so what does it look like?
Here is a hello world module.

hello.c:

#include  /* Needed by all modules */

dinterface.d:

extern (C):
int printk(char *s, ...);

int __gdc_personality_v0()
{
    // STUB: int __gdc_personality_v0() not implemented
    return 0;
}

int init_module()
{
    printk("Hello world!\n");
    return 0;
}

void cleanup_module()
{
    printk("Goodbye world!\n");
}

Makefile:

# D compiler
DC := gdc
# D objects
DOBJS := dinterface.o

ifneq ($(MAKE_KBUILD),)
# kbuild part of makefile

obj-$(CONFIG_HELLO) := hello.o
hello-y += $(DOBJS)

else
# normal part of makefile

KERNELDIR := /lib/modules/$(shell uname -r)/build

all: $(DOBJS)
	$(MAKE) -C $(KERNELDIR) M=$(shell pwd) CONFIG_HELLO=m MAKE_KBUILD=1 modules

clean:
	$(MAKE) -C $(KERNELDIR) M=$(shell pwd) MAKE_KBUILD=1 clean

%.o: %.d
	$(DC) -c $< -o $@

endif

Simply type

make

to build it, then to insert the module into the kernel

sudo insmod hello.ko

And you can see the hello world in ‘dmesg’

That simple eh? OK, what is the catch Iain…
The catch? In order to use D’s most favoured features, such as arrays, you will have to port D’s runtime, typeinfo and exception handling routines (notice that __gdc_personality_v0 is just a dummy function), as they won’t be carried over in the linking of the module.

Hmm… so have you implemented this?
As of writing, no, and I don’t intend to either. You can however look into Xomb for a minimal d runtime. But the feasibility of porting it is not really worth the hassle. Infact, more than likely you will never get it working full stop, and just end up segfaulting the kernel every time.

OK, so what is the moral of this post then?
I’m wide awake, it’s Saturday. :)

About ibuclaw
An avant developer and support analyst.

One Response to Proof of Concept: Writing a Linux Kernel Module in D

  1. Pingback: Proof of Concept: Writing a Linux Kernel Module in D « Just North … | Linux Affinity

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: