Driver building in C++?

Hi,
I want to compile my code in C++ (because this is what I know and I am doing an experiment), but the standard makefile '.include <bsd.kmod.mk>' works only with the C compiler. At this stage, I do not have any idea about the various bits of code that must be linked and that is why I cannot simply write my own makefile.

This is the test code that I am wanting to compile:

Code:
// test module event handler

#include <iostream>
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>

static int hello_modevent(module_t mod__unused, int event, void *arg__unused)
{
  int error = 0;
  switch(event)
    {
    case MOD_LOAD:
      std::cout << "Hello, world!" << std::endl;
break;
case MOD_UNLOAD:
  std::cout << "Good-bye, cruel world" << std::endl;
  break;
  
    default:
      error = EOPNOTSUPP;
      break;
    }
  return(error);
}

static moduledata_t hello_mod=
  {
    "hello",
    hello_modevent,
NULL
  };

DECLARE_MODULE(hello, hello_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);

This is the Makefile - which currently does not work:

Code:
KMOD=	hello
SRCS=	hello.cpp

.include <bsd.kmod.mk>

The file <bsd.kmod.mk> does not seem to contain anything that prevents compilation in C++, but it includes <bsd.sys.mk> which seems to be where the problems come from. The first thing I would like to do is to simply use g++ and to remove all the references to c etc.

Can you help me to write a working makefile so I can use KLD via a C++ coded module?

What libraries would I need to link?
 
I don't believe that developing KLD using C++ is good idea.
However, I would start redefining the CC (compiler) to point to g++. And the setting CFLAGS+= your libraries could suffice. The problem is that a lot of CFLAGS for the KLD are valid for C compilers and not for C++, so you should try defining the CFLAGS from scratch.

Therefore something like the following:

Code:
CFLAGS+=-Imycpp.so                                                                        
CC=g++ 
KMOD=	hello
SRCS=	hello.cpp

.include <bsd.kmod.mk>
 
You would at least have to provide the API functions of your module using "C" linkage. In other words the exported symbols of the module can not have C++ name mangling. This is usually accompished by declaring the functions in an extern "C" block in the header file:


Code:
#if defined(__cplusplus)
extern "C" {
endif

extern int myfunc(int foo);
....

#if defined(__cplusplus)
}
#endif
 
because this is what I know and I am doing an experiment

Unless you're willing to enhance kernel C++ support, that sort of "experiment" will be futile. STL, exceptions, multiple inheritance, none of those will work.

FreeBSD kernel programming - C. Nothing else. If you're missing object-oriented ways of C++, check out kobj, eg. FreeBSD kernel objects.
 
Zare said:
Unless you're willing to enhance kernel C++ support, that sort of "experiment" will be futile. STL, exceptions, multiple inheritance, none of those will work.

FreeBSD kernel programming - C. Nothing else. If you're missing object-oriented ways of C++, check out kobj, eg. FreeBSD kernel objects.

Well, the only valid point in using C++ is to reuse an existing library, but it means that the kernel module code must act as a wrapper for such library.
However, I agree that KLD should be C-only. Well, all operating system development should be C-only but this is going quickly off topic....
 
fluca1978 said:
Well, the only valid point in using C++ is to reuse an existing library, but it means that the kernel module code must act as a wrapper for such library.
However, I agree that KLD should be C-only. Well, all operating system development should be C-only but this is going quickly off topic....

Why? - Just as this is a nice sound bite? Will you tell the clang project to re-write their code in c?
 
neilms said:
Why? - Just as this is a nice sound bite? Will you tell the clang project to re-write their code in c?

clang is not an operating system. I'd say that kernel development should be C only also as it is lower level than C++.

I'm no C++ expert, but generally it breaks down to this:

  • C++ provides many ambiguous ways to shoot yourself in the foot
  • Operating system development is already hard (and prone to bugs)

Thus, a simpler, less ambiguous language is preferred.

For applications (such as clang), sure, C++ or Objective-C provide benefits.
 
There's also the issue of C++ runtime. There's none of that available in kernel space. That means you would have to link your driver module statically with all the C++ runtime code and that would make the compiled binary quite large.
 
kpa said:
There's also the issue of C++ runtime. There's none of that available in kernel space. That means you would have to link your driver module statically with all the C++ runtime code and that would make the compiled binary quite large.

This is not a real problem at all! A few extra kilobytes perhaps is what we are really talking about.
 
If you tried writing a KLD in C++, you would probably just end up misusing the language.

For example, you have no C++ bindings to the underlying C libraries (which would be a lot of work to implement).

Exception propagation would have serious problems.

The DECLARE_MODULE macro is already incorrect C++. Instead you should be using templates. Macros are a C thing.
 
kpedersen said:
If you tried writing a KLD in C++, you would probably just end up misusing the language.

For example, you have no C++ bindings to the underlying C libraries (which would be a lot of work to implement).

Exception propagation would have serious problems.

The DECLARE_MODULE macro is already incorrect C++. Instead you should be using templates. Macros are a C thing.

This demonstrates your lack of understanding of C++. In any event I never said that I wanted to use any advanced C++ features at all. I will leave you all to theorize and pontificate about all imaginable obstacles and just get on and do what I planned.
 
Search the -hackers, -stable, and -current mailing list archives. There's been a few attempts at doing this in the past. None have gotten anywhere productive.
 
neilms said:
This is not a real problem at all! A few extra kilobytes perhaps is what we are really talking about.

Actually its not an issue of just linking extra kilobytes, the runtime will just simply not work in kernel space. You need to port/tailor it for specific kernels and then maintain it. Might as well use that time to improve the driver itself in C..
 
expl said:
Might as well use that time to improve the driver itself in C..
Good point.

As always, use the right tool for the job. If one wishes to do kernel hacking (including device drivers), one should use C. Far be it for me to say that C++ is useless (I do find it syntactically ugly but that's a matter of taste, not to mention completely besides the point here) but for kernel hacking and device driver development it's just not the right tool. If on the other hand you wish to create a GUI-driven application interfacing with a database, both C++ and Java might very well be better choices than C. Moreover, if you need to do lots of recursive calculations, perhaps Haskell is a better choice than any imperative programming language anyway. Again: right tool, job, blah blah blah.
 
neilms said:
Why? - Just as this is a nice sound bite? Will you tell the clang project to re-write their code in c?

Good luck writing your KLD in C++!
I personally love both C and C++, even if I admit they are quite different.
I believe you are not the first to try to inject OOP into the kernel (even not a BSD one) and I guess you will fail. Operating systems are not a good OOP playground, at least to the meaning OOP has for a lot of developers (you can do OOP programming even without classes...).
Of course you are free to prove we are all wrong on this and that even the kernel hackers are so remendously and religiously obtuse to refuse to adopt OOP within the kernel. The fact that you confuse clang with KLD tells to me that you did not do a deep analysis on the KLD/operating system subject, but that's my opinion. You also stated that your aim is not to use any advanced C++ feature (e.g., exceptions?, templates?, what?), so you are using C++-- for your aim, that sounds to me that probably you are lacking some design property that will allow you to go on pure C.
But hey, ust write your code and prove us we are wrong.
And we will be happy to admit it.
 
neilms said:
A few extra kilobytes perhaps is what we are really talking about.
I have not dealt with close to the metal code in a long time but I know such talk will you thrown out of any kernel developer's room with that statement.

The core of Windows is written in C. So is Linux and FreeBSD and just about everything else. You'd have to do some hard searching to find one low level stuff in C++. There's a reason for that but the last time I dealt with that I was dealing with bits and not bytes so I won't comment further.
 
drhowarddrfine said:
I have not dealt with close to the metal code in a long time but I know such talk will you thrown out of any kernel developer's room with that statement.

The core of Windows is written in C. So is Linux and FreeBSD and just about everything else. You'd have to do some hard searching to find one low level stuff in C++. There's a reason for that but the last time I dealt with that I was dealing with bits and not bytes so I won't comment further.

I know, a lot of people still think that Mac OS X is not a real OS, but only a kids playground. I do not want to start a flame war here, so, I do not contest this. Anyway, Mac OS X (Darwin)'s IOKit is an object-oriented framework consisting primarily of dozens, if not hundreds, of C++ classes.

I wrote a Kernel Extension (.kext) on Mac OS X for a National Instruments PCI-DAQ board using IOKit C++. It is extremely well documented, and it worked without a major pain in the ass.

Recently, I completed a similar exercise on FreeBSD, writing a Loadable Kernel Module KLD (.ko) for the same NI-PCI-DAQ board in C. This, took me longer to understand the basics, and to get it to work correctly. I still have an issue with DMA.

C++ is suitable for writing kernel stuff, as Apple's IOKit may demonstrate - if not to all - so at least to some of us. In general I prefer C over C++, though.

At the bottom-line, I use the language that is most suitable to get the task done on a given system.

Also, I was under the impression, that all kind of language flames came out of fashion already in the 80's, after this ultimate write-up about Real Programmers cleaned-up with all possible mis-conceptions on programming. :)
 
I am a massive C++ evangelist (I also teach it at University) however, I still wouldn't suggest using it for kernel development in FreeBSD, mostly because the code base is complex enough without mixing more languages in there.

I am not a fan of people adding more language dependencies to a project for the sake of them loving a language.
 
rolfheinrich said:
I know, a lot of people still think that Mac OS X is not a real OS, but only a kids playground. I do not want to start a flame war here, so, I do not contest this. Anyway, Mac OS X (Darwin)'s IOKit is an object-oriented framework consisting primarily of dozens, if not hundreds, of C++ classes.
IOKit is:
...a restricted form of C++ that omits features unsuitable for use within a multithreaded kernel. By modeling the hardware connected to an OS X system and abstracting common functionality for devices in particular categories, the I/O Kit streamlines the process of device-driver development.
 
kpedersen said:
I am a massive C++ evangelist (I also teach it at University) however, I still wouldn't suggest using it for kernel development in FreeBSD, mostly because the code base is complex enough without mixing more languages in there.

I am not a fan of people adding more language dependencies to a project for the sake of them loving a language.

Also, if you ever want to get your work integrated into the official release, I doubt you'll ever succeed with C++.
 
Back
Top