Proof of Concept: Writing a Linux Kernel Module in D
May 22, 2010 1 Comment
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. :)
Pingback: Proof of Concept: Writing a Linux Kernel Module in D « Just North … | Linux Affinity