www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Translation of C struct to D

reply 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.

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/
Nov 14 2011
next sibling parent reply Jerry <jlquinn optonline.net> writes:
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?
Nov 14 2011
parent Michael Kremser <mkspamx-usenet yahoo.de> writes:
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.
Nov 15 2011
prev sibling next sibling parent Bernard Helyer <b.helyer gmail.com> writes:
kbuild is almost certainly not linking in phobos. 
Nov 15 2011
prev sibling next sibling parent reply Iain Buclaw <ibuclaw ubuntu.com> writes:
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 wh=

 can look like that in C:

 static struct file_operations fops =3D {
 =A0 =A0 =A0 =A0.read =3D device_read,
 =A0 =A0 =A0 =A0.write =3D device_write,
 =A0 =A0 =A0 =A0.open =3D device_open,
 =A0 =A0 =A0 =A0.release =3D 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 {
 =A0 =A0 =A0 =A0int function() open;
 =A0 =A0 =A0 =A0int function() release;
 };

 In init_module() I have the following code:

 char[] DEVICE_NAME =3D "dtestdev";
 file_operations fops;
 fops.open =3D &device_open;
 fops.release =3D &device_close;
 Major =3D 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-=


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 --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Nov 15 2011
parent reply Michael Kremser <mkspamx-usenet yahoo.de> writes:
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
Nov 16 2011
parent Michael Kremser <mkspamx-usenet yahoo.de> writes:
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
Nov 17 2011
prev sibling parent Trass3r <un known.com> writes:
 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
Nov 16 2011