 Okay. Hello. Down here in the front. All right. Stay three of the door crisis. It's not been fixed yet. Okay. All right. So what we're going to do today is we started last time talking about how the operating system gains control of the machine. And this is important because the operating system is in charge. And it needs to not only have special privileges that normal programs don't have, but there are moments where the operating system needs to run. And if the operating system doesn't run in those moments or something else runs, then unsafe things are going to happen. So we're going to finish up today talking about hardware interrupts, which is one way that the operating system gets control. And then we'll talk about software interrupts and exceptions, which is another pretty important way that the OS gets control. And then I think we'll start talking a little bit about some of the limitations of the processor that the operating system is going to try to eliminate. Okay. So I have good news and bad news today. I'm sure everyone wants the good news first. You may not consider the good news to be good. I do, which is that test 161 is out now. How many people have used it? Yeah. It's pretty sweet. So yeah, and it's awesome. So if you happen, you need to and you will want to because it will grade your assignment right in front of you, which is kind of nice. Like other parts, so the instructions are online on the discourse forum for figuring out how to install it. It's also up on the website now. This is not optional. This is how you will eventually submit things and we're getting pretty close to being having that ready to go as well. So please get that installed and start using it. It's pretty nice. We've also been pushing a bunch of upstream changes to the staff repo. So please make sure you have those as well before you start running this. And thanks a lot to Scott and Yee Hong. We've been working really hard on this. Scott wrote most of the clock. I should say most basically the entire client side tool. Can I talk and you guys listen? Thanks. And Yee Hong wrote the web front end, which you guys will start to experience once you get to the submission. So it's very nice. I'm very happy with it. Okay, so and the submission stuff should be working soon. They're almost done with that. And if needed, we'll move the assignment one due date a day or two to give you guys more time to actually submit things. But don't count on it. If they get that done today or tomorrow, we'll just keep it where it is. How many people are done with assignment one? Everything works? Sweet. Okay, that's why I like to see. Okay, so now let me go through the bad news. This is a first. So it turned out apparently yesterday there was a very interesting recitation that was held in the afternoon in which large portions of the solutions that were displayed. How many people were at that recitation? So I'm a little embarrassed that none of you guys actually told anyone about that. One of you did. But there was like 24 of you that didn't. So apparently you guys want to pay $1,000 to not learn stuff. But I would suggest next time that happens, you let us know. But happily we found out. So here's what's going to happen. I feel like in the interest of fairness, if you would like free credit on assignment one. So assignment one is 50 points that works out to 5% of your grade. There were three parts of the assignment where there were quote unquote solutions that were displayed. Those were CVs, locks, and the whale mating problem. If you would like free points, you need to contact the core staff. No one's going to get them without at least emailing us. This is like a little bit of a low bar here. But if you want them, go ahead. So this is what I'm doing in interest of fairness. If you were not one of the lucky and a little greedy 25 who were there and who got to see them up on the screen for long periods of time, then you're welcome to contact us and you can get those points. Now there's a couple of caveats here. The first part is that the solutions weren't actually entirely correct. So that's an issue. We're going to add some test cases to the existing test scripts to catch some of the problems with these, but I would suggest that if you blindly cut and pasted what was shown that you rethink that, because again, not quite correct. I couldn't tell for the locks, I couldn't see, but the CVs in the whale mating were definitely not quite correct. The second note is that you need working locks and CVs to do the other assignments. So even if we give you 10 free points, you still don't get working locks and CVs. So I would suggest that you do this part of the assignment. And like I've said earlier in the class, you have two options. One is you do it now and you feel good about yourself for earning those points in front of the deadline. The other option is you wait, you get the free points and then nothing works on assignment two or assignment three ever. And keep in mind, those two assignments together are worth nine times what assignment one is worth. So this is just like, this was just a little part to get you started. Yeah. No, they're not on top of assignment one. No, you cannot get 70 points out of 50 on assignment one. Thank you for asking. I'm just going to clarify that. Those are in to replace. So if you've got like a nine out of 10 on the CVs and you want the 10 out of 10 because you think, apparently I had been at that recitation on the snow day where the idiot TA decided to show us the solution set, I would have had those points. So if you want those points, email us. But no, they are not, yeah. Every loophole will be exploited, apparently. Any other, okay. And then also we're not going to post the video for yesterday's recitation. Sorry. This is as much to avoid confusing people as any other reason. Because again, what was presented actually turns out to not be correct. It's also very hard to see. It's a little too blurry. Okay. Any questions about this? I hear a question right here in the front row. I think they were, in theory, I think they were supposed to be his solutions. Whatever. That things that were shown in recitation are things that should not have been shown. I also want to point out that that is in direct violation of the course collaboration policy. So if you communicate with each other like that, if you're trying to help somebody with their lock implementation, and you take a projector and you put your lock implementation up on a big board for them to look at, you will fail the class. I just want to point out that that is covered under the not talking in code part of the course collaboration policy, even if it's up on a display. Yeah, so please don't do that. Any other questions? I realize this is sort of an unusual situation. Again, it's not something that's happened before. The approach that I'm choosing is trying to balance my interest in you learning things with your interest in having the class be administered in a fair way. If you have a problem about this, please feel free to say, one of the rare times where you can email profitopsclass.org or post something on Discord so we can talk about it. But this is the, and again, this is not something I've given deep thought to because it just came up today. All right, any questions? All right, and I apologize for this, by the way. I mean, you guys deserve the chance to learn how to do these things, and when someone just throws up code in front of you in recitation, it's kind of not helping you learn how to do that, right? So this is a situation that will be addressed. All right. Okay, so back to Monday's material. Questions about privileges interrupts. We got through hardware interrupts. We didn't get to exceptions. Any questions about kernel privilege, how I get in and out of the kernel before we go on? Okay, so let's do a little bit of a review today. So why, we talked on Monday about the fact that the kernel has these special privileges. Why? Why does the kernel need special powers? Yeah. So the kernel certainly does not trust user programs. That's true, right? And I guess you're right. Not trusting a user program and having some sort of special power that it doesn't have kind of work well together. But what part of the operating system's responsibilities are really require that it have some type of special powers? Yeah, over here. Yeah, well really any system resource, whether it's a real resource like memory or disk or some sort of abstract resource, right? So yeah, multiplexing system resources. That's the real reason that I want special powers because I need to divide up the things on the system and I need to make sure that applications don't violate those divisions. If I don't do that, it's very easy for applications to take advantage of the situation and take more memory, more processor time or whatever than the operating system wants them to have, okay? Now we talked at the beginning of the class about the fact that operating system's multiplex resources and also provide abstractions. Do I need these special powers to provide some of the abstractions that we've talked about? True or false? True. Who wants to argue true? Raise your hand. Okay, false. Most people are in a quantum state. Anybody? Take a stand. False. False, why? Hmm, so a lot of those abstractions are built on top of hardware resources but the existence proof here, well there's a couple of existence proofs. One is that there's a lot of threading libraries like P-threads that provide a lot of abstractions that are very similar to what we've been talking about. P-threads allows you to fork. It's a new thread within the process. And this is a thread that's totally hidden from the kernel. The kernel knows nothing about it. There's also an interesting design point. We may come back to this at the end of the class where we start looking at some sort of research projects related to computer systems. So there was a project called the exo-kernel project that went on at MIT about 20 years ago. And they were actually able to take this idea of multiplexing and abstracting and providing abstractions and build a kernel that only provided multiplexing. It's pretty cool. It didn't provide any abstractions. And so all the abstractions were actually implemented in user space libraries. So it was kind of a neat design exercise. So what does this mean? We talked about the kernel having special privileges. What does that mean? What does it mean? What does this mean? I mean it sounds good. It sounds like I can do something that processes. But what can I do? Let's start calling out people like that. What can I do? Right there. Nope. That's you. You? Great in the gray cardigan. Yes. What can the operating system do that a process can't? Give me one example. Yeah. Yeah, but it's too abstract. How? How do I do that? What's the mechanism here? Yeah. Okay, still we're still not quite there. There's a couple of things that are special about the operating system. We talked about privilege. What does that mean? How does that map down onto the hardware resource? Anybody? Yeah. Yeah, so the processor itself provides a flag that says, am I in privileged mode or not in privileged mode? And there's instructions that will only work if I'm in privileged mode. If I'm not in privileged mode, they either don't work or they will cause the system to enter privileged mode, which is the way of getting you in trouble with the kernel because the kernel finds out that you're trying to do something you weren't supposed to be able to do. The other thing that was alluded to by one of the answers was that the kernel runs first. And so when we talked today more about interrupts, you may wonder, well, why are interrupt handlers connected to kernel privilege? Interrupt handlers are part of kernel privilege because the kernel runs first and it gets to install them. So when the kernel starts up during boot, one of the first things it does, and you can find this in your own OS 161 source code, is it installs interrupt handlers that point into the kernel. So that makes sure that any time there's a hardware interrupt or a software interrupt, the kernel is what runs. We'll come back to that later. Three things this is important to know that happen more or less simultaneously when an interrupt or exception occurs. What are those three things? Yeah, that's right. So I enter privilege mode. This is just hard-coded into the CPU. When the interrupt line is triggered, or when today we'll talk about how software interrupts are generated, the privilege level is automatically raised. I record some state about the system, and then I start executing at a particular location in memory. That is what's referred to as an interrupt handler. That's the code that's loaded there. The code that is run to handle an interrupt. And that code is installed by the operating system during boot. So this is a great question. How does this translate to hardware? These things are performed by the processor. So if I had a processor that was running along, doing stuff, executing whatever instructions, I mean processors are pretty simple. I load an instruction, I interpret it, I execute it, and then maybe it's a branch or a jump, and then I might go somewhere else. So imagine I'm going along doing that, just mind amount of business, and then an interrupt gets raised. Automatically, the processor jumps to this other location. It probably flushes out the pipeline and then says, okay, I'm jumping over here. And that's just something that the operating system relies on hardware to do. Does that make sense? That goes back a while. But your point about processors getting more complicated and providing more obstructions is certainly true. And that's something that we can talk about later, and we probably will talk about later toward the end of the class, because there's certainly been this very fun interplay, and this is one of the things that's cool about operating systems between the things that hardware provides and the capabilities that operate this was reliable. But this capability goes back a long time. This is not a new thing. Any other questions? So hardware interrupts are generated by some device that's part of the system that needs some kind of attention, or is just making its presence known. What are some examples of this? What are the types of things that would trigger a hardware interrupt on a system? Yeah. Yeah, mouse click. It's a great example. What else? Yeah. Ooh, a bad sector on a disk. Yeah, maybe. You know, that's interesting. An interrupt is probably the way that the disk might want to get the driver's attention to say, by the way, this weird thing happened. What else? It's kind of unusual. Up here. CPU tick. CPU tick. So a CPU tick, if you're talking about the instruction loop, would not generate an interrupt. If it did, I wouldn't be able to write an interrupt handler that was more than one instruction, because it would just keep triggering itself. There is a tick, though, that goes on up here. Yeah? Yep, that's true. The bus there probably generates an interrupt saying, oh, by the way, there's a new device, or there isn't a new device. Yeah. Keyboard. Yeah. I mean, it's a fun exercise left to the reader, and you can do this with your OS 160 warrant kernel to think about everything that happens between when you hit a key and when something's rendered on the screen. It's mind-boggling how complicated that is. You guys are so used to it, you just type it along, right? And it's like, computers are awesome, right? Like, it's just incredible, but it's incredible how much had to happen. The interrupts and everything has to be processed, and there's eight different layers, and then there's, like, a font that has to get rendered, and that has to be pixelated and shadowed or whatever. And then the whole screen has to get redrawn. I mean, it's just mind-boggling, right? And you're just like, oh, my terminal works. That's cool. Yeah, you don't really appreciate how awesome these machines are. You're just so, it's so natural, right? And of course, that's what you get, right? That's what you get from your 18 gigahertz processor, right? It's like, wow. Terminal works really well. OK, so, you know, and these are other things. Disk reads, network cards arrive. Timers fire it. So keep this in mind, right? We're going to come back to this because the timer firing is one of the critical ways that operating systems regain control over the system. A lot of these other events we're talking about, hardware events, they happen sometimes. They may not happen for long periods of time, right? The timer, the timers that are configured, now if someone said to CPU tick, there are timers that are constantly firing on modern systems that generate interrupts at a steady rate. You may wonder why. It just seems like overhead. All I'm doing is I'm generating all these stupid events for the operating system to handle. All those events say, oh, by the way, another 10 milliseconds went by. Those turn out to be really important. We'll come back and we'll talk about why. OK, so any questions about this before we go on? So to where we left off on Monday. OK, so jumping back in to finish off hardware interrupts. So, you know, we talked about hardware interrupts and in general hardware interrupts, you can imagine that the processor is configured to accept lots of different hardware interrupts from lots of different peripherals. So there's some, you know, a bunch like all the different things you guys were talking about. They might arrive on different interrupt lines. And that brings us to this idea of being able to ignore interrupts or mask interrupts. And hardware interrupts that are asynchronous, which means that I can sort of wait to process them. So the disk may tell me, by the way, I've got that data that you wanted. You know, it's here. It's in my buffer. When you get around to it, you might want to read it out. You're the one who told me to read this sector. I don't know what it's for, but I've got it, right? In that case, the operator says, you know what, I'm kind of busy right now. I'm going to come back to that in a few microseconds, right? And so the way I do this is I mask interrupts. And the processors frequently provide a way for the operator system to say, here are a set of interrupts from different peripherals that I don't want to handle right now. So if those interrupt lines are fired, nothing happens. This is usually done because I'm in the middle of doing something else. And a lot of times that doing something else is handling some other interrupt. Because there are certain cases where if I can't mask interrupts, I can actually create a cycle, right? Where I'm trying to handle one interrupt and that causes another interrupt. Trying to handle that interrupt causes another one of the first one, right? And then I get stuck, right? Yeah. Black magic. Yeah. We're not going to talk about it. I mean, yeah. But I just wanted to let you know this is possible, right? The answer, of course, is it's complicated. It depends on the types of devices and things like that. Yeah. So it depends, right? So the device is in control of these interrupt lines, right? So if I mask an interrupt and then while the interrupt is masked, the device decides I'm tired of waiting for the kernel's attention. I'm just not talking to it anymore. That wouldn't happen, right? But a timer actually might fire repeatedly, but then it would drop the interrupt line. So for example, a timer, those events don't get queued up. What happens is just I get whatever the next one that shows up, right? So if the interrupt is still asserted when the mask is dropped, then it fires. If the device has lowered that interrupt line, nothing happens. Does that make sense? Yeah. Cool. And there are also this category of synchronous interrupts that the operating system is not allowed to ignore. And these are almost kind of like panic in your kernel. It essentially says, look, there's something. You have to stop everything and do this because I'm about to shut down, for example, right? If the processor is about to reset, that's not something the kernel gets to ignore because it just means that everything else is about to stop. OK. I don't want to go through this in a lot of detail. And essentially, masking interrupts allows the system to establish a priority. So some interrupts are more important than others. And it also prevents the situation where I can generate a loop of interrupts and get stuck trying to run interrupt handlers and never make any progress. So this is kind of what gets me out of that. OK. So, yeah. Sorry. Yeah, exactly. So masking interrupts. So this is a great question. Controlling the interrupt mask on the processor. Privileged instruction? Non-privileged instruction. What do you think? Probably privilege. Why? What could happen if a process could change the interrupt mask on its own? So I can get all sorts of bad things to happen if I can control the interrupt mask for a process. But what's kind of like the basic one? I mean, maybe you guys are probably too young to have played with those old Apple II computers. I'm sounding like a broken record. I keep bringing those up. But they're kind of interesting. But anyone ever write those basic programs in high school or in middle school that just printed the same thing over and over again? You would run them on the lab computer and the teacher had no idea how to get it to stop. They'd have to call the IT department. You're like, just hit Control C. Come on. But then you can write the basic code that denors Control C, and that's even hard. Anyway, so if I'm that kind of program, what can I do? I start to run, and for some reason, the system allows me to control the interrupt mask. Disable all interrupts. I'll take that answer and make it workable. Disable all interrupts. So I just want to run. I just want to compute pot. I don't want to tell anybody about what I'm computing pie because doing that would require interrupts. But I just want to compute pie privately, just by myself. And so I'm just going to turn off all interrupts and start computing pie. No timers ever fire. Everything that happens outside my own little world is just like I put on blinders. I have my Bose earphones on. Nothing will stop me at that point because the operating system will never run again. When does the operating system get a chance to run? When interrupts happen, when I need attention, but I don't need attention. I'm computing pie all by myself. I'm not telling anybody about it. So I don't need anything from the system. I just need to run in this loop forever. So controlling the interrupt mask is a privileged action. Did I answer a question? I think I did after a long digression. Okay. So there we go. I just said that. So the interrupt handlers are part of the system that the operating system has to maintain control over. So alternatively, if the user program could install its own interrupt handlers, it could pretty much do what I just described, but it would even be better because I could communicate with devices. I could set timers. I could do all the stuff that the kernel is supposed to do, but I would never have to let the kernel run ever again. I could just become the operating system. So to prevent this from happening, the interrupt handlers are loaded into an area of memory that's protected and applications are not allowed to write. So if I try to overwrite the interrupt handlers for some reason, that operating system should stop me and kill my process because that's an area of memory that is off limits. All right. There we go. And again, going back to something I said earlier, and I would encourage you guys, I have two which is already on the website. We'll put up some screencasts, and one of the things we'll do is we'll look at boot. So the code for boot is already in there, and if I were you, I would take advantage of the opportunity to read probably the most well-commented boot code you will ever see. And one of the things, I mean your kernel, like every other kernel, one of the first things it does in the assembly code when it starts to run is it copies its exception handlers into the places where the hardware expects them to be. Remember, the hardware is going to jump to a predetermined instruction and start executing. The MIPS processor that this 161 simulates does the same thing. It turns out it has two different exception handling routines. One is for memory-related exceptions, a very specific category of them, and the other one is for everything else. And that's one of the first things your OS 161 kernel does. It copies that code over so that it can make sure that it handles all the exceptions that are generated by the machine. Okay. So now the question, we sort of got to the point where we've talked about how the kernel locks down the machine. How the operating system makes sure that it keeps control over what's going on. So you might sort of be wondering how do applications ever get anything to happen? So I'm running along and I'm in application. Let's say I want to read from the disk. Well, I can't handle the interrupt that the disk generates, and I can't write to the disk directly. So what am I going to do? How do I get the kernel's attention? So there is something, yeah, so here are some examples. I might need to read some memory. I might want a larger to increase the size of my heap, need more memory. So what's kind of clever here is that CPUs pretty much reuse the idea of an interrupt to provide this capability. And this is what's called a software interrupt. So we've been talking about interrupts that are generated by hardware. So there's some, you know, electric line attached to the processor that gets raised from a zero to a one. I can trigger the same behavior in software using a special instruction. And on the MIPS that you guys are using, it's called syscall. On the x86, I think it's called int. It's interrupt. It's a software instruction that generates an interrupt. Now the nice thing is once I do this, the rest of everything else is the same. So when I run the syscall instruction, what is the CPU going to do? This is a chance for us to review. When the syscall instruction is executed, what does the CPU do? So it enters privilege mode, it records some state necessary to process this interrupt, and then it starts executing the kernel. It jumps into the exception handlers. This is the same thing that happens when a hardware interrupt is triggered. And if you look at the code that we've given you for OS 161, one of the first things that happens on the interrupt handling path is that your kernel figures out whether this is a software interrupt or a hardware interrupt. The hardware interrupts vanish into the lane bus code that you should never ever read, and the software interrupts get handled by you, it turns out, in assignment two. So again, we've been talking about the kernels having an interface like a program. Function calls, essentially a set of function calls that applications can make. The way that they make them, though, is different. It's different than the way you would make it in a library where you would push some arguments on the stack and jump into the location of whatever function you were trying to access. Instead, what I do is I use this system call instruction to trigger the operating system to start running. And then what I need to do is I need to tell it what to do. So the syscall instruction by itself is not sufficient to give the kernel close to enough information about what I want to happen. All the syscall instruction does is tell the kernel, hey, I need help. There's something I need to do that is your job because you're in charge of managing the system resources. So I'm asking for help. And so in order to sort of get enough state into the kernel for this to happen, there's a calling convention. And this is, again, pretty similar to the way that functions get called in most languages. When the kernel starts to run after a system call, it's going to expect that the application that generated the system call has prepared some information in certain registers that is there to tell the kernel what to do. So for example, I might need to identify what kind of thing am I asking you to do? What kind of system call am I requesting? For example, is it a read? Is it a write? Is it fork? And then normally those function calls have arguments. And so I need some way to get those arguments into the kernel as well. So we talked before about the fact that when you call read or write from the C library, you're actually not calling the system call. Instead, what you're doing, and what the C library does for you, is it knows, so read, write, fork, all of those end up generating the same instruction. The instruction is syscall. What's different about those calls? How does the kernel know what to do? So when I do a read, I'm going to eventually call syscall. That's all that's going to happen. The kernel's going to trigger a software exception. The kernel's going to start to run. How does it know that I wanted to do a read? I don't know what you mean. All I know when I enter the kernel is that there's a software interrupt that's been triggered. And on MIPS, syscall takes no arguments. So there's not even a way to pass one bit of data. So how do I know? Is it based on the predetermined place that the interrupts go? Nope. So remember, on the MIPS, there are only two places where interrupts go. And most of them, all the system call interrupts on MIPS go to the same place. So every time I execute syscall, whether it's a fork or a clone or an open, I end up running the same code. So again, how does the kernel know what to do? I don't even know what that means. That's an interesting idea. I wish I understood what you were saying. No, because remember, all the kernel knows. The kernel just wakes up suddenly. It's like, whoa. I was asleep. What happened? Oh, there's a system call. Now what happens? Yeah. Again, I'm executing code in the kernel. All I know is that there was a software interrupt. OK, so he makes a great point, which is that this is a place where there needs to be agreement between user space and the kernel about certain things. Because again, we're not speaking English. We're talking numbers. And so what actually happens is the user program will say, syscall 8. And the kernel is like, huh, interesting. What is that? And so I need a way so that the user space knows that open is 8 and the kernel knows that open is 8. And we have to agree on that. And this isn't one of the header files. In your kernel, this isn't a header file that's exported to user space for this very reason. Because if we don't agree on that, nothing can happen. You said, read, I closed the file. Because again, so we're getting closer here. How does the kernel know what to do? I call syscall. It's actually on the slide. That's what's really funny. Yeah. Yeah. Right. So remember, I have to have this agreement on the mapping from the number to what is going to happen. So the kernel and user space have to be able to agree. And if I want fork, what number do I load? And what the user space program does is it loads that number in a register. So there's a predetermined location. I can't remember where it is on MIPS, but whatever. You guys will know by the time you're done with assignment two, where the kernel and the user space agree. When I start running a system call, the kernel is going to start to run. And it's going to say, aha, you loaded 18 into register whatever. 18 means that I am going to try to execute. I'm going to try to create a link. Or I'm going to try to seek a file or something like that. So this is part of the calling convention for syscall. Now the next thing is, how do I get the rest of this stuff? So let's say I did a read. What other information would a read want? So now I've been able to identify that I know what I want you to do. But what other information does read need to tell the kernel? Yeah, I need to identify the file I want to read from. What else? That's going to be checked during the read. But I don't need to tell the kernel that. The kernel, the file system will know that. At some point, the file system will say, OK, process challenge is trying to access this file. Does he have permissions to do it? But that gets handled usually by the file system during the operation. I'm going to read data from a file. What else should I tell the kernel? I definitely need to tell the kernel the number of bytes. That's important. It turns out the offset on Unix is kind of weird. It turns out to be inferred. So Unix maintains an offset, but that offset is just kind of pushed along. So when I do a read, I'm reading from wherever the offset in the file already is. But there's something really important here that I haven't said. What do you mean? Let's say you want to print something. Well, no, no. That's a separate operation. But you're getting there. Yeah. Like, where do you want the data to go? The kernel is going to be like, oh, by the way, I've got 512 bytes of data. Where in your memory do you want me to put it when the read completes? So when the read is done, I know that I've got a buffer that I provided the kernel that now has data from the file. So how does this information get into the kernel? So I've identified the read by sticking the number in a special register. What about the rest of this stuff? Where does it go? How do I communicate it to the kernel? Yeah. I don't know what that is. Well, look. I mean, let's think about this. So how did we identify the system call we wanted to perform? What did the user program do? It put a number where? Into a register. Let's just apply that same principle again. Let's say there's a memory address where I want you to put the read when it's finished. Where could I do with that? Put it in a? Another register. Another register. Right? What about the, it turns out there's a number that identifies the file. Remember, open returns a file descriptor, which is a number? It turns out it's very handy right here. Because I don't have a path, I have a number that identifies the file. Where do I put that number? In another register. I've got like three, I've got a bunch of registers, right? I mean, whatever, registers are cheap. So it turns out at least on OS 1.61, there are, I think, like four arguments that can be passed in registers. And that actually ends up being enough for a lot of the system calls. If I need more information, so give me, can anyone think of a system call where I definitely would not be able to fit everything into a register? There's a file related system call where it's totally obvious that I just can't, I don't have enough registers. Or I can't have enough registers. Any guesses? What about open? What is one of the things that open has to tell the kernel? I want to open a file. What do I need to tell the kernel in order to do that? The file itself, how do I identify the file? Well, you're getting ahead of me, right? The file name is a what? A string, right? It's an array of characters. How long could the file name be? Like arbitrarily long, right? I mean, I don't want to be like, well, sorry, your file name was more than four characters. Therefore, I couldn't pass them directly in registers and you can't open a file. That would be a very sad file system, right? You would have, I don't know, how many? Somebody is mumbling up there. What's that? All right, I mean, again, if I had to pass it in registers, I could open any file as long as the name was only four characters. So again, I mean, that limits you a little bit. You'd probably run out of files. It'd be difficult to organize them. Your directories would only have one letter in them. That's sad. Anyway, so there are certain cases where I need to pass arguments from user space to the kernel by passing a pointer or some other way, right? But in a lot of cases, it's sufficient to put things into registers, right? You guys will know how to do this by the time you're done with the assignment. Okay. So those are software interrupts, right? A software interrupt is a case where the code wanted the kernel to do something on its behalf. It knew that. You wrote code that said, I am going to read data at this point in my program. The C compiler took that code. It expanded it to use the system call instruction, and that's what got executed. I would encourage you guys to use, and maybe this is something we'll do for assignment two, is the screencast. Guru's going to love doing all these screencasts, I'm promising, is take one of the binary files that we gave you, deassemble it, and look at how it works, right? I guarantee you can find the CIS call instruction in every user binary that we give you because they all need to communicate with the kernel. So software interrupts are cases where, again, I knew I wanted to open a file. I called the kernel for help. The kernel helped me out. The file got open. That was great. Software exceptions are different. So software exception, the biggest difference in interrupt is that the code wasn't meaning for the kernel to get involved. And there are some silly cases of software exceptions. It also is a case where I cannot execute the next instruction without calling the kernel for help. I simply do not know what to do next. There's like no way to proceed. What's an example of a software exception that could trigger? Yeah. Ah, okay. You got a no pointer exception. So that's a great example, and that is right, right? You guys have seen the segmentation fault error? How many people have seen that? Well, come on. You all took 250, right? Give me a break. So that is, and we'll come back to that when we talk about memory, that error, does anyone understand what that error means? You are going to understand what it means by the time you finish this class. It's like, I think that's the best thing people think that they take away from this class, right? Is they understand what it means, segmentation fault, right? What does that mean? I will tell you later. So that's one example, and that's a great example, because what it means is that I try to access this piece of memory that I can't access. There's nothing there. So what is the system supposed to do? I read from a memory address that doesn't exist. There's nothing else to do other than kill your program, right? You may have thought, this is so mean my program keeps crashing. There's nothing else to do, right? Like what value am I supposed to put there? So actually it turns out that at some point, some people were doing some research on making software more robust. And they found out that in certain cases when programs hit these sorts of errors, if you just return zero, everything works, right? So it's kind of funny, right? Instead of giving you an all pointer exception, if I just pretend that that memory contained zero, the program will just keep running, right? And sometimes we'll keep running happily. But anyway, that's not what we do. We kill the program because there's really no way to proceed. Other ways, other things, divide by zero. What's the result of dividing by something by zero? It's undefined, so I can't, like the CPU just can't complete that instruction, right, if you try to divide by zero. Another example we talked about before, try and use a privileged instruction. I can't let this instruction complete. Because doing so would mean allowing the process to do something it's not allowed to do. So I call the kernel for help. Now, so you might be thinking, well, software exceptions sound bad, right? It sounds like most of the time when a process is running along and the kernel suddenly becomes involved and it wasn't expecting to become involved because I didn't interrupt it asking for help, it's bad. But it turns out probably something like, I don't know, 99.999% of software exceptions are completely benign. And the reason is that they are heavily involved in transiting virtual memory addresses. So this is something we'll come back to and we'll talk about in a great deal, a deal of detail when we talk about virtual memory. But this is another case. It occurs when the process is trying to use a memory address, something that thinks its memory, and the kernel has some work to do to make it act like memory. But this is by far the most common case of a software exception. All right. And again, just to highlight the differences. So the interrupts are voluntary. An interrupt is me asking for help. The exceptions, so this is kind of like, again, I mean, I would like some help doing a particular thing. Exceptions, on the other hand, are non-voluntary. It means that I was running along and suddenly the kernel started running. And I didn't do anything that I thought was going to cause the kernel to run. And in some cases, like I said before, most of the cases, the process is going to be restarted and it's never going to know anything happened. But there are some of these cases, like if I divide by zero, where essentially the kernel just has to throw up his hands and say, I don't know what to do. I just have to kill you because there's no way for you to continue. OK. All right. Any questions at this point? Let's see where we are in time. I might just stall and do this next time. Any questions about privilege, interrupts, exceptions? Everything makes perfect sense? OK. So I think I'm going to stop a few minutes early today and we'll pick up on Friday. This is kind of a good stopping point. Good luck with assignment one. Like I said before, I'll post on discourse through the details of the assignment one un-mess-up policy. And I'll see you guys on Friday.