 All right, welcome back to operating system. So this fun lecture hall has a pelty box in the middle So if you're too loud, I guess you can go in that. I don't know why that's there. Oh Right. Anyways kernels. So let's continue our journey on operating system So where we left off and this time I have Unmuted my mic so recording should be okay So we're left off with this program that I told you was a program We looked at the first four bytes. We saw it was 7f ELF and I said, you know, that's the file format for executable files so let's go ahead and again, we'll just make sure it works as a little sandy check and Prince hello world whenever I execute it and if I look at it to the world links I Can see its size is right here at a hundred and sixty eight bytes. So pretty small and That's hello world So here's an aside before we get into it So there's basically three major ISAs today in your computer organization course use arm and ISA stands for instruction set architecture We won't have to go into details But it's a good thing to know since you are all computer. Well, you're all in ECE So there's x86 64 bit, which is most of your desktops and non-mac laptops And servers everything will probably probably probably be that architecture Then there's AR 64, which might be called arm 64. Those are the newer Mac books. Those are your phones And close to what you had in the computer organization course that fun arm processor And then there's risk 5 which is like an open source implementation similar to arm So an operating system we're going to start looking at throughout this course is written in Risk 5 which is pretty easy to understand and we'll just use that as a basis But again, like I said in the previous lecture, you don't really need to understand assembly or how to write assembly Just we're we'll read a little bit of it and I'll be there to help guide you through it So we'll just touch on all of them a little bit because sometimes it will matter most of the time it won't matter So going on abstractions just to explain what we had with opening files and stuff So our next abstraction after a process is a file descriptor So because our processes are all independent the next most obvious question You might have as well if they're all independent. How do they do anything? How do they talk to each other? Like how do you transfer data between processes if they're all independent? Well, there's a thing called IPC and that stands for inter process communication Just a fancy way of saying I want to send data between two different processes So instead of being independent, you don't want it to be completely independent because you need some data to go back and forth So a file descriptor is a resource that users may either read bytes from or write bytes to and All it is is a number Which is an index and that is unique to a process So if in the other example we saw before we opened a file That would be represented as a file descriptor with some number. Let's say index three So throughout that whole processes life You just open three file descriptor three is valid until you eventually close it But nothing else can monkey with your file descriptors. They're one of the other independent things between a process But you can use a read and write to send bytes to and from that file descriptor So file descriptor it's only called that it doesn't necessarily represent a file Just things that kind of look like files, which is why it's an abstraction So it could actually represent a real file, but it doesn't help have to and it can represent something like your terminal So your terminal is something that you can write bytes to and read bytes from because at least in first year You've probably wrote an application where you can type something press enter and then process that data and then print Something at the end. So you're reading and writing bytes when you're doing that All right system calls. So system calls are how you make requests to the operating system and At the beginning we can just represent them like C functions Behaviorally, they're really not much different. They only really differ in their implementation So here's two system calls. We actually need for a basic hello world program the first one is called write and it takes three arguments and All it does is write bytes from a byte array Specified by that buff and how many bytes to write specified by count to that file descriptor Specified by fd. So fd is the file descriptor I want to write bytes to buff is an address that represents the start of a byte array that just has to be initialized and that's where The operating system will write bytes to starting from and count is how many bytes Maximum you want to write and Then the other system call. Oh, yep. Oh, okay. Yeah, so there's a question What's the difference between size t and s size t s size t is signed size so it can be negative the other one is unsigned so it can't be negative and the reason this so write returns the number of bytes written and it will return a negative number of There's an error. So that's why it's signed All right, the second system call is called exit group and that Exits the current process and sets an exit code Corresponding to that status. So status is an integer here But the offering system only cares about the least significant byte. So you can only actually return error codes between zero and 255 Any you can Specify like a million if you want that fits in an int But it's just gonna chop off some of it. The only thing cares about is zero to 155. Yep So file descriptors just represent a file and then if you try to write two billion to it The the operating system be like no I can write the first like, you know Few thousand and then it'll return it wrote the first few thousand and then if you want to write a million Well, then you have to call it again and go over and over again Or it could just you know and say you're not allowed to do that anymore if you go too far Okay, so these two system calls are actually all we need for hello world and they make requests directly to the offering system So before we get into this we need to know a bit more about file descriptors and magical file descriptors So nothing is enforced by the offering system This is just a convention, but everybody follows this convention and that is how all your terminal applications actually work So by convention whenever you start a process There should be three open file descriptors and they have specified numbers So file descriptor zero is always standard input Just zero standard input that means you should be able to read bytes from that file descriptor then you have file descriptor one which is standard output or write so that's where you write bytes to and that's Means usually that represents your terminal So if you say print it goes to that file descriptor if you have used C plus plus C out It's file descriptor one if you view C and use print F. That's file descriptor one If you use literally any language it's standard out just means file descriptor one And then there's file descriptor two which some of you may not have used Which is standard error and it's just meant for you to write error codes to sometimes people don't do that Sometimes people do do that Generally you want to write errors to that but some people don't do it So if we were to kind of write iffy hello world program in C It would look something like this it would Just be a function that doesn't return anything and doesn't take any arguments Because we don't need that for hello world We don't use any of the arguments and we don't need a main because we're trying to do the least amount of things possible So just naming something main doesn't matter. I could have named this whatever, but I don't really need any arguments I'm not gonna return anything because I'm going to write To file descriptor one. I'm going to write hello world So that'll be represented as an error as a array of characters or you know Char star so point to the first character in Hello world and then I'll say I want to write 12 bytes. So that should represent so hello That's five Space one world It's another five and then backslash n is the new line character, which is just something you should probably do So that's another byte. So in total we were on want 12 12 bytes to one Which is standard output and then if we're done with our program we just call exit group and Just say zero zero by convention means nothing went wrong. We have no errors. Yeah nope Yeah, the question is do I need a main function for this and the answer is no I'm writing like the most basic hello world thing main before will We won't see it but before main executes a bunch of stuff happens and We'll we'll explore that in a bit too, but we don't if we're writing the smallest thing possible We don't need a main if we could magically tell the if we could magically tell the offering system to just start Executing this instead of main. We don't need it Yep Yeah, so that's a good question. What happens if I just omit exit group zero. So if I omit exit group zero well this will get compiled into some instructions and They'll have to get mapped into memory at some point. So Right after the right if I omit exit group It would just be invalid memory and would try and execute that and then it would just fail So it would just die it would crash the operating system would have to do something with it But it would yeah, so it would probably die, but it would die an untimely death and A messy death. So this is a proper hello world that actually exits. Yeah Yeah, for now it could represent a file or a terminal Yeah, so in this case if I change one to two by convention I would be writing to this file descriptor standard error So by default your terminal shows both of those so it would look exactly the same if I change the one One to two No, so it would look the same the only difference is just what file descriptor it wrote to so eventually when we know how to Manipulate file descriptors if you only care about errors, you can just see everything from file descriptor two You don't care about errors. You can't ignore file descriptor two. We'll see a bit of that in a sec. Yeah Yeah, so the question is what's the difference between exit group zero and just returning from main So exit group zero is what will actually happen on like Unix operating systems That's this the request you have to make to the operating system So the only difference between returning from Main in C C will take care of figuring out how to exit a process on whatever operating system you're running on so So returning from main on Linux will eventually call exit group with whatever number you return from main So, you know specifically what it does on Linux But yeah, but on Windows it'll do something different because that won't exist All right, so C does some little nice things for us. We thought it was low-level, but actually does some things All right, any other questions with that? This is a whole new world, right? All right, so we have to take another quick aside to a difference between an API and an ABI you might not have heard the term a BI before hopefully you heard the term API before So API application programming interface It's meant to just abstract the detail and describe arguments and return values and generally what the function does so like a function takes two integer arguments and Returns you an integer that represents like the addition between them or something like that So that would be like an API description an ABI Description is like low-level details that you may have monkeyed around with in computer Organization how to set up, you know like prologue to function calls and all that stuff That's all specified in something called an ABI and that's like explicitly how to pass arguments So if you're in C we pass arguments on the stack In your computer organization course You probably pick certain registers to represent certain things But that would be defined in something called an ABI and in C the C call a convention Yeah, it does just pass arguments on the stack instead of explicitly using registers Okay, so with that Here is the system call ABI for Linux specifically on arm64 or AR 64 whatever you want to call it so Because the operating system is Running something else. It's not in C. You can't just make C function calls to it. That doesn't make any sense so There's no functions to call because there's no addresses because you know the kernel won't just Give you its memory let you access its functions or anything like that So you can't just call a function if you want to make a request to the operating system You have to do something called a system call and a system call you did interrupts in computer organization, so how we make a Function call to the operating system is there's a special instruction that we're allowed to execute that will generate and Interrupt to the operating system. So specifically for arm64. It's called the SVC instruction I forget what stands for like supervisor vector something call I forget exactly what stands for but stands for something Basically all that instruction does is generate and interrupt and then the convention is to pass arguments and registers So register x8 should just have a number that represents what function call you want to make So for example, right would be function call some number Exit group would be another number that's supposed to represent Hey, I want to make an exit group function call and then it takes six arguments Past and registers x0 to x6 So anyone think of any limitations to this interface Yep Yeah, if I have more than six arguments, I'm screwed now, right in C. Are you allowed to have more than six arguments? Yep, because you can just it's on the stack. So you can just Keep popping or keep pushing as many arguments as you want until you run out of stack space, of course, but you know It's essentially fairly unlimited. All right. Any other ideas or Limitations this has Yep, so in this you can't make recursive function calls or anything like that So you just make one request to the operating system say do this for me, please So the operating system could implement that in a recursive way, but you can't make recursive calls or anything Yep, so this is specifically for arm 64 using Linux So every operating system and architecture is going to have its own calling convention Yeah, the question is oh, can I just reuse system calls to operating system the answer that is no So they'll be all slightly different. So that's one of the reasons why someone came up with the C standard library So you don't have to worry about you don't have to worry about this You just let it figure out what system call it actually needs to make for your system So that's like one of the things the standard C library does. Yep. Oh, yeah so registers six and seven there'll be like caller saved or call you save well, I'm just kind of ignoring it just because We won't have to write this it's only for for showing you So, yeah, we don't have to care about the calling convention. So many things will just do this for you Okay, so yeah, like I said before programs on Linux and I guess PlayStation stuff use the alpha format So it stands for executable and linkable format elf nothing to do with me And it's the format for both executables and libraries and we'll see libraries in the next lecture So they always start with the same four magic bytes that's seven F and then ELF and ASCII They're called magic. They're literally called magic. That's like the whole magic of a computer. It's just Random numbers that means something if you know what the random numbers are supposed to be So this is like a very common thing. So there's a Wikipedia link for file signatures So by reading the first few bytes of most file formats, you can figure out what it is So like PDF files start with ampersand PDF and then a dash That's how every single PDF file in the world starts. So That's the file format So our bytes represent an elf file we already know that because we looked at the first four bytes and it matches so The whole thing so we'll break it up into parts, but basically that whole elf file just says load this entire executable file into memory at address 10,000 hex and The header file if you look at the specification for elf, which is a fairly boring document It says well the header file has to be 64 bytes So it's 64 bytes. Basically. It just gives you some information about the executable So that the offering system can tell One of the bits of information in it. It's like the ISA so the operating system can tell What ISA it's running and what the file is and if they don't match you can say I can't execute this without trying any further things like that after the Header file there's a program header which basically just that's the part that says where to load it into memory and it's 56 bytes of Information so 120 bytes of our 168 byte file is literally just filling in information for this file format, which is fairly boring so We have 48 bytes left. There are 36 bytes for instructions and we'll disassemble them and see what they are And then the last 12 bytes are for the actual string. Hello world and In this case if you Calculate the difference from the start of the file to where the instructions start and where the data starts and convert it to hex Well, instructions would start at bite hundred and fifth or hundred and twenty because the first hundred and twenty bytes are The header and the program header so instruction if we loaded it at address ten thousand hex while instructions would start 120 bytes after ten thousand hex so if you convert hundred and twenty to hex it is Seven eight and if you add them together you get that address so instructions would start at that address and if you do the same thing and you just know that the string Starts after the instructions and that was our choice to make it would start at bite Hundred and fifty six which is nine C and hex again add it together so the string would start at that address and There's a command you can use read elf dash a it will give you all the gory details of the file format if you're really curious I Don't super recommend it, but hey, I can't tell you what to do. I guess I kind of can but Whatever all right So this is visually how the L file gets divided so that head file header was 60 bytes Everything that's in it So it also has a field for like what endian this this file represents the instruction set architecture The ABI it's expecting to use so in this case. It's Linux the entry point So in that header file the entry point means where to start execution if I want to start executing this process so in this case if I want to start executing my beginning of the instructions I should set my entry point to address 10,078 and That's where you that's where the offering system knows where to start executing your program It's in that header file and Then in this cyan color there's a program header and that says what to load into memory and where so in this case All those bytes basically just say load this entire file at address 10,000 hex and that's all it says So pretty verbose are saying that and then The next bit is the actual instructions if we just take the assembly and just convert it to machine code That's what they are and then at the end is our string itself So this is what the instructions look like if you throw them into a disassembler for arm So it follows that calling convention. I showed you earlier So x8 is our system call number in this case. Let's just say in a decimal. So That's what system call to make and we want to make a right system call first So if you there's a whole table you can look up. So the right system call means I want to call function 64 so 64 represents right The first argument was the file descriptor So if we want to write hello world, we should probably just write it to standard out. So that would be file descriptor one The next argument is the address of The string and because it's arm we have to build it in two parts So we have to build the lower byte and then we have to build the upper bytes So 9c was the lower part of the address and then if we do this move k instruction We will add 10,000 to it to give us our 10,009c, which is the beginning of our string Then the next argument is and again, you don't if you can't read this It's fine. This is like the only time we'll read arm assembly. This is just to illustrate how you actually make system calls so the last argument is the number of bytes and we want to write 12 bytes and then to start a system call after we set up all the registers we Execute this svc instruction and that will generate and interrupt and then the operating system gets to handle it and Some of you have handled interrupt before so you can use your imagination with what it kind of looks like to the operating system Now after that After that system call is done. It will just continue execution So the next time it will so after it's done, right? It will come execute this instruction We want to do an exit group system call It's number 94. It only takes one argument zero and then we do SVC And that does the exit group system call and exit group never returns because our process is now dead. It's exited It's gone no more Yep Yeah, this is specifically how to do system calls on Linux using arm 64 Yeah, so if you want to do this on x86 on Linux the register names are obviously going to be different because they don't exist Right, but it's pretty much similar. Just the register names are different If you want free BSD is the same macOS is pretty much the same Windows is a bit weirder But this is basically how you do it and how it will always work no matter what operating system just the details are going to change so that string 12 bytes that was hello world and We just asking coded it so a fun low-level Ascii tip that might not be so fun to some of you is it was designed in such a way to know if a character is lower case or Upper case by looking at a single bit. So bit five If bit five is zero, it means it's uppercase and if it's one it means it's a lower case And which just means the values differ by 32 so if you ever for some reason need to do low-level Ascii stuff, then that's a good thing to know Hopefully you never need to know that fact. I don't know why I put it in there Anyways, so that that's every bite. So every bite is useful and Let's go ahead and see what C does. So that was again 128 bytes And yeah before I even show that can you already spot the difference between Strings compared to C. Oh, that was a hint. So what do C strings always end with? Yeah A null character do what did I have an all character there? So this was my string Do not know not know not know not know go through that null is just another word for zero. So none of those is zero As a side if I if it had to be a C string and it said, oh, okay, right until a zero Well, then suddenly my right system calls useless I can't write zeros to anything and if you couldn't write zero to a file that probably be pretty bad So ending a string in zero is literally just a C convention. The offering system doesn't care That's it's not a thing to the offering system. So Whenever you see it will just ignore that Null character that just means the strings done and don't process it. Yeah So entry point is the address to start executing instructions So in this case our entry point if we say we want to load things At ten thousand our instructions would start here at this address. So this would be our entry point So if you do that read off on the file, it will say that address as the entry point That just means I want to start executing at the start of my instructions So if I change that it would skip some instructions and then bad things would happen Okay, let's see what C does Yep, which number Yeah, if I if I make that number lower Then this whole thing is loaded at ten thousand So it would start trying to execute like here or here or somewhere So it's whatever instruction represents zero which probably isn't valid. So it'll just crash So your operating system won't let you execute a legal instruction. So it'd probably be an illegal instruction Yeah, it could be so low that's not even part of this in which case it'd be invalid memory And then it knows to stop which we'll figure out when we get to virtual memory All right, so let us but yeah, good questions. Let's see what C does though because C is going to do something that Probably not as good Okay, so here's C. That's hello world everyone Agreed that that's hello world. That's pretty minimal Any disagreements with hello world looks hello world to me? All right Let's make sure it's compiled Let's run it So this is so it does hello world and it looks exactly the same as my hello world It doesn't really do anything different Any guess is how big this monster is Few megabytes. All right got a few megabytes Kilobytes kilobytes 70 K 70 kilobytes For hello world to do anything different than my program No, see people think C is like low level and slim and everything that definitely isn't that is that is bloated, right? 70 K for hello world yikes Although we'll figure out that C is not that bad Okay, so Okay before we can explain the difference between those two so we will explain the difference between the two Let's have another aside so The beginning of the sides of kernels that you might have heard Linux kernel before but you probably just don't know what a kernel is so a kernel is a core part of your offering system and Specifically on every single CPU there is there is some special privilege mode called kernel mode And it's a privilege level that gives you access to a whole different set of instructions So most of the kernel mode instructions are going to let you manipulate hardware directly and it's going to be more privileged than if you just run some application so Different architectures have a different name for this mode in risk 5. It's called s mode for supervisor mode You might hear it be called kernel mode on really old CPUs It's called they had a concept of rings to represent all the instructions. So unlike Intel CPUs. It's called ring zero So they all mean the same thing. It's just a separate CPU mode that gives you access to more instructions I can actually directly manipulate the hardware the idea behind that is well You want a different privilege level so that your application can't just do things that manipulate the hardware Without the kernel knowing about it, right the kernel in order to maintain security and integrity and Make sure everything is independent while it needs to have control of the hardware not you so the kernel is a core part of your offering system the definition of the kernel is The software that runs in kernel mode. That's it. So the kernels the software that runs in kernel mode it is a separate CPU mode and These instructions so like for example only the kernel can manage virtual memory for processes No one else can do that You have to be in the special CPU mode to access any instructions that have to manipulate the virtual memory So it kind of looks like this visually so there's on some CPUs. There's up to four different privilege modes So in CPU mode you which is called user mode. That's where your applications and everything Execute so you don't have access to any special instructions if you try and execute that special instruction It'll say illegal instruction and kick you out so S mode is Yeah, S mode is the supervisor. So yeah curl is part of your operating system runs in kernel mode. That's literally the definition so S mode or supervisor mode. That's where your kernel lives. That's the CPU mode your kernel executes in and Below that that is even more in str- more privileged than the kernel itself It's something called hypervisor the hypervisor which is in H mode Because your hypervisor would need to maintain virtual machines So all your operating systems shouldn't be able to interfere with each other So it manages making those independent so that the kernel can't monkey around with any other kernel running. Yeah Yeah, so when you are in kernel mode, you can do whatever you want So one of the kernels job is to Schedule processes to run and give them CPU time So that's like that's one of the things your operating system does Yeah, okay, so yeah, and then below that which is this M mode or machine mode is more what you did in the computer Organization course You don't have any applications. You don't care. You don't care about these privilege modes You just have access to literally every instruction and you can do whatever you want so on risk five. That's just called machine mode That's where your bootloader lives and like really low-level things that we won't really get into in this course most of this course we're going to focus on Supervisor mode and user mode and the boundary between those two So yep Yeah Yeah, so how it actually works. So if some of you have set up lab zero in Windows So if you the suggestions to use hyper V so hyper V Windows will actually run as a hypervisor So Windows actually runs as a hypervisor So it can manage the virtual machines and then you can install any number of virtual machines on top of it And it's Windows job to manage them Yeah, so that's what I'll do and it gets kind of iffy because this is a fair Virtualization everything like that is a fairly new concept. So this it gets kind of weird Yeah, so this is when you enable it that's why you have to reboot it because it has to be a hypervisor now instead of just a regular machine and We'll get into more details like at the very end of the course once we explain Once we explain how the kernel works will be able to more better explain what the hypervisor actually does so the border between user mode and kernel mode is Can only be entered by doing system calls what we did before so system calls are the only way To get between user mode and kernel mode once an operating system started. So on Linux there is only 456 Essentially functions you can make to the kernel. That's the maximum number of valid system calls to make some of them are like read and write which we've kind of seen already open close and This is a whole bunch of them at the end of this course. You'll Come back and look at this list and you will understand what each of these are actually supposed to do Except for init module and delete module, but you're you did that if you Completed lab zero and that's how that worked So the nice thing about having this boundary between your actual Applications or user mode processes and the kernel is you can trace all of them So on Linux, there's this fun little command called s trace So you can type s trace before anything and it will tell you every single system call you make so we can actually see what our hello world program does and We can actually see what C does and compare them because no matter what you Language you write it in your your application is going to do system calls. That's the only way It can interact with the hardware is through the kernel so let's go ahead and We can s trace and just run our program And if we do that it looks a bit messy here. I'll make it bigger too It looks a bit messy Well, but it's showing that this is not something we did but it says write and Exit group so those are the system calls we made those are the only ones we Yeah, those are the only system calls we made and that's kind of what we expect to be There but we'll see it's kind of jumbled up. There's a weird new line character. So it is also printing Hello world as it's showing this so Once you get used to these file descriptors s trace actually outputs everything on file descriptor 2 and We're actually printing the file descriptor 1. So this is from file descriptor 1. This is from file descriptor 2 So if we really want clean output We could do this again You don't have to know this would be tested on but this says take file descriptor 2 and redirect it to somewhere and then there's this handy file Which is on Linux. It's just called the void. I like to call it any bites you right there just Get deleted immediately. So this So that would delete everything that s trace outputs and I would get hello world If I want to see what s trace is doing I could delete everything from hello world So I just delete everything from file descriptor 1 So then I just get without that weird new line break So I can see when I execute my program. I do a write system call and then an exit group system call so Now that we know kind of how to figure out the ground truth of what things are doing Yeah, so the question is if your language is interpreted rather than compiles. How do they do the system call? The the interpreter is just gonna do the system call for you So your interpreter is compiled at some point. So it's gonna be like your Python interpreter Python's an executable the system calls are all done by that Python executable Yeah Yeah, the question is this is s trace for the see the same. So let's see. So we'll s trace Hello world and Let's just get rid of the hello world part So if C is minimal it just needs two system calls, right? We just did hello world and two system calls There we go. So that's what C did So what the hell is C doing so you can see We don't know what that means, but that's actually initializing your heap. So that's an operating system call We have no idea what this means yet. We will No idea what this means. This kind of looks like you were opening a file called this that was just some cache whatever Did you do? Close open we can see that it opened. Oh, that looks interesting. So it opened the standard C library That makes sense. See standard C library. It should probably load that at some point So it opened the standard C library with file descriptor five and then it read from the standard C library And guess what? It's an L file that one seven seven This displays an octal for some reason. I don't know why it's octal. That's one there. That's seven F Don't don't ask me why it's an octal So it read a bit from the standard C library Did some more stuff did some more stuff did some more stuff Did some more stuff did some more stuff. We can't explain yet. Did some more stuff. We can't explain yet Did some more stuff. We can't explain yet. Oh it got an error that inappropriate very naughty Did some more things It initialized the heap again I don't know so it had to do it twice and this is it requested more space for the heap So it now has a heap So that makes sense it had to initialize a heap and read see So and then eventually hey it did what we expected it did the exact same thing we did it Said 12 bytes the hello world exit group. Yeah Yeah, so the question is if I statically linked this would it have less system calls And yeah, I wouldn't have to link the standard C library because it's dynamic and we'll see that next lecture But yeah, you get rid of some system calls. Yep Yeah So the question is if I compile this with all my optimizations on will it do any better than the answer that is no so the only thing it will optimize is your main function and Main doesn't do much. It does makes two function calls It might get rid of some C function calls, but won't get rid of system calls Because system calls are the only way it can interact with the operating system So we can verify that so no matter what so let's see we have Python I did hello world and Python Python 3 sorry So guess what we can S trace it and let's just get rid of the hello world part and see what Python does Python does a lot of stuff, but see at the end it had to do exit group and There's the hello world But even between them it did some things and before that It you could see that it oh it had to read the file So it read print hello world, which is the contents of my file So Python had to load your file. Well, it had to To get information from your operating system. It has to make a system call So to read the file has to make a system call. So it read that file twice for some reason Don't know why I did that Then you can see most of it is doo-doo-doo It does a lot of things Python has some languages. It's going in some libraries Some site customized so you can really figure out what Python is doing here See distutils hack. That's probably Probably an intern did that Do-do-do See look at look at all the stuff Python's doing So if we don't want to scroll through all this I generated earlier So this will see how many lines there are which is like how many system calls it makes so Python made about You know over 350 system calls to print hello world Well To reg on something else. Let's say JavaScript hello world so we can ask trace JavaScript to Oops One sorry Wow, that's called a long time. So JavaScript was JavaScript do well at the end it did exit group Before then it started closing some files. I Don't even where is hello world. It's doing Who knows what the hell JavaScript is doing? That's bad. You can't even find the hello world system call. Oh, I passed it Wait somewhere in here. All right. Well, whatever it's somewhere there And I generated it earlier so we can see how many system calls JavaScript makes and Over a thousand. So yeah common JavaScript W, right? Yeah, yeah, you can tell I don't really like JavaScript, but I have numbers to back me up so The beginning system calls that looked like it was finding this standard library Then it loaded the standard library and see and then eventually it set up the heap and then did Hello world as we expect it to do So What you can think of the kernel is it's like it's kind of like a long running program but it's just running in a different CPU privilege mode and writing kernel code Because it's a long running process It's more like writing library code like there's no main or anything So if you've done lab zero you're actually writing kernel code and you're requesting it to be loaded by the kernel and executed by the kernel So your code will actually run in kernel mode so that's what you do you create a module for it and In general kernel codes loaded on demand because a lot of it is device drivers and things like that So the offering or the kernel will know what hardware gets plugged in and what code that corresponds to and try and load and execute the appropriate code so When you're doing lab zero and you're writing a kernel module you can execute Privilege instructions you can do whatever you want there So right now it's just printing some messages to the kernel log because the kernel doesn't have printf It doesn't have a standard C library or anything like that because it's running in kernel mode So it doesn't have anything it needs to enable you to have those things So if you really want to and you knew what you're doing in your code for lab zero you could One of the things you can do is kill every process just kill every process Whatever's running you can just kill it if you want like there's you could read any processes memory You can do whatever you want because your code is running in kernel mode It's supposed to be you know high-quality code Which is why a bunch of people would review it for the actual kernel But since you're writing your own you can just do whatever you want So there's different kernel architectures, which we will not have time to go into so instead of that I will just let you go and say I'm just pulling for you. We're all in this together