 back to system software so some housekeeping items to get out of the way real quick so you should have lab accounts activated tomorrow also with your lab accounts there's going to be a optional tool to help you so one of the previous students has developed some tool to help you prioritize what assignments you should complete and what you should study for and all that so you'll get details post about that if you would like to help out that would be greatly appreciated so today's lecture is kind of a fun lecture you don't have labs set up or anything so sit back relax and enjoy the ride I will tell you the few minor things you actually need to take away from this lecture but this is another setup lecture so don't be too worried if it's kind of confusing so why is it confusing because well this is Hello World so this is Hello World if you write out each individual byte in hex and you try to execute it so let us make sure that I wasn't lying to you and that this in fact is Hello World so if I look at my directory here let's see I have a file called Hello World Linux a arch 64 we'll get into what that means in a second and here is the file size it is only a hundred and sixty-eight bytes and if I execute it Prince Hello World amazing right so we're going to dive into the details of how this works and it will set up kind of where this course is aimed at and what we need to take away and what we'll learn from this course and we'll also figure out why JavaScript is terrible all right great so I've showed you this actually is Hello World so let's get into it so first aside that you don't need to know that may come up so there's three major ISAs or instruction set architectures in use today it stands for like I just said instruction set architecture it's the machine code or the magical numbers the CPU understands to tell it that needs to add two registers together and things like that you probably have hopefully done a little bit of assembly but the lowest level it's what your CPU actually understands three main ones today is x86 64 bit so that's like any desktop processor you have any laptop you have that's not an Apple one then you have a arch 64 aka arm 64 that's like any phone tablet or Apple laptops we'll be using that so I had to execute specifically that because well I have an Apple laptop so it's arm the next one that might come up a little bit in this course that we will read but don't worry you don't have to look it up or anything is risk five might be called RV 64 GC it's an open source implementation of an instruction set architecture so you are allowed to implement it yourself possibly in future courses without having to pay arm a licensing fee that cost millions and millions of dollars so we'll touch on them a bit in this course but not important just something you should know because it's going to be important today but again not to understand so the next abstraction we have in this course is something called a file descriptor so we already argued that our processes are independent they have their own independent memory and if they're independent well they need to be able to transfer bytes to one another somehow otherwise you wouldn't be able to see their output or give them input or anything like that so something that is important to know the acronym for something called IPC or inter-process communication don't worry we'll get to it again later in this course so it will come up again but if you want to know it now you can and all IPC is is transferring data between two processes so a file descriptor is just a resource that users can read or write bytes from so it's actually identified by an index and that is stored in a process and that is how your process can actually communicate with you know your hard drive and your storage and all that fun stuff it could also represent different things from a file even though it's called a file descriptor it could represent your terminal or things of that nature and we'll get into other things that can mean as we progress through the course so there are ways to ask your operating system to do something and they are special in that they are not C functions or anything like that they are in fact called system calls and that is how you make a request for the operating system you probably have never done this before because this is what the C standard library does for you but in this course will be actually understanding where what the system calls are and what they do and that's kind of where this course is aimed so there's two system calls we need to use if we were to have the bare minimum hello world program there's a system call called write that takes three arguments the first one is a file descriptor so it's just a number and then that should represent a file or or a terminal or something like that and that is where to write bytes to and then because it's C it uses pointers so there's a conv void star pointer called buff if you haven't seen a void star before in C that just means it's a pointer and it doesn't really care what the data type is it sees waves say saying just a pointer don't care and then so it gets a pointer and then the third argument is account or the number of bytes to start reading from to write out starting at that address so three arguments file descriptor an address to start at and then the number of bytes to start writing out from that address the next system call we need is something called an exit group system call and it takes a status and was what it does is it ends the current process from running you might or something like that and that exit status code is just a number between 0 and 255 by convention 0 means there are no errors and again you don't actually have to know this but it might come up during the course alright so our hypothetical hello world so by convention and this is the only way programs work is that there is some expected file descriptors it is good to know these numbers you don't have to write them down right now but as you go through this course these will be burned into your mind and you will start just representing the standard file descriptors as just numbers so you probably heard of like standard input standard out standard error while they're just given magical file descriptor numbers so whenever we refer to standard input to Unix offering systems at least that's just file descriptor 0 if I say standard out that's file descriptor 1 if I say standard error that's file descriptor 2 so my most basic hello world program if I could just magically write a function to start executing all it would contain is this a write system call to file descriptor 1 so that represents standard output and then this is my string to write so hello world with a new line and from that C string I only want to write out 12 bytes so I want to write out H E L L O space world and then the new line is another byte itself so after writing out hello world all it has to do now is an exit group system call and now that process is done and this is the bare minimum we need to have a hello world program so any questions about that one all right we're well the ride doesn't actually get that much more wild than this so here's another aside that is probably important to know if you don't know it already so there is something called an API that you probably all have hopefully heard of before and then an AB I which may or may not be new so API to distinguish between the two it just kind of abstracts the details and describes the arguments of a function what it returns and then what it does so you know a function takes two integer arguments and multiplies them together or something like that the opposite side of that is an API that specifies the details and specifically describes how to actually do a function call in machine code like where exactly the argument should be should they be on the stack where should they be on the stack what order should they be in you know where does the return value go whenever the function gets called and you if you've done any assembly you probably heard of the calling convention so the caller has to put arguments in certain way and then the actual function needs to read them in the same way if they agree with each other your code works if they don't you will never ever debug it and you'll be stuck on it for probably a good month so an API is like the actual nitty-gritty details for that architecture so the same function using the C calling convention which by default passes arguments using the stack which is it is only slightly true all right so system calls are not C functions system calls like having eight as the same API as functions but the way the mechanism to actually call them is a bit different so with C functions they're just an address that you can call and you know you set up some arguments and then you jump to an address and then you jump back you read the return value it somewhere with system calls we're actually asking the operating system to do something so its instructions is not loaded into our memory it has its own private memory that only it can touch so you are not allowed to touch it and that's how operating systems provide some type of security so you can't just do a function call into your operating system you have to do a system call yep so the only thing to do to access special operating system protected things is to make a system call and that's it yeah so we'll get into that a bit so knowing the system call ABI is not terribly important but just in case you want to see the mechanisms how it works is instead of doing a jump instruction or something like that it calls a special instruction called SVC and that generates an interrupt that the kernel can go ahead that the operating system can go ahead and handle and it does not use a stack it passes arguments in registers so on RM64 they just generically name registers with just X and then a number so the convention is that in register x8 you put the system call number there so right the right system call would be associated with some magical number the exit group system call would be associated with a different number and then you can have up to six arguments that are in registers in this order so compared to see that uses a stack what are the limitations of this ABI yep yeah I only have six arguments so I can't pass anything more what about if I also want to pass something that doesn't fit in a register then I can't do it either right so I'm limited here with C since it's stack based I can use essentially as many arguments as I want until maybe I stack overflow or something like that but we'll ignore that and C arguments can all be of different sides in this case everything has to be a register or fit exactly in a register so there's some limitations but you as a user you generally don't see this because you don't use system calls directly so here is finally the last design so the C ABI or calling convention for x86 actually uses so actually does use the stack a bit so arguments are pushed on the stack from right to left order then some registers are call these save some or call or save and with this some arguments are actually passed using registers instead of the stack but it gets into like some nitty-gritty detail so if you want to see the details again not important I don't suggest that as reading unless you are a psychopath like me so there but you can ignore it the only important things we need to know system call uses registers this uses a stack so what other advantages does this give us well we already kind of named it you can have any arguments you want and they can be different sizes so the next thing to explain what a program is on Linux so it uses something called the elf file format to describe how to actually execute your program so elf again has nothing to do with me it is a clever name invented by computer engineers or computer scientists that do not you know are not terribly clever elf stands for executable and linkable format and it's the format for both executables and libraries so they always start with four bytes seven F and then ELF and ASCII and again that is called magic and that is how a computer knows what a file is and they just read the first few bytes and then see if they match some hard-coded value and if they match well then it just interprets of rest of the file as if it was actually that format so there's a whole list of file signatures in case you're interested again I don't have terribly interesting hobbies so I like that stuff like PDF files start with ampersand PDF and then it tilde I think it is or it's a dash so all the files are just looks like that so that is what our bytes oh sorry yep so for this file format it's specific to Linux and PlayStation and BSD ish but macOS has their own Windows has their own and PlayStation Sony was just like yeah let's just use this one yes that's true all right so our bytes that's what they represent they represent ELF file and to do a too long didn't read of all the bytes it basically tells the operating system to load that entire executable all hundred and sixty eight bytes into memory starting at address ten thousand in hex so there is a file header that's sixty four bytes it and a program header that kind of says where to load something into memory and that is fifty six bytes so those hundred and twenty eight bytes are just describing what are in the file and they're not actually doing anything so like the header will contain things like what architecture is this for what operating system is it meant to run on what byte order is it in and boring details like that so the next thirty six bytes are just instructions and we don't need that many instructions and the next 12 bytes are just for the literal string hello world with a new line so if we if we lay out the file such that we have our headers that describe the file and then the instructions the instructions would start at address ten thousand seventy eight in hex because seventy eight is a hundred and twenty so the first hundred and twenty or hundred and twenty bytes are just header files so instructions would start at that address and then the string that represents the actual data of our program starts at address ten thousand nine C because it is directly after the instructions so it would start at byte hundred fifty six if you want to get into the gory details there is a program called read elf that will show you all the information about a file you can go ahead and look at all the gory details if you want again do not suggest it because it's kind of boring so this is visually how it gets divided so the file header has like the end in this the ISA this program is in where to actually start executing it if I want to run it so it has an entry point that's just the address to start executing instructions before again this is what the offering system actually uses so in C whenever they told you begins execution at main that is not true it starts executing at whatever address that entry point is which will probably be the C runtime yep yeah so in this case I could have put the data in whatever order I wanted as long as it was consistent yeah so the header says what to load into memory and then tells it where to start executing from so part of so this big blob of stuff just says load this whole thing into memory starting at address ten thousand and this will say what address to start executing from so if I wanted to I could ship the instructions to the back and put the data ahead of it but I just have to start executing at the beginning of the instructions whatever address I choose yes so this is what the compiler will generate for you in this case I wrote it by hand because I'm again my hobbies are not that interesting so I decided to lay this out but your compiler will lay it out however it wants to but aside the only rule is that it has to begin with ELF and that the first 64 bytes have to be the header and it describes the rest of the file you can do whatever you want you will you will never do this so don't worry about it so this is this is should be a advertisement of why we use compilers because otherwise you know you're like me all right so if we plug in those so if I take what's in the green there and plug that into an online disassembler and I actually disassemble it using arm 64 I'll see that my disassembled instructions are something like this you might use a disassembler if you get into you know do playing with exploits and all that fun stuff for this course thankfully we don't have to do it it's only for this lecture so if you disassemble the instructions you'll see that it actually follows that system call a bi so it does a move x 8 so x 8 is the register where you put the system call number in in this case it puts hex four zero or 64 so 64 corresponds to the right system call and then in the first argument that's my file descriptor if I want to output to standard out that's file descriptor one so I put move the value one into that register the next argument is the address of the string to start writing out we argue before that it is that it was 10,009 C all the way back here it said the string data starts at address 10,009 C so because it's arm 64 we have to do it in two steps so we have to load the lower bytes of the register with x or sorry 9C first and then this move K essentially just adds it together so it adds 10,002 that so our resulting address in x1 is going to be that 10,009 C right here so after that the last argument is the number of bytes to actually read from those memory addresses and it's 12 which is C then we do SBC 0 it takes a number argument but it never gets used so it's always just 0 so that SBC will initiate the system call so then my offering system will go ahead write those bytes out to in this case our terminal and then whenever it is done writing the bytes out it will return start executing the next instruction which would replace the value in x8 so that's a new system call number turns out exit groups number is 5E or 9E4 and then the last thing is the status and while we just return 0 for main 0 usually means no errors so only one argument we set to 0 and then it does another SBC instruction or initiates a system call and then our process is done we're done running so any quick questions about that again don't really need to know it's essentially the same thing as we had before it's essentially the body of that function but just using the system call ABI and written out just using assembly instructions all right so we were all right so the last part of that is the data for our hello world example so 12 bytes hello world and the new line so if we asking code it that's what they are so weird low-level ASCII tip won't come up for this course but if you really want to know bit 5 is 0 if it's uppercase one if it's lower case because the values differ by 60 32 and well why did they design it that way because computers back in the day were dirt slow and checking a bit is about the fastest thing you can do that fact of just checking a bit is the fastest thing we can do may come up later in the course as well so that's every single byte of our 168 byte program all accounted for and 120 of those were just header files that we had to explain what the hell we were doing so let's see how big C is so I have previously any guesses as to how big hello world is going to be when I compile it using C we got a big what's big 1 megabyte 12 kilobytes all right let's do over under over under let's go everyone under 10 kilobytes okay under 10 kilobytes all right anyone over over 10 kilobytes all right few people don't have any hope in C the people that know hope in C are correct so that is what is that 70 k so they tell you C's efficient right well let's see if it does anything different hello world mine is what 168 bytes what does mine do what the hell so see does a lot of stuff they told you C was efficient they lied a little bit oh and can you also spot the difference in strings compared from our example to C so in C what do strings always end with a null did I have to use a null character no because to your operating system that's just a C thing your operating system doesn't care zero means nothing to it zero means nothing that write system call has to be super generic and work for anything if it assumed there was a null terminated bite and that's how like where to stop writing data that means that you could never write a zero bite out which would be a very terrible operating system if you could never write a zero so now we get to use the term kernel finally so the definition of an operating system is a bit fuzzy because sometimes it includes libraries and other things that we need to but what is not up for debate is that the kernel is the core part of your operating system and it has a fairly not surprising definition so the magic for that I heard someone say it earlier that kind of the operating system does some privileged instructions so on your CPU there is a specific mode you get to set that tells you what instructions you are allowed to execute so one of the modes on your CPU is something called kernel mode and if your CPU is currently switched to that mode it means you can access more instructions that can actually interact directly with the hardware and actually control the hardware otherwise there's another CPU mode what you have used currently so far in your career is all your programs run in something called user mode which has less privileges it can't change any hardware directly or anything like that if it tried to execute one of the privileged instructions you would get an illegal instruction your program would crash immediately so the kernel actually runs in kernel mode some different architectures also have a different name for the mode this mode on risk 5 it's called S mode or supervisor mode but they mean the exact same thing so the definition of a kernel is not terribly fun so the kernel is just software that is running in kernel mode so for example if you've ever heard the term the Linux kernel so Linux by itself is technically not an entire operating system links by itself is just a kernel so the only way to interact with Linux is by using that system call interface and aside from that Linux doesn't operate below that and Linux only runs in kernel mode with those privileged instructions in order to have an entire operating system you need like a C library and things like that that are not included in Linux for like macOS something like that they have their own kernel it has a different name that you've probably never heard of before it's something called Darwin Windows has like an NT kernel or something like that so every operating system will have a kernel most of them you probably won't know their name but technically Linux is a kernel so like I said these kernel mode instructions they're the security measures so they only allow trusted software to interact directly with hardware and that trusted software is called the kernel that gets to control everything and that's the main part of your operating system so for example for security like the kernel is the only thing that is allowed to manage virtual memory for processes because it is in charge of security if the kernel has an error in it or something like that and other processes can start reading each other's memory then you essentially have no security anymore any process can go ahead and read your bank account information or anything like that so super important that the kernel works properly and is secure and will go over this course will focus on what the job of the kernel is without having to get into the nitty gritty details but this course pretty much operates on that system call interface we're going to learn how to use it properly every program is going to use it eventually and we're also going to understand what the system calls actually do so again here is it graphically so there's might be more CPU modes on your processor like for arm or for risk 5 they define four different modes so least privilege is this user mode up here that's where your applications and libraries run that's where most of the code you've written this far in your life actually runs and it is the least privilege it has no access to hardware or anything like that the next is the supervisor mode so that can interact directly with hardware and that actually manages things like virtual memory what has more privilege than that is something called a hypervisor mode which we will not get into until the very end of the course but in lab zero well as part of this course you'll be using a virtual machine so your virtual machine manager is actually running in something called hypervisor mode because it needs to make sure your virtual machines are secure so it needs to have access to even more hardware instructions than the kernel itself and then below that there's machine mode which if you did assembly before is probably where you were it has no security whatsoever can just access everything and that's primarily for like bootloaders and firmware stuff we will not touch in this course at all that will be an embedded course later on so the system calls are the only way to get between that user mode and kernel mode and you can think of it again like the API of the kernel so the kind of surprising thing is that's the only way to talk to hardware essentially and there's at the time I did this there's only 453 functions that you're allowed to use and that is how every program interacts with the hardware so surprisingly few functions or system calls if we want to be accurate that everything has to use the next thing about system calls so the important thing from this lecture in terms of actually your career later and figuring out what things actually do for now you won't really know what the system calls mean aside from two but this program is very very handy so there's a program called Strace so if we run Strace we can see what system calls are programs actually do and this leads to a lot of fun so we can use Strace it will tell us all the system calls any application makes and because we have this strict user mode kernel mode it tells us exactly how it interacts with the kernel and we can see exactly what it does no matter what language it's written in or anything like that so for instance if I Strace this my hello world application and I do this so this will just throw away the hello world that it outputs so it takes file descriptor one and throws it to this device called DevNol which just is essentially a black hole so if I run it it'll tell me all the system calls I make so this first system call I did not make we will get into that later this is what I actually did so I did a write system call and then an exit group and then that was all my processes done so since we have this tool we can just see what C does so we will take this Strace so we'll probably need to scroll up so at the end of the day C did what we expected doesn't matter what language it's written in it did a write system call to file descriptor one with hello world 12 bytes and then exit group but it did some other stuff so what the hell was it doing so did this system call don't know what that is and map we have no idea what the hell that is but that has to do with virtual memory see it did some preload something or other no you got an error okay so it just gave up oh something with the cache oh caches are good we like that something we don't know more virtual memory oh hey that's interesting open what's that oh it's libc oh well that makes sense it has to open libc if it wants to do anything we can see here that so open at will return you a file descriptor number so file descriptor for represents the standard C library does a read system call here we can see that the C standard library starts with something that is already familiar for some reason again don't ask me why this when it escapes the number is an octal don't ask me why this is 7f but an octal so it's 7f ELF so it's an elf file standard C libraries an elf file that makes sense does some more virtual memory stuff who knows what the hell it's doing some other stuff don't know what it's doing let's see get random I don't know neat why is it need a random number for hello world I have no idea BRK so this actually has to do with your heap so if you say BRK with null it tells you where the beginning of your heap is and here it's just reserving some heap storage that turns out I don't need and then I do my right and then exit group so cool want to try it with Python so like I said this course is relevant no matter what language you write because everything has to go through the kernel so we can see what Python does so let's see what Python does well that's rolled but what it do so at the end it did exit group while it had to because that's the way to end a process and up here is my right so it did some other things before that it seems also to be weird so it read the Python file that said print hello world and then it went back to the beginning and read it again so I don't know why it did that so if you want to go fix Python you can have at it clearly has some issue here but you can see it read that my source file it opened my source file here it looked at my directory it did some other weird things it got some errors it loaded some Python packages let's scroll up a bit more what it seems like it did a lot of stuff whoa what are you doing Python there we go so when Python started hey kind of did the C stuff oh it uses the math library math library is an alpha file uses a Z library oh there it goes so yeah Python uses a C standard library so that's cool to know but did a lot of things so we can see how much stuff it did so minus 2 so it did about 366 system calls for hello world seeded like 34 33 I think and we only really need to so now we can objectively see how bad JavaScript is so let's try this again both JavaScript all right so whoops all right any guesses for JavaScript is it gonna be way worse than Python or way better way worse all right better all right so it ended with exit group it should print hello world at some point so right hello world does anyone see right hello world on that screen at all all right so I will scroll through it quickly or not quickly slowly tell me when you see right hello world so that was a right to file descriptor 13 a bunch of zeros what could be have we seen it yet no we oh there it goes what the hell does it need to do after hello world program it's done so we can scroll up see it does a lot of things so if we see how many lines it actually did oh like my laptop's warm now all right 1045 if I minus the two lines so objectively it's probably at least three times worse than Python all right so you can go ahead and do that for any program you've ever executed if I wanted to you could S trace VS code you could S trace Chrome if you want it will produce a lot and a lot of output probably don't do that unless you want things to go slow but you can figure out what anything does and if you like have to ever reverse engineer something or just figure out what it does again don't care what language it's written in nothing just S trace it it'll tell you what system calls it makes and after this course you will understand a lot of the system calls and then generally what they do all right any yep no I did that yeah yeah so the S trace command you can tell it to output to TXT or a file name if you want it has a bunch of different options yep you can tell it to follow processes and be recursive yeah so you can tell it to just keep on going but yeah you can use S trace for everything S trace at the end of this course S trace will be your friend you can impress everyone and then you can objectively say you know how bad or worse something is and you know so we even saw some weird Python inefficiencies because it read the same thing twice well I didn't even need to know Python or know what it's written in to see that that's probably not a good idea any other quick questions all right that was a fun whirlwind tour to do all right so just so you have it I don't know I really know why I put on the slide these system calls are all too long didn't read for finding the C standard library so it needs to figure out where it is and then it loads the standard C library in the memory and then it sets up the heap even though we don't use it and then it finally does our printing so this at the end of the day we also saw no matter what language it was written in because everything to interact with hardware at all or to communicate between processes it has to go through the kernel so it has to use a system call so we can see what any program is doing so we saw the right system call with Python we saw it with JavaScript we saw it with C doesn't matter so oh yep oh the okay so let's say it so the the right system call has a return value so if you and actually printf has a return value anyone anyone want to tell me what printf returns how many of you actually knew printf returned something oh yep one nope kind of kind of yep yeah the number of bytes it actually printed and the idea behind that is hey you could actually check for errors because if it printed nothing oh then that's probably not a good thing but how many of us have checked for printf all right everyone's laughing so probably no one so right does the same thing it just returns a number of bytes actually written out for you to check for errors because well I could have written out like requested 12 bytes and the curl could be like yeah no I didn't do that sorry and well in this case I wouldn't have caught it because I didn't have any error handling code at all but I probably couldn't do anything about it anyways so turns out doesn't really matter but right and printf just returned the number of bytes read you've probably never actually used it before in this course we'll probably we'll have to check for errors so we'll do some right system calls and you should probably check for errors for those so you can think of the kernel as a long running process so writing kernel code is actually more like writing library code to because there's no main function so as part of lab zero just to get you familiar with how it looks without actually writing real kernel code you will write a kernel module yourself and then the code will that you write is actually going to execute in kernel mode so if you knew what instructions to call you could actually mess with the hardware and that's why I have you set up a virtual machine so you do not destroy something so the kernel lets you load some code into it as it is running so as soon as you boop your computer your kernel is running so the code you're allowed to insert into it that it executes is called modules and they load on demand so I can force it to load sometimes they load whenever you plug in like new hardware like a new USB device or something like that and again those are the code you're writing in your kernel module is writing a kernel mode so if you wanted to you could just end every single process on the machine if you want and again that's why we don't have you actually accessing some real hardware so this is the only actual important thing in this lecture so kernels have different architectures so the different kernel architectures separate what software runs in user mode and has no privilege versus what runs in kernel mode or kernel space and has access to the privilege instructions so things like virtual memory process scheduling so deciding what process should actually execute and IPC are all in kernel space and then other things that could be in kernel space are like your file systems how to actually access the devices that would be device drivers so actually you know interacting with your storage device and figuring out how that data is stored so the first architecture is called a monolithic kernel and that pretty much runs everything it can in kernel mode and this is what Linux is so anything that even is remotely has to do with hardware it's all running in kernel mode so some people most researchers think that is very bad because well if there is a bug in any one of those components and then you can start escalating your code and actually start running in kernel mode then you have access to the entire machine and it has no security anymore you get to control it so there is another architecture called micro kernel and the idea behind that is it puts the minimum amount of services in kernel mode and then puts the rest that it can into user space so things that have to be in kernel space are like basic inter-process communication so they can actually be separated from each other process scheduling what process one runs which and then virtual memory and then in user space you can put some more advanced IPC up there device drivers and file systems so don't worry about memorizing this right now it will make sense as we go in through the course and figure out what each of these do but knowing the two different architecture styles is good so there's other types of kernels too called hybrid that are kind of between that monolithic and micro kernel so sometimes in Windows any emulation will be done in user mode so like old DOS and like old versions of Windows will be done in user mode instead of the kernel and then on macOS because while Apple doesn't want you monkeying around with their kernel they'll put device drivers and things in user mode so that you know hardware people that are just creating hardware don't get to touch the sacred macOS kernel and then in research there's things called nano kernels and pico kernels that aim to like push more things out of kernel mode and that's a line of research if you happen to be interested in software research there's different architectural lines you can draw with different trade-offs yep well the idea is that the more stuff I move in user space that less code is actually in kernel mode and the less code you have the less likely it is to have a bug that's the whole idea behind it so doesn't kind of depends on code quality that's why the links kernel is so popular because well it's monolithic and it's good so seems to work out all right so lessons from the lecture kernel part of the OS that interacts directly with the hardware system calls of the interface those are the two important things and then the other ones were not important file format not important different architectures slightly important we'll get to them later so just remember pulling for you we're on this together