1
00:00:00,005 --> 00:00:02,002
- [Instructor] All right, now you're going to get

2
00:00:02,002 --> 00:00:05,004
to update your LinkedIn profile

3
00:00:05,004 --> 00:00:09,007
or your resume, saying that you're a kernel developer.

4
00:00:09,007 --> 00:00:10,008
You write kernel code

5
00:00:10,008 --> 00:00:11,007
'cause we're going to show you how

6
00:00:11,007 --> 00:00:15,006
to write a loadable kernel module.

7
00:00:15,006 --> 00:00:19,001
So one of the things that's an essential is

8
00:00:19,001 --> 00:00:21,008
to a compile a kernel module,

9
00:00:21,008 --> 00:00:25,005
you have to use the kernel makefile

10
00:00:25,005 --> 00:00:28,001
and you need to use the kernel makefile that goes

11
00:00:28,001 --> 00:00:33,000
with the kernel that you want to load the module into.

12
00:00:33,000 --> 00:00:34,000
Underneath lib modules,

13
00:00:34,000 --> 00:00:38,000
your kernel version should be a soft link called build

14
00:00:38,000 --> 00:00:41,009
that will point to a directory

15
00:00:41,009 --> 00:00:43,005
for the kernel makefile,

16
00:00:43,005 --> 00:00:47,000
which will have a config file and everything you need.

17
00:00:47,000 --> 00:00:51,004
And then we got to tell the kernel makefile

18
00:00:51,004 --> 00:00:54,000
with this capital M here

19
00:00:54,000 --> 00:00:57,006
in what directory to do the make,

20
00:00:57,006 --> 00:00:59,004
and then what we're making is modules.

21
00:00:59,004 --> 00:01:02,009
So we're making modules in the current directory,

22
00:01:02,009 --> 00:01:05,006
using the kernel makefile.

23
00:01:05,006 --> 00:01:08,000
And the kernel makefile will look

24
00:01:08,000 --> 00:01:10,007
in your current directory for another makefile.

25
00:01:10,007 --> 00:01:13,000
So you have to have a makefile in your directory along

26
00:01:13,000 --> 00:01:15,003
with the code for your module.

27
00:01:15,003 --> 00:01:18,005
So your module will be a C program

28
00:01:18,005 --> 00:01:22,002
and in the makefile, you can just have one little line.

29
00:01:22,002 --> 00:01:26,009
OBJ-M: equals the name of the module, dot O,

30
00:01:26,009 --> 00:01:29,007
not KO, not C, dot O.

31
00:01:29,007 --> 00:01:32,006
And the kernel makefile knows how to make a dot O

32
00:01:32,006 --> 00:01:36,007
from a dot C and it knows how to make a kernel object file

33
00:01:36,007 --> 00:01:38,001
from a dot O.

34
00:01:38,001 --> 00:01:40,005
So that's all you need.

35
00:01:40,005 --> 00:01:44,007
One of the key things for compiling a loadable,

36
00:01:44,007 --> 00:01:47,004
kernel module is the header files right?

37
00:01:47,004 --> 00:01:49,003
For any C program, you need header files

38
00:01:49,003 --> 00:01:50,008
and it's essential

39
00:01:50,008 --> 00:01:53,009
that you're using the kernel header files

40
00:01:53,009 --> 00:01:56,004
from the kernel you're building a module for.

41
00:01:56,004 --> 00:02:00,007
That's part of why you got to give the path

42
00:02:00,007 --> 00:02:02,009
to the kernel makefile.

43
00:02:02,009 --> 00:02:07,005
That build will have the header files for your kernel.

44
00:02:07,005 --> 00:02:10,007
And again, the configuration choices

45
00:02:10,007 --> 00:02:12,009
for the kernel are there, and that's essential too

46
00:02:12,009 --> 00:02:15,009
'cause when you build stuff for the kernel,

47
00:02:15,009 --> 00:02:20,005
it's going to make use of kernel configuration options.

48
00:02:20,005 --> 00:02:22,009
Now if you're on like Ubuntu

49
00:02:22,009 --> 00:02:25,009
and you're using apt for install stuff,

50
00:02:25,009 --> 00:02:28,001
you can install Linux headers,

51
00:02:28,001 --> 00:02:30,004
Linux headers dash kernel version.

52
00:02:30,004 --> 00:02:34,000
But you might need to do a dash dash reinstall

53
00:02:34,000 --> 00:02:36,006
to make sure you're getting the header files

54
00:02:36,006 --> 00:02:39,007
for your current kernel version.

55
00:02:39,007 --> 00:02:42,008
Now this is a big deal.

56
00:02:42,008 --> 00:02:46,000
This little snippet here is a complete,

57
00:02:46,000 --> 00:02:49,003
loadable kernel module source file.

58
00:02:49,003 --> 00:02:52,003
Of course it's just a skeleton, but it's complete.

59
00:02:52,003 --> 00:02:55,006
So we're calling this simple module C.

60
00:02:55,006 --> 00:02:58,007
We got three header files here

61
00:02:58,007 --> 00:03:00,007
and then we got two prototypes.

62
00:03:00,007 --> 00:03:05,004
For a module, you want to have two special functions at least.

63
00:03:05,004 --> 00:03:07,008
One is an initialization function

64
00:03:07,008 --> 00:03:09,009
and one is a cleanup function.

65
00:03:09,009 --> 00:03:11,004
The initialization function's called

66
00:03:11,004 --> 00:03:14,003
when the module's loaded and the cleanup is called,

67
00:03:14,003 --> 00:03:17,001
if and when it's ever removed.

68
00:03:17,001 --> 00:03:19,002
So you can call your initialization function,

69
00:03:19,002 --> 00:03:20,009
kind of whatever you want,

70
00:03:20,009 --> 00:03:22,006
and then we'll register it below.

71
00:03:22,006 --> 00:03:26,002
So we got a prototype for it, compiler wants that.

72
00:03:26,002 --> 00:03:27,008
Here, we just do a print K.

73
00:03:27,008 --> 00:03:30,002
You don't do print F in the kernel.

74
00:03:30,002 --> 00:03:32,003
There's no window for the kernel to print in.

75
00:03:32,003 --> 00:03:35,004
Remember it prints in a buffer that you can see

76
00:03:35,004 --> 00:03:38,002
with D message or would show up on the console.

77
00:03:38,002 --> 00:03:39,000
So you do a print K.

78
00:03:39,000 --> 00:03:41,001
Most of the arguments and so forth are like print F,

79
00:03:41,001 --> 00:03:44,001
but this is just a string with a new line at the end.

80
00:03:44,001 --> 00:03:47,004
And then you return zero from your init function

81
00:03:47,004 --> 00:03:49,005
to represent success.

82
00:03:49,005 --> 00:03:51,007
I initialized successfully.

83
00:03:51,007 --> 00:03:53,001
And then you have a cleanup function.

84
00:03:53,001 --> 00:03:56,002
It has no return value, you can't fail on a cleanup.

85
00:03:56,002 --> 00:03:58,009
This is happening, sometimes like

86
00:03:58,009 --> 00:04:00,005
if you're rebooting or something like that.

87
00:04:00,005 --> 00:04:02,003
So can't get out of it

88
00:04:02,003 --> 00:04:05,007
and there's no parameters to either of these functions.

89
00:04:05,007 --> 00:04:09,002
But we'll do another print K in there.

90
00:04:09,002 --> 00:04:12,005
Then we use the macro module underscore init

91
00:04:12,005 --> 00:04:14,008
to register the function we're using

92
00:04:14,008 --> 00:04:16,004
for initialization function,

93
00:04:16,004 --> 00:04:19,002
and the macro module underscore exit

94
00:04:19,002 --> 00:04:21,000
to register the function we're using

95
00:04:21,000 --> 00:04:23,003
as our cleanup function.

96
00:04:23,003 --> 00:04:24,006
And then all in capital areas,

97
00:04:24,006 --> 00:04:28,006
we're using this macro module license,

98
00:04:28,006 --> 00:04:31,008
GPL there to say what our license is.

99
00:04:31,008 --> 00:04:34,006
And that actually makes a difference.

100
00:04:34,006 --> 00:04:38,008
Modules that have like proprietary licenses are restricted

101
00:04:38,008 --> 00:04:42,001
from some of the API in the kernel.

102
00:04:42,001 --> 00:04:49,000
So if you can make your module GPL, then it'll be handy.

103
00:04:49,000 --> 00:04:54,006
So we put that in a file called simple module dot C

104
00:04:54,006 --> 00:04:57,005
and then we can create a makefile with just one line in it.

105
00:04:57,005 --> 00:05:02,001
Here's an easy way, we just echo OBJ-M: = simplemodule.o

106
00:05:02,001 --> 00:05:03,004
in the makefile.

107
00:05:03,004 --> 00:05:06,006
That creates the makefile and it's got the one line in it.

108
00:05:06,006 --> 00:05:08,008
Then we're going to compile that like we talked about,

109
00:05:08,008 --> 00:05:10,001
make minus capital C,

110
00:05:10,001 --> 00:05:14,002
that changes directory to this directory build points to

111
00:05:14,002 --> 00:05:15,009
and uses the makefile there.

112
00:05:15,009 --> 00:05:17,006
That's the kernel makefile.

113
00:05:17,006 --> 00:05:19,008
The kernel makefile will refer

114
00:05:19,008 --> 00:05:22,005
to the variable you set here, capital M,

115
00:05:22,005 --> 00:05:25,003
and go back to that directory and look for a makefile.

116
00:05:25,003 --> 00:05:27,001
That's what we just made

117
00:05:27,001 --> 00:05:30,000
and it'll make all the modules referred to

118
00:05:30,000 --> 00:05:30,009
in that makefile.

119
00:05:30,009 --> 00:05:34,005
And that OBJ dash M has to do with, this is a list

120
00:05:34,005 --> 00:05:37,007
of modules to make and we're making modules.

121
00:05:37,007 --> 00:05:39,008
That's the target of the kernel makefile.

122
00:05:39,008 --> 00:05:42,002
Make modules in this directory,

123
00:05:42,002 --> 00:05:44,007
using the makefile in that directory.

124
00:05:44,007 --> 00:05:50,007
So if all goes well, you will get a simplemodule.ko file,

125
00:05:50,007 --> 00:05:53,004
and you can insmod it.

126
00:05:53,004 --> 00:05:55,008
And then you can rmmod it.

127
00:05:55,008 --> 00:06:00,001
And if you do dmesg and look at the recent messages printed,

128
00:06:00,001 --> 00:06:03,001
you should see the output from the print case

129
00:06:03,001 --> 00:06:05,000
from your modules.

130
00:06:05,000 --> 00:06:06,000
Pretty darn cool.

