View mode: basic / threaded / horizontal-split · Log in · Help
November 14, 2011
Translation of C struct to D
Hi!

I currently try to create a simple linux driver (for test purposes) just 
like in [1] in D based on [2]. The main difficulty is to call 
register_chrdev. It expects an argument "fops" of type file_operations 
which can look like that in C:

static struct file_operations fops = {
	.read = device_read,
	.write = device_write,
	.open = device_open,
	.release = device_release
};

device_read and so on are functions. Originally, file_operations has 
much more fields and it's possible to omit unused fields.

What I tried so far: I declared "register_chrdev" as follows:

extern (C):
int register_chrdev (uint major, char *name, file_operations *fops);

My try for the translation of file_operations looks like that:

struct file_operations {
	int function() open;
	int function() release;
};

In init_module() I have the following code:

char[] DEVICE_NAME = "dtestdev";
file_operations fops;
fops.open = &device_open;
fops.release = &device_close;
Major = register_chrdev(0, std.string.toStringz(DEVICE_NAME), &fops);

The code compiles with some warnings, and if I try to insert it into the 
kernel, I get some messages in the kernel log.

WARNING: "_D3std6string9toStringzFAaZPa" [...../hello.ko] undefined!
WARNING: "_Dmodule_ref" [...../hello.ko] undefined!
WARNING: "_D15TypeInfo_Struct6__vtblZ" [...../hello.ko] undefined!
WARNING: "register_chrdev" [...../hello.ko] undefined!
WARNING: "_D3std6string12__ModuleInfoZ" [...../hello.ko] undefined!

Nov 14 21:12:39 eeepc1104 kernel: [17127.068990] hello: Unknown symbol 
_D3std6string12__ModuleInfoZ (err 0)
Nov 14 21:12:39 eeepc1104 kernel: [17127.069613] hello: Unknown symbol 
register_chrdev (err 0)
Nov 14 21:12:39 eeepc1104 kernel: [17127.070462] hello: Unknown symbol 
_D15TypeInfo_Struct6__vtblZ (err 0)
Nov 14 21:12:39 eeepc1104 kernel: [17127.071359] hello: Unknown symbol 
_Dmodule_ref (err 0)
Nov 14 21:12:39 eeepc1104 kernel: [17127.072352] hello: Unknown symbol 
_D3std6string9toStringzFAaZPa (err 0)

Any help greatly appreciated.

Greetings

Michael

[1] http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN680
[2] 
http://iainbuclaw.wordpress.com/2010/05/22/writing-a-linux-kernel-module-in-d/
November 15, 2011
Re: Translation of C struct to D
Michael Kremser <mkspamx-usenet@yahoo.de> writes:

> Hi!
>
> I currently try to create a simple linux driver (for test purposes)
> just like in [1] in D based on [2]. The main difficulty is to call
> register_chrdev. It expects an argument "fops" of type file_operations
> which can look like that in C:
>
> static struct file_operations fops = {
> 	.read = device_read,
> 	.write = device_write,
> 	.open = device_open,
> 	.release = device_release
> };
>
> device_read and so on are functions. Originally, file_operations has
> much more fields and it's possible to omit unused fields.
>
> What I tried so far: I declared "register_chrdev" as follows:
>
> extern (C):
> int register_chrdev (uint major, char *name, file_operations *fops);
>
> My try for the translation of file_operations looks like that:
>
> struct file_operations {
> 	int function() open;
> 	int function() release;
> };
>
> In init_module() I have the following code:
>
> char[] DEVICE_NAME = "dtestdev";
> file_operations fops;
> fops.open = &device_open;
> fops.release = &device_close;
> Major = register_chrdev(0, std.string.toStringz(DEVICE_NAME), &fops);
>
> The code compiles with some warnings, and if I try to insert it into
> the kernel, I get some messages in the kernel log.
>
> WARNING: "_D3std6string9toStringzFAaZPa" [...../hello.ko] undefined!
> WARNING: "_Dmodule_ref" [...../hello.ko] undefined!
> WARNING: "_D15TypeInfo_Struct6__vtblZ" [...../hello.ko] undefined!
> WARNING: "register_chrdev" [...../hello.ko] undefined!
> WARNING: "_D3std6string12__ModuleInfoZ" [...../hello.ko] undefined!
>
> Nov 14 21:12:39 eeepc1104 kernel: [17127.068990] hello: Unknown symbol
> _D3std6string12__ModuleInfoZ (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.069613] hello: Unknown symbol
> register_chrdev (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.070462] hello: Unknown symbol
> _D15TypeInfo_Struct6__vtblZ (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.071359] hello: Unknown symbol
> _Dmodule_ref (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.072352] hello: Unknown symbol
> _D3std6string9toStringzFAaZPa (err 0)
>
> Any help greatly appreciated.

This looks like you don't have druntime or phobos linked into your
module code.  

Does the original C example work for you?
November 15, 2011
Re: Translation of C struct to D
Jerry thought it would be a good idea to write me on 15.11.2011 05:01 
GMT +0100 (CET):
> 
> This looks like you don't have druntime or phobos linked into your
> module code.  

My Makefile looks as follows:

# 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

Is there something missing?

> Does the original C example work for you? 

Yes, it works, and also the "Hello World" module in D from the other 
webpage works.
November 15, 2011
Re: Translation of C struct to D
kbuild is almost certainly not linking in phobos.
November 15, 2011
Re: Translation of C struct to D
On 14 November 2011 20:54, Michael Kremser <mkspamx-usenet@yahoo.de> wrote:
> Hi!
>
> I currently try to create a simple linux driver (for test purposes) just
> like in [1] in D based on [2]. The main difficulty is to call
> register_chrdev. It expects an argument "fops" of type file_operations which
> can look like that in C:
>
> static struct file_operations fops = {
>        .read = device_read,
>        .write = device_write,
>        .open = device_open,
>        .release = device_release
> };
>
> device_read and so on are functions. Originally, file_operations has much
> more fields and it's possible to omit unused fields.
>
> What I tried so far: I declared "register_chrdev" as follows:
>
> extern (C):
> int register_chrdev (uint major, char *name, file_operations *fops);
>
> My try for the translation of file_operations looks like that:
>
> struct file_operations {
>        int function() open;
>        int function() release;
> };
>
> In init_module() I have the following code:
>
> char[] DEVICE_NAME = "dtestdev";
> file_operations fops;
> fops.open = &device_open;
> fops.release = &device_close;
> Major = register_chrdev(0, std.string.toStringz(DEVICE_NAME), &fops);
>
> The code compiles with some warnings, and if I try to insert it into the
> kernel, I get some messages in the kernel log.
>
> WARNING: "_D3std6string9toStringzFAaZPa" [...../hello.ko] undefined!
> WARNING: "_Dmodule_ref" [...../hello.ko] undefined!
> WARNING: "_D15TypeInfo_Struct6__vtblZ" [...../hello.ko] undefined!
> WARNING: "register_chrdev" [...../hello.ko] undefined!
> WARNING: "_D3std6string12__ModuleInfoZ" [...../hello.ko] undefined!
>
> Nov 14 21:12:39 eeepc1104 kernel: [17127.068990] hello: Unknown symbol
> _D3std6string12__ModuleInfoZ (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.069613] hello: Unknown symbol
> register_chrdev (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.070462] hello: Unknown symbol
> _D15TypeInfo_Struct6__vtblZ (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.071359] hello: Unknown symbol
> _Dmodule_ref (err 0)
> Nov 14 21:12:39 eeepc1104 kernel: [17127.072352] hello: Unknown symbol
> _D3std6string9toStringzFAaZPa (err 0)
>
> Any help greatly appreciated.
>
> Greetings
>
> Michael
>
> [1] http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN680
> [2]
> http://iainbuclaw.wordpress.com/2010/05/22/writing-a-linux-kernel-module-in-d/
>

If you are going to write a kernel module, do not use or rely any part
of the D, or C standard library. Do not attempt to do anything that
would generate hidden calls to the D runtime library, or would depend
on there being one.  Otherwise you will find yourself hitting a total
system freeze when loading the module into the kernel. :~)


Rather than using toStringz, you should be able to get by with
declaring the register_chrdev function as follows.

extern(C)
int register_chrdev (uint major, in char *name, file_operations *fops)



Regards
-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
November 16, 2011
Re: Translation of C struct to D
Am 2011-11-16 00:53, schrieb Iain Buclaw:

> Rather than using toStringz, you should be able to get by with
> declaring the register_chrdev function as follows.
>
> extern(C)
> int register_chrdev (uint major, in char *name, file_operations *fops)

This yields the following compiler error:

Error: cannot implicitly convert expression (DEVICE_NAME) of type char[] 
to char*

If I try to cast with register_chrdev(0, (char*)DEVICE_NAME, &fops); the 
following error appears:

C style cast illegal, use cast(char*)DEVICE_NAME

Best regards

Michael
November 16, 2011
Re: Translation of C struct to D
> If I try to cast with register_chrdev(0, (char*)DEVICE_NAME, &fops); the  
> following error appears:
>
> C style cast illegal, use cast(char*)DEVICE_NAME

Or use DEVICE_NAME.ptr
November 17, 2011
Re: Translation of C struct to D
Am 2011-11-16 23:23, schrieb Trass3r:
>> If I try to cast with register_chrdev(0, (char*)DEVICE_NAME, &fops);
>> the following error appears:
>>
>> C style cast illegal, use cast(char*)DEVICE_NAME
>
> Or use DEVICE_NAME.ptr

Compilation now succeeded, but when I try to load with insmod, the 
following errors appear:

Nov 17 15:03:49 eeepc1104 kernel: [43799.326876] hello: Unknown symbol 
_D3std6string12__ModuleInfoZ (err 0)
Nov 17 15:03:49 eeepc1104 kernel: [43799.327297] hello: Unknown symbol 
register_chrdev (err 0)
Nov 17 15:03:49 eeepc1104 kernel: [43799.327702] hello: Unknown symbol 
_D15TypeInfo_Struct6__vtblZ (err 0)
Nov 17 15:03:49 eeepc1104 kernel: [43799.328252] hello: Unknown symbol

Best regards

Michael
Top | Discussion index | About this forum | D home