1
00:00:00,006 --> 00:00:03,007
- [Instructor] Let's look at driver source stuff,

2
00:00:03,007 --> 00:00:05,001
a little bit in the kernel.

3
00:00:05,001 --> 00:00:06,001
First of all, let's figure

4
00:00:06,001 --> 00:00:10,007
out what ethernet devices we have.

5
00:00:10,007 --> 00:00:12,004
So we've got a few there

6
00:00:12,004 --> 00:00:14,008
and then we've got this kind of real one,

7
00:00:14,008 --> 00:00:17,000
even though we're in a VM.

8
00:00:17,000 --> 00:00:26,003
This ENP thing, let's find out more about that.

9
00:00:26,003 --> 00:00:31,004
And it tells us the driver is MLX5 core.

10
00:00:31,004 --> 00:00:35,006
All right, so let's see if there's a loadable module

11
00:00:35,006 --> 00:00:40,004
with that name.

12
00:00:40,004 --> 00:00:44,007
Yep. Sure enough, there's a module with that name loaded.

13
00:00:44,007 --> 00:00:48,005
So the driver for that ethernet was built

14
00:00:48,005 --> 00:00:51,006
as a loadable kernel module.

15
00:00:51,006 --> 00:00:55,001
Let's see if we can go find the source code for that.

16
00:00:55,001 --> 00:01:05,005
If we find dot name mlx5 underscore core.

17
00:01:05,005 --> 00:01:11,000
Oops. We don't pipe into slash name.

18
00:01:11,000 --> 00:01:12,002
All right, we've got a bunch of stuff

19
00:01:12,002 --> 00:01:15,009
underneath drivers net.

20
00:01:15,009 --> 00:01:28,004
So let's go to drivers net ethernet mellanox mlx5 core.

21
00:01:28,004 --> 00:01:29,006
Now we got lots of stuff.

22
00:01:29,006 --> 00:01:32,002
Now I already did a full build in here,

23
00:01:32,002 --> 00:01:37,005
so I got lots of object files along with the source files.

24
00:01:37,005 --> 00:01:42,007
There's a make file in here. Let's look at the make file.

25
00:01:42,007 --> 00:01:47,004
And we see here on line nine,

26
00:01:47,004 --> 00:01:51,001
obj dash value of some variable,

27
00:01:51,001 --> 00:01:55,004
plus equals mlx5 underscore core dot 0.

28
00:01:55,004 --> 00:01:57,008
Turns out that macro config,

29
00:01:57,008 --> 00:02:02,006
mlx5 underscore core will be the letter M

30
00:02:02,006 --> 00:02:04,009
when we configure this to be a module.

31
00:02:04,009 --> 00:02:07,008
So that will be OBJ dash M,

32
00:02:07,008 --> 00:02:10,008
plus equals MLX five underscore core dot 0.

33
00:02:10,008 --> 00:02:14,000
So it's going to add to the list of modules to be built,

34
00:02:14,000 --> 00:02:17,005
the mlx5 underscore core dot 0.

35
00:02:17,005 --> 00:02:22,001
And then it turns out we've got all kinds of dot 0s

36
00:02:22,001 --> 00:02:24,009
in the file here that will get added in

37
00:02:24,009 --> 00:02:29,000
to make that mlx5 underscore core.

38
00:02:29,000 --> 00:02:33,002
All right, so this is where it's built.

39
00:02:33,002 --> 00:02:35,004
Now what about our config?

40
00:02:35,004 --> 00:02:43,004
Let's grep that config mlx5 underscore core.

41
00:02:43,004 --> 00:02:45,006
That's what was in the make file.

42
00:02:45,006 --> 00:02:49,008
We're going to grep that in our dot config

43
00:02:49,008 --> 00:02:57,008
to see how our kernel is configured with respect to that.

44
00:02:57,008 --> 00:03:00,007
And there we see, it's set to M, like I said.

45
00:03:00,007 --> 00:03:04,002
It's configured to be a loadable module.

46
00:03:04,002 --> 00:03:06,002
All right, so this is a loadable module.

47
00:03:06,002 --> 00:03:09,000
There should be a module, a net function in here somewhere.

48
00:03:09,000 --> 00:03:16,003
Let's see if we can find that.

49
00:03:16,003 --> 00:03:19,000
There's a couple. Let's look at main dot C.

50
00:03:19,000 --> 00:03:22,006
That's probably the main for the driver.

51
00:03:22,006 --> 00:03:26,001
And I was looking at this before,

52
00:03:26,001 --> 00:03:31,008
but if we look at module init,

53
00:03:31,008 --> 00:03:35,001
this is 2,351 lines long.

54
00:03:35,001 --> 00:03:38,007
Second line from the bottom registers the mlx5,

55
00:03:38,007 --> 00:03:41,001
underscore init as the initialization function.

56
00:03:41,001 --> 00:03:46,005
Now let's go look at that.

57
00:03:46,005 --> 00:03:50,008
That's up on line 2,307.

58
00:03:50,008 --> 00:03:53,005
So this is the function that gets called

59
00:03:53,005 --> 00:03:55,005
when the module is loaded.

60
00:03:55,005 --> 00:03:59,002
So you can see it does maybe a little warning,

61
00:03:59,002 --> 00:04:03,008
does some sort of random bits, registers some stuff,

62
00:04:03,008 --> 00:04:08,001
all right, registers it as a PCI driver

63
00:04:08,001 --> 00:04:11,007
and then just check it for errors throughout.

64
00:04:11,007 --> 00:04:14,005
And if it gets an error, it does some cleanup stuff

65
00:04:14,005 --> 00:04:17,000
and then it returns the error.

66
00:04:17,000 --> 00:04:20,005
So that could be minus one or minus two or minus three

67
00:04:20,005 --> 00:04:23,002
or something like that, depending on what the error was.

68
00:04:23,002 --> 00:04:27,000
All right, so that's the mellanox driver

69
00:04:27,000 --> 00:04:29,004
for our ethernet card.

70
00:04:29,004 --> 00:04:37,008
Let's look at that mem dot C.

71
00:04:37,008 --> 00:04:40,007
And let's use cscope.

72
00:04:40,007 --> 00:04:44,006
All right, so we know the name of a function.

73
00:04:44,006 --> 00:04:50,000
Let's look for the definition. How about write null.

74
00:04:50,000 --> 00:04:52,002
Only one of those apparently, it brings us right to it.

75
00:04:52,002 --> 00:04:53,004
Boom, just like that.

76
00:04:53,004 --> 00:04:56,007
Notice read null is right above it.

77
00:04:56,007 --> 00:05:00,009
So just like we saw, the right null just returns the number

78
00:05:00,009 --> 00:05:06,008
of bytes you asked for and read null just returns zero.

79
00:05:06,008 --> 00:05:09,000
Pretty simple, right?

80
00:05:09,000 --> 00:05:13,005
Now how does it know to use these functions?

81
00:05:13,005 --> 00:05:20,005
Well, let me show you a little bit more.

82
00:05:20,005 --> 00:05:22,009
So what a character driver does is,

83
00:05:22,009 --> 00:05:27,005
it registers a struct file operations

84
00:05:27,005 --> 00:05:31,005
and in that struct, it has the address of the functions

85
00:05:31,005 --> 00:05:37,003
that it wants to implement that are part of the file API.

86
00:05:37,003 --> 00:05:42,005
So null implements lseek, read, write,

87
00:05:42,005 --> 00:05:46,005
some iterations, a splice and a U ring command, right?

88
00:05:46,005 --> 00:05:48,003
There's potentially a lot more things,

89
00:05:48,003 --> 00:05:52,002
like M map, didn't implement.

90
00:05:52,002 --> 00:05:55,001
So these are just the ones it implemented.

91
00:05:55,001 --> 00:05:57,008
So you should be able to do any of these with dev null.

92
00:05:57,008 --> 00:05:59,000
If you do one of the others,

93
00:05:59,000 --> 00:06:00,006
it'll just do a default kind of thing

94
00:06:00,006 --> 00:06:02,008
and that might be returning

95
00:06:02,008 --> 00:06:06,003
with an error saying not implemented.

96
00:06:06,003 --> 00:06:08,001
So there is an lseek.

97
00:06:08,001 --> 00:06:11,006
Why don't we just go ahead and look at that.

98
00:06:11,006 --> 00:06:17,000
That's called when you try to seek on a device.

99
00:06:17,000 --> 00:06:20,007
And what the null one does is just set the position to zero.

100
00:06:20,007 --> 00:06:23,000
Every time you call, every time you try to move it, oh,

101
00:06:23,000 --> 00:06:27,002
move the pointer to 100, offset to 100 into the file,

102
00:06:27,002 --> 00:06:30,001
it just sets it to zero and returns back zero,

103
00:06:30,001 --> 00:06:33,004
saying you're at zero no matter what you do.

104
00:06:33,004 --> 00:06:36,009
And the comment here is kind of interesting.

105
00:06:36,009 --> 00:06:41,003
It says now you can open in append mode.

106
00:06:41,003 --> 00:06:43,008
So append mode needed the lseek.

107
00:06:43,008 --> 00:06:46,005
So you can't really append the dev null.

108
00:06:46,005 --> 00:06:47,003
You try to append,

109
00:06:47,003 --> 00:06:49,003
it'll just, you know, when you do the write,

110
00:06:49,003 --> 00:06:51,007
just say it did it write like we saw.

111
00:06:51,007 --> 00:06:55,003
But the open should work. There you go.

112
00:06:55,003 --> 00:07:00,000
That was delving into some kernel source code for drivers.

