hello world my name is victor engelmann
and this is the second part of my
tutorial on linux kernel programming in
the first part we've downloaded the
linux source code compiled it
and booted this laptop with it and
in this second video i want to go into
the topic of kernel
modules well for example
drivers are kernel modules and since the
majority of code in
the linux kernel is for drivers
i think yeah kernel modules are an
important topic
okay the first thing that you need
when you want to write a kernel module
are the headers for your kernel
and yeah most distributions
don't install them by default but
they usually offer some package for you
to install
that contain these headers on manjaro
this
package is named linux
headers
and when i try to install them it
gives me this list of options which
headers to install
but since i'm running on a self-compiled
kernel here
i don't even have that problem when you
have compiled your kernel yourself then
you just have the headers so i can just
abort this on different distributions
this package might be named differently
it might be
kernel headers or on the raspberry pi
it's
called raspberry pi linux headers or
something
so yeah just google it and
i'm sure you will find the name of your
headers package for your distribution
let's write a little kernel module and
the other classic example is the hello
world module and
credit where credit is due this mostly
comes from
the linux kernel module
programming guide
so this is from peter j salzman michael
bourien and uri polans
i've seen several tutorials on this
topic which
just blatantly copied the code and
didn't
credit them for that and yeah i think
credit where credit is due so
we start with a c file because kernel
modules usually are written in c
and a make file
i will load them in
this nice little text editor called
kate
that i use often
okay now how do we
write a kernel module well the first
thing we need is
we need to include the header file
linux slash module.h and then
we basically need just to provide
two functions uh one function that is
called when the module is loaded
and one function that is called when the
module is
unloaded or removed so the
first one must return an end
and be marked with init
and we can name that whatever we want so
for example init hello
and it's important although it doesn't
get
any parameters so normally i would just
omit this void here but
the compiler options that i used for
compiling this
force you to put this void here okay so
let's just put that there
and when we return a zero that means
okay this module has successfully been
loaded
so um if anything goes wrong you might
return something
else like a status message that says
i don't know the device is busy or
something
okay then we also need
a function that returns nothing marked
with
exit
okay good
this is almost already sufficient for a
kernel module
to avoid any conflicts with the names
like if you had multiple modules with
the same names
that might cause problems so
you can mark these with static
so that these names are not exported and
then
yeah you cannot have any collisions with
these names
and now we need to incorporate two
preprocessor
macros module
in it with which we
tell the the system which of these
functions
is our initialization function
and which is our exit function
and then we need to also tell it the
license because yeah the
the kernel might react differently to
different
differently licensed modules like for
example
you could compile your kernel with an
option that
says i only want gpl
licensed modules i just don't allow
anything else
and then yeah the kernel would just
refuse to
load any modules that aren't gpl
licensed
so yeah we need to tell the kernel
about the license
okay now this was would already be
a legal module but it wouldn't do
anything so
yeah since this is a hello world module
it makes sense to print
a hello world
but yeah printf
is a function that's defined in the
glipc
and kernel modules are not linked
against the tree libc
so we cannot use that but
inside the kernel we have an alternative
that's called print k
as in kernel
okay
and now let's compile this
compiling this module is quite easy
you only need to uh
tell the make system
the name of this
c file here
except that you replace the c with an o
okay now that would be not much code for
a make file and yeah the thing is
that
this isn't actually the make file that
we are using
so the make file that we are actually
using is
in lib module
modules then the name of your kernel
build
you see that
here is a make file in that directory
and
when we call make
with dash c it means that
we actually want to run make in this
directory so then it will take this make
file
then we pass a variable
m which we fill with our current working
directory
yeah just to tell that make file to
pull the
this variable from that make file here
okay i hope that makes sense so
okay and
this has now compiled the kernel module
here this helloworld.ko as in kernel
object
that is the kernel module
and now i can load that module
okay and
if i list all the loaded modules now
it's a pretty long list but
up here the first entry you can see that
the kernel now tells me that hello world
is one of the modules that
are currently loaded and
with rm mod
hello world
you can unload the module again
notice that for
the ins mod i gave it the
physical location of the of the file
and for our mod i gave it the name of
the module here
as it is in this list
but you might have noticed one thing
when i
uh when i inserted this module
there is no output here it doesn't say
hello world although
i clearly told it i want to print hello
world
now the thing about kernel modules is of
course that they don't know
in which context you will run them so
you might run them on an iot device that
doesn't even have
a screen attached so why would it
try to to put any text on your screen
the print k function isn't supposed to
put text on your screen it prints that
text into the kernel log
you can examine that
with sudo the mask
for display message okay and up here
there is our hello world
and if i
if i remove the
module again then we have the goodbye
world here
in the hello world from from before
up there
this kernel lock at least this part of
the kernel lock
runs on a ring buffer that means
you have these 16 kilobytes of buffer
and messages are just written into it
but when it overflows then it just
starts overwriting stuff from the start
again
okay and with sudo
the message dash c you can clear the
ring buffer
now yeah this stuff here that's from my
sudo
command so that's just new stuff in
there
and with dash s
some number you can change the size of
the
ring buffer
okay now like this
you see that you only have 1.0 file
coming from one c file if you want to
have multiple source files which of
course is something that
you normally do when you're programming
you uh
your code usually just spans multiple
files
then you just give
your module some name like foo here and
then
you take that same name who with dash
objs for objects
and then you can list the
object files that correspond to your
source files
in this entry for the list
of objects that go into this foo
project
of course when you write a kernel module
or a driver or something
you probably want it to be loaded every
time your system starts
so how do you do that
well it depends on your distribution a
bit
because in system v in it this was
configurable
and yeah some different distributions
just did it differently so in system v
distributions you might need to
put an entry in a file like etsy modules
or in etsy rsc.modules
all right have a
file in etsy sus
config
modules and something like
hello world that
modules or something they would be
bash scripts that would be executed
at the system start
but uh yeah most distributions these
days use
system d in it and with systemd there is
luckily
only one location where
these things are so you would
create a file in etsy
modulesload.d let's call it
helloworld.conf
okay and in here you would just say
i want hello world to be loaded at
system start
now the problem here is that
this would load the module using the
command
mod probe so it would do sudo mod
probe hello
world okay and
yeah as you can see now
um it says it didn't find hello world
because uh it's not looking in the right
location it once that file
it's looking for that file in this
directory lib modules
and then the name of your kernel
so to solve that problem
you would copy
your module
two lip modules
then the name of your kernel
okay now
if you try to mod probe now it will
still fail
because modprobe also has some
cache of the modules that are in there
so
you first need to update that cache with
sudo dapmod
a
okay now if i sudo mod probe hello world
this has now worked so
here is my hello world
and i can unload that module again so
yeah let's just try if that works and
reboot this computer
okay the computer has now rebooted so
let's
see
see here we have the hello world and if
i
call at smart
might not be the first this time
let's sort the output
there hello world
of course sometimes you need to pass
parameters to a kernel module just like
you need to pass parameters to a program
because you don't want to hard code
everything sometimes you need to
make something configurable at runtime
or so
and linux comes with some
useful preprocessor macros
module parameter a name for
your parameter a type
and yeah just put this to zero here for
now
i don't want to go into what this is
right now
and if you want to you can also give it
a description
make sure you have only palm here but
param here it's a bit confusing but okay
so description
and we also need to reserve the memory
for that
we can leave it like this so without
setting the variable to some default
value but
yeah we should better give it a default
value because otherwise
the module will cause problems maybe
crash
if we
if we insert that module and not give it
a
value for that parameter
okay
build it
okay we can
we can now insert it without
a parameter
and yeah here's one hello world because
the default value
was one right so
normally we print hello world once
but
we can now also give it a parameter
and now we have printed it three times
and when you want to automatically load
this module now
you can then just in this configuration
file
just put the parameter
just the same
okay i think that's enough for this
video
if you liked this video like it share it
subscribe and when you're watching these
videos
please consider turning off your ad
blocker that would help me a lot
yeah next time i'm going to take this
topic a bit further and
turn this kernel module into an actual
driver for an external
device i think that's going to be
interesting so
definitely don't miss that and until
then
see you next time and goodbye world