1
00:00:00,005 --> 00:00:02,003
- [Instructor] Let's briefly talk about

2
00:00:02,003 --> 00:00:07,002
Linux kernel source code underneath drivers.

3
00:00:07,002 --> 00:00:10,001
So if you do a list underneath the driver subdirectory,

4
00:00:10,001 --> 00:00:12,009
you'll see a lot and lots of sub directories

5
00:00:12,009 --> 00:00:15,007
and sub directories within sub directories and so forth.

6
00:00:15,007 --> 00:00:20,004
There are many, many drivers written for Linux.

7
00:00:20,004 --> 00:00:24,001
Linux is well-supported by lots of hardware.

8
00:00:24,001 --> 00:00:27,003
Some of the drivers aren't actually hardware drivers.

9
00:00:27,003 --> 00:00:33,000
They're pseudo drivers, like for devno,

10
00:00:33,000 --> 00:00:35,005
which we'll talk about in a second.

11
00:00:35,005 --> 00:00:38,005
Common hardware devices are ethernet devices

12
00:00:38,005 --> 00:00:42,005
and there's quite a few available for Linux.

13
00:00:42,005 --> 00:00:47,004
If you want to find out which driver your ethernet devices

14
00:00:47,004 --> 00:00:52,008
are using, you can first of all try ip addr

15
00:00:52,008 --> 00:00:55,005
to see the names of your interfaces,

16
00:00:55,005 --> 00:01:00,003
and then try ethtool -i name of an interface

17
00:01:00,003 --> 00:01:04,003
to see which driver as well as some other information

18
00:01:04,003 --> 00:01:07,002
goes with that interface.

19
00:01:07,002 --> 00:01:12,005
So remember, the device file dev null had major number one.

20
00:01:12,005 --> 00:01:14,005
It had a device driver.

21
00:01:14,005 --> 00:01:20,002
Well, that actually gets implemented in driver's char mem.c,

22
00:01:20,002 --> 00:01:24,002
along with the other, we'll call sibling drivers,

23
00:01:24,002 --> 00:01:28,005
dev zero and so forth.

24
00:01:28,005 --> 00:01:35,007
Writing the read and write for dev null, it's pretty easy.

25
00:01:35,007 --> 00:01:39,002
So if you cat dev null, what's going to happen?

26
00:01:39,002 --> 00:01:41,009
The cat command's going to open it,

27
00:01:41,009 --> 00:01:45,000
gets back a file descriptor, and then it calls read

28
00:01:45,000 --> 00:01:47,009
with that file descriptor and it's cat.

29
00:01:47,009 --> 00:01:50,001
So it's going to give it a buffer

30
00:01:50,001 --> 00:01:53,006
and it's going to ask for a bunch of bytes.

31
00:01:53,006 --> 00:01:57,003
And when that read function goes into the kernel,

32
00:01:57,003 --> 00:02:00,008
the kernel, through indirection, will know

33
00:02:00,008 --> 00:02:04,000
to call the read function from dev null.

34
00:02:04,000 --> 00:02:07,008
The open sets up the data structure needed by the kernel.

35
00:02:07,008 --> 00:02:11,000
So that file descriptor is actually a subscript

36
00:02:11,000 --> 00:02:15,005
into a table, and in there is a pointer

37
00:02:15,005 --> 00:02:17,005
to a structure that's got the address

38
00:02:17,005 --> 00:02:19,004
of the read function to call.

39
00:02:19,004 --> 00:02:21,003
So it turns out the read function

40
00:02:21,003 --> 00:02:24,002
for dev null is called read_null,

41
00:02:24,002 --> 00:02:27,007
and it's in the mem.c file.

42
00:02:27,007 --> 00:02:31,001
And here's what it looks like.

43
00:02:31,001 --> 00:02:34,005
So it returns a size t, read returns

44
00:02:34,005 --> 00:02:37,007
the number of bytes read, it'll return zero

45
00:02:37,007 --> 00:02:40,009
at end of file, saying there's no more bytes to read.

46
00:02:40,009 --> 00:02:45,009
And what the kernel passes is a pointer to a struct file.

47
00:02:45,009 --> 00:02:49,002
So it's not a file descriptor, it's been interpreted

48
00:02:49,002 --> 00:02:53,003
to be a pointer to one of these data structures.

49
00:02:53,003 --> 00:02:57,001
It does point the user buffer.

50
00:02:57,001 --> 00:03:00,005
Got that pointer, and the number of bytes asked

51
00:03:00,005 --> 00:03:03,008
for the count, and then a pointer

52
00:03:03,008 --> 00:03:06,002
to where we are in the file

53
00:03:06,002 --> 00:03:09,005
so that a driver could keep track of where it is.

54
00:03:09,005 --> 00:03:11,007
So the next time you call read,

55
00:03:11,007 --> 00:03:13,005
you start from where you left off.

56
00:03:13,005 --> 00:03:16,005
But read null doesn't need to deal with that.

57
00:03:16,005 --> 00:03:19,001
It just always returns end of file.

58
00:03:19,001 --> 00:03:20,009
It doesn't care how many bytes you ask for,

59
00:03:20,009 --> 00:03:26,004
it doesn't care what position was, it just returns zero.

60
00:03:26,004 --> 00:03:30,000
How easy is that? So think about it for a second.

61
00:03:30,000 --> 00:03:34,009
What should write do? Well, let's look at write.

62
00:03:34,009 --> 00:03:38,001
So if we say echo hi into dev null,

63
00:03:38,001 --> 00:03:42,001
the shell's going to open up dev null for writing.

64
00:03:42,001 --> 00:03:45,000
So it'll call open.

65
00:03:45,000 --> 00:03:49,001
And then, when we do the echo, it's going to do a write.

66
00:03:49,001 --> 00:03:51,008
And again, open return to file descriptor.

67
00:03:51,008 --> 00:03:55,003
So that's how the kernel's going to know which write function

68
00:03:55,003 --> 00:03:59,002
to call when we pass in a buffer

69
00:03:59,002 --> 00:04:01,008
and how many characters we want to write.

70
00:04:01,008 --> 00:04:07,002
And here's the write function in the kernel in the mem.c,

71
00:04:07,002 --> 00:04:10,009
right next to the read null actually.

72
00:04:10,009 --> 00:04:13,008
Write returned how many characters,

73
00:04:13,008 --> 00:04:16,001
how many bytes were written.

74
00:04:16,001 --> 00:04:20,000
It takes in a pointer to a file structure again.

75
00:04:20,000 --> 00:04:23,009
It's taking in a pointer to the buffer, that's the string.

76
00:04:23,009 --> 00:04:27,005
How many bytes, how many characters you want to write,

77
00:04:27,005 --> 00:04:29,005
and a pointer to where we are in the file.

78
00:04:29,005 --> 00:04:32,000
So next time we write, we can continue

79
00:04:32,000 --> 00:04:34,002
from where we left off.

80
00:04:34,002 --> 00:04:37,009
But for null, we don't need to worry about any of that.

81
00:04:37,009 --> 00:04:39,008
We just tell you we wrote

82
00:04:39,008 --> 00:04:41,003
the number of bytes you asked for.

83
00:04:41,003 --> 00:04:44,002
You want to write five bytes? We tell you we wrote five.

84
00:04:44,002 --> 00:04:47,001
If you wanted to write a terabyte, we say,

85
00:04:47,001 --> 00:04:49,001
hey, we wrote a terabyte.

86
00:04:49,001 --> 00:04:51,000
We don't do anything with those characters.

87
00:04:51,000 --> 00:04:53,003
We don't effectively clean 'em up

88
00:04:53,003 --> 00:04:54,006
or throw 'em away or anything.

89
00:04:54,006 --> 00:04:57,002
We just tell you, we wrote the number

90
00:04:57,002 --> 00:05:01,000
of characters you asked for me to write. Pretty simple.

