 Is that better? Great. So we'll finish talking about interrupts and exceptions. We'll talk a little bit about sort of historical rise of CPU multiplexing and then talk about preemption and contact switching and how that actually works in the kernel, so how the kernel actually switches between threads. And all sorts of technical difficulties today. So again, the first three assignments are up. We're going to start grading the code reading questions for assignment zero today. So when we do the grading, you guys will start to see scores appearing on your page. And I think I've decided to let you guys try to submit those questions like twice. So once you see your grade, for the first set of code reading questions, you'll be able to submit a new set if you like. If you'd like to try to improve your scores on any of those questions and will grade those, at which point you'll take the scores on those. The scripts can be uploaded as many times as you want. There's still definitely some bugs on the website. Wembley found one this morning. So the script files you upload should be just plain text. If you have to do something weird to them to get them onto the website, then you're probably doing something wrong. So ask a question in Piazza or something and we'll help you. But if you have to convert it using some strange dodgy program that you found on the internet somewhere in the chat room, then that's probably not gonna make our grader happy. And please start on the assignments. How many people have started on assignment zero, done most of the scripts, uploaded everything? Okay, awesome, okay, great. How many people have started on assignment one? All right, so maybe next week I'll start badgering you about assignment one because you guys are doing okay, but you should be on to assignment one next week and the code reading questions are up for that. And I think the other questions are up as well, though they may not let you submit them yet, but we'll fix that over the weekend. All right, so on Wednesday we talked about, we sort of introduced the idea of CPU multiplexing and tried to motivate it. We talked about kernel privilege, which is one of the mechanisms that the kernel uses to enforce multiplexing, not just at the CPU, but of other system resources as well. And then we started talking about interrupts, we got through a little bit about a hardware interrupt. So questions about the material that we presented, we covered on Wednesday before we do a little bit of review. All right, see here. So why does the operating system need special privileges? We're gonna start at this side of the room today. Jen. So, right, so it needs special privileges to divide resources, right? So other programs on the system have essentially ceded control of resource allocation to the operating system. What else does it need to do, Sarah? So that's part of multiplexing, right? But once I've divided the resources between applications, what else do I need to do? I need to enforce the division. I need a way to prevent these buggy or malicious applications from either accidentally or purposely taking resources that I've given to other applications, right? So I'm gonna divide resources and I'm gonna enforce those divisions, right? This is the reason that we've given these special powers to the operating system. This is one of its main jobs and it's the job that requires that it had these special privileges, right? All right, true or false. Implementing common operating system abstractions requires special privileges. I don't know your name, but I should. Reimo? Reimo? Yes. True or false. Implementing common operating system abstractions requires special privileges. False. Why not, and can, Spencer, can you give me a counter example? Oh, there's Spencer. I'm coming back to you. Don't think you're off the hook. There are two Spencers, two Gens, at least two Daniels, so they're okay, yeah. This is an example of redundancy, right? Okay, so yes, libraries, threading libraries, and also, we didn't talk about this on Wednesday, but maybe we'll get back to this at some point. There's a design pattern called exo kernels where a lot of the abstractions are actually implemented in libraries that are used and the kernel is kind of boiled down to just the tiniest, tiniest little bit of what it needs to be, and that is usually to enforce these resource divisions and divide resources, right? So to not provide these abstractions, right? All right, let's see. So what about the processor, Tim, is what processor feature exists to help the operating system divide resources, give it some special power? Yeah, so we have this thing called, you know, privileged or kernel mode, right? Which gives the kernel access to special instructions, potentially allows it to modify registers that you can't modify when you're running another mode, et cetera, right? So this is kind of like where this begins, right? It's something that's actually built into the hardware, right? So hardware interrupt, right? A hardware device needs some help from the kernel. When this happens, what does the CPU do? Another Tim, I think. See, we have two Tims, too, right? Okay, so it enters privileged mode, okay, that's good. What else? Samuel, there's three things. Rune, you wanna help them out? Yeah, it's trying to help the kernel out, so it's gonna record some state about what happened, right? So when the kernel starts executing, it can figure that out and then Robert, what's the third thing? Yeah, so it jumps to a specific spot and starts executing instructions, right? Hard-coded memory address that the CPU will jump to every time the interrupt handler and interrupt is raised, right? An interrupt fires, a device needs attention, okay? Hardware interrupts. What are some examples of hardware interrupts? Let's see, we're going this direction. Alyssa, just examples of things that hardware would do that would require the kernel to help it. Yeah, okay, those are great, right? So there's a keyboard event, right? Like someone pushed a key on the keyboard, right? Or the mouse has moved a certain distance, right? Other examples? Josh, yes? Disrecomplete? Disrecomplete, Nick? Yeah, all sorts of things. So these happen when devices need attention and then there's a variety of different types of hardware interrupts that could happen, right? That would mean that the CPU and the kernel would get, the kernel would need to get involved, okay? All right, good. So any questions about this before we plow forward? Yeah, Brian. So I know, yeah, it's a great question. So it's not exactly an answer to your question, but I believe at some point in time, there was a, and this was decades ago, right? When hardware and software architects were still kind of working this stuff out together. There was a processor that came out that could not, for some reason, could not record the state of the system when the interrupt happened. And so that processor was not able to properly handle interrupts. So architectures that used this had to have a second processor that was specifically just for doing this, right? So when an interrupt happened, the first processor would be halted, right? All the registers state would be the same, right? Which is essentially what a context which preserves, we'll talk about that maybe more later today. The second buddy processor would handle the interrupt and then you would switch back to the first processor. Of course, this is really stupid, right? Because this second processor sat there idle most of the time, right? So you had twice the processor cost, right? And processors are not cheap, right? I mean, how many people have ever bought a CPU for a machine that they were building? I mean, you're plucking down a good 300, 400 bucks, right? For a good one. And now you have two, right? And one of them sits there by itself all the time. However, so there's a different answer to your question which is, can you optimize some of this in other ways, right? And there has been work recently on sort of using, how many people know what FPGAs are? Yeah, so kind of using reprogrammable hardware to try to optimize some of the things that the operating system does, right? But as far as using a separate processor, I would argue that that's probably overkill because now I have a processor that sits there idle most of the time, right? When it's not actually executing handling interrupts, it's just sitting there. And why would I want a machine where only one processor is working at any given point but there's two processors in the box, right? But yeah, that's a fair question, yeah. No, no, I don't know. I mean, on multi-core machines, you could have a single core that was kind of dedicated to trying to do as much of this as possible, right? Practically, the other thing that happens when we start talking about software interrupts today is many software interrupts, and this is somewhat true for hardware interrupts too. There's synchronous, right? So if the software could go on and continue doing useful work, then it might make sense to offload the processing to another processor. But in many cases, that's not true, right? In many cases, once, for example, once the disk is done doing a read, it kind of needs the processor to do something to it before it can keep going, right? So whether or not that's one processor on the system or a lot of many, or just the single processor that we kind of like to think about in this class despite the fact that we live in a multi-core world, it's still, it's kind of like, now you introduce this additional parallelism problem. So it's possible that that kind of architecture would be able to take advantage of a little bit of parallelism that exists, but I think we're still working on using those sorts of asynchronous system calls better in user space libraries, so it's a good question. Hopefully at the end of the class, we'll get a chance to talk a little bit about sort of some modern operating system developments that have to do with continued evolution of hardware and some other interesting properties. Yeah, Brian? Good question, I don't really, I mean, remember, I think we grouped traps into interrupts and exceptions, right? And interrupts we group into hardware and software interrupts. So I think of a trap as, again, anything that causes the CPU to start executing and causes the kernel to start executing, right? Anything that causes the CPU to jump to the specific point and start executing code, right? That can be hardware, software interrupts. It could also be software exceptions, right? So that's, if I recall correctly, that's the taxonomy we had developed. These are good questions, Jim. Sorry, you said the port did what? Burns out? I don't know what that would cause. That's a good question. I mean, it would depend. That could cause an interrupt, right? It could also just cause the USB device to stop functioning properly, right? And then in that case, the driver would probably have to notice that and do something useful. Did this happen to you recently? Okay. Yeah, look. FPGA, field programmable gate array. Man, you guys are tough today. What's that? Don't try, I'm confused enough as it is, okay? I'm always just lurching right on the brink of confusion, so don't push me over the edge. All right, any other questions? Good questions. All right. Okay, so we just reviewed this. When the interrupt is triggered, right? The processor enters privilege mode, records the state necessary to process the interrupt, jumps to a predetermined memory location and begins executing instructions. Before class today, I was actually looking around and I didn't have enough time, but I was hoping I would be able to find the code that in your OS 161 system, so I hope that this is something that Ditya will do in recitation next week, you can find the code in your kernel for when the kernel boots, one of the first things your kernel will do, and you don't have to do this, it's done for you in assembly, is that it copies the exception handlers to the place and memory where the MIPS processor expects to find, right? So, and you guys can find the code that does that, right? It's assembly code, but it's readable, it's very well commented. So again, we call this thing that the processor executes when an interrupt fires the interrupt service routine. So we need to finish talking about hardware interrupts, and there's just one important thing to point out here, right, is that hardware interrupts can be either asynchronous or synchronous, and asynchronous interrupts, an asynchronous interrupt means that the interrupt occurs and the processor is notified about it, but it doesn't have to take action immediately, and the way that it can prevent itself from taking action immediately is it can choose to mask an asynchronous interrupt. So when the processor is executed in privileged mode, there's an interrupt mask that it can set on the processor that essentially tells it, I don't want you to tell me about certain kinds of interrupts right now, right? So, so right, so if an interrupt is masked, that interrupt will not trigger the ISR when the interrupt is raised. As soon as I unmask that interrupt, then it will trigger the ISR, right? So I'm trying to have a good analogy for this, but you know, essentially the, the mask tells the hardware, I mean, you know, the disk, I'm ignoring you, right? This is kind of like what I do to Jeremy sometimes when he's trying to ask, answer lots of questions, right? I'm ignoring you, I'm ignoring you, I'm ignoring you. Okay, I'm done ignoring you now, and now you know, I'll handle that interrupt, right? So why would I do this, right? This is a feature that's very common. Why would this be a useful feature? Yeah, okay, yeah, that's, so that is probably not because the interrupt's being masked, it's probably because the screen isn't painting properly, right? So that's a different type of problem, but that's a good observation, right? So, but sorry, I messed up my flow on the slide. So the synchronous interrupts cannot be masked and certain types of synchronous interrupts are really serious conditions that, you know, there's no way to ignore them, right? So for, there aren't usually too many of these, but one example is like a processor reset, right? The processor resets, you know, there's no, the kernel can't ignore that, right? Something has to be done, right? Jeremy, yeah. Yeah, so there's certain, you and Bethany have collaborated to get this answer right. So interrupt masks allow me to establish interrupt priorities, right, so there's certain cases where in the process of handling one interrupt, either the process of handling that interrupt may generate other interrupts, right? And then I could get into this interrupt storm where I was just sitting there trying to process interrupts, but every time I, it was like, you know, it was kind of like recursion. Every time I try to handle the interrupt, I create new interrupts, I try to handle those interrupts, create other interrupts. So it's possible sometimes I just need to be like, turn them off a bunch of things, let me handle this interrupt and then I can kind of work down the stack, right? The other reason is that sometimes some interrupts are actually more important to handle than a timely way than others. So, you know, this is my canonical example, you know, so why in this case, pick on somebody else today, Swetha, why would it be more important potentially to handle a DVD write buffer empty interrupt than a network packet is waiting interrupt? Well, I might, I want to prioritize the DVD write interrupt over the other one, okay? Why? So what's going to happen if I don't, if I don't handle the, is it Unchal? Shikar. Yeah, so like, you know, my DVD writer might be like, it might have the disk up at full speed and I might have a write session open and if I don't fill the buffer, it might like start writing zeros into the disk and, you know, these are like write once type of disks and so that they would ruin the whole, ruin the whole DVD, right? Whereas you know what, if I don't get to the network packet for, you know, 10, 20 milliseconds, stop the end of the world, it's still going to be there, probably, right? When I get back to it, right? There's a question over here somewhere and then it went away. Jim? Okay, all right, good. And then again, there's other cases where, you know, and I don't want to go into this in too much detail but you know, handling some interrupts would generate other interrupts and that would make it difficult for the system to finish doing what it was trying to do in the first place, right? All right, so, what about the interrupt handlers themselves, right? So I said that the kernel installs these, right? On boot, it puts in place its own interrupt handlers. What would happen if I allowed application, you know, this sounds like a cool feature, you know? I'm just going to allow applications to install their own interrupt handlers. What would happen? Is it charging? What's that? It would be uniform, but what could they do, right? Okay, well, yeah, that's one thing they might do. That sounds like a nice thing that they could do. All right, we're good. Well, remember, I'm not changing the number of interrupts. I'm just allowing applications to install their own interrupt service routines. I mean, hey, you know, this is a solution to Brian's problem. Like, the kernel is constantly getting involved in meddling. You know, I'm the DVD writer application. I should be able to install an interrupt handler for when the DVD write buffer is empty. Thomas, okay, the kernel can't help. What else can't the kernel potentially do? AJ, yeah, we're moving in the right direction. Yeah, you want to add something to that answer? Yeah, Thomas. So this would mean that essentially, well, I mean, there's two things that can happen. First of all, yeah, I could just take control of devices, but the kernel might never get control again of the machine. Interrupts are the primary way that the kernel gets control of this machine back from applications, right? We're talking about hardware interrupts. We'll talk about software interrupts. And the later we'll talk about scheduling, which requires hardware timer interrupts to give the kernel a chance to run, right? So remember, at some point, in order to allow an application to do useful work, I have to let it run on the CPU. So I give it the CPU and I let it go, right? But at some point, I want the machine back, right? Because if I don't ever get control again, I'm the kernel, right? Let's say the application sits there in a while one loop. What's gonna happen, right? The kernel, you know, and let's say there's no, let's say the application starts to run, it installs its own interrupt handlers, and then sits there in a while one loop. The kernel will never run again and your machine will never do anything again, right? Certainly the mouse will not move, right? Unless the application deans to allow the mouse to move, right, it decides to paint the screen, right? Maybe it'll paint like, you know, you have been hacked or something. I mean, this would be terrible, right? So anyway, so this is, yeah, this is essentially, this is the main, one of the main ways that the operating system retains control of the system is that it says every time there's an interrupt, every time there's an exception, I get to run. Me, the operating system. And again, we'll talk about in scheduling how the operating system uses a device, specifically a timer to make sure that no application is allowed to run forever, right? Even if there weren't any hardware interrupts, right? Even if there was a situation where for whatever reason the mouse wasn't moving and the disk wasn't operating and the network wasn't receiving packets, an application would still not be allowed to control the CPU forever because something will happen that causes the kernel to be able to run. And the way that we do this is very simple. It just, you know, the memory that contains the interrupt handlers is protected by the CPU and by the memory management unit from modification by user space application. Yeah. So whenever we are installing a new hardware, play an input device or something like that. So it has its own application, right? Like the device driver. It has a device driver, right? So isn't it the application which is controlling it? Like the interrupt? Because the operating system didn't have that earlier. I just installed it. Right, right. So, but what the operating system did have is first, so first of all, normally there aren't, if you look at your OS 161 system, there's really only one interrupt service routine. That interrupt service routine branches out into the kernel and ends up calling a bunch of other code, right? But a lot of times what's really happening is that there are standard buses on your system. For example, your system motherboard might support like SATA, right? And SATA interrupts are gonna end up on the processor somewhere. They're gonna cause the kernel SATA bus code to run. So when you stick in a new disk, right? The kernel doesn't have to modify most of this, right? What happens is that there might be some piece of code at the very end of a long chain that has to figure out how to deal with a different type of packet. But if you install things like disks and there are all these standards and stuff like that, so there really isn't much that changes here, right? But other types of hardware devices usually sit at the end of some bus, right? That means that what they're really doing is exchanging packets of information with the kernel, right? And what a device driver is doing is taking that information and acting on it and using it to control the device, right? But essentially my point is that like most of this doesn't change, right? But at the bottom of it, there needs to be, yes, some code, which we call device drivers, that understands how to talk to that device, right? Most of the communication protocol itself is handled by the kernel and by sort of standard interfaces, right? This is what USB, SCSI, SATA, all these things are. They're standards for how to move data back and forth to devices, right? That's a good question, though. I wish we could go more in detail to this gooey stuff, but if you guys wanna see how this works, look at all the, David Holland invented something called the lane bus, which is the bus that Sys 161 uses. You can, all that code is there in your tree. I don't encourage people to poke around in there because you don't need to, but if you want to, I wanna see a little bit about how this works. That's there, and it implements a very, very sort of simple set of devices, character devices and things like that that you need to operate your system. All right, oh, I think, and again, so one of the first things we do about booty is install interrupt handlers. I think this guy's about to go off. Sweet. Okay, so we've talked about hardware interrupts up until this point, right? And hardware interrupts are the mechanism that allows hardware devices to receive attention. But remember, I mean, really, most of what the kernel is doing, or a big part of what the kernel is doing, is supporting user applications, right? The kernel is sitting there between hardware and user space applications, right? And so we've talked about, you know, requests for attention and requests for support that come up from the hardware level, right? But in order for it to be useful, I have to be able to handle stuff that comes down as well. I mean, that's the main thing I wanna do. And there's various types of requests that applications are going to make of the kernel, right? So if you know anything about C and you know how normal C library calls happen, right? You know, when you make a call to the C standard library, you push some arguments onto your stack, you jump to some other memory address where this C library is located, you execute the code there and then the library returns a result and there's all these standard calling conventions, right? The way that applications communicate with the kernel is quite different, right? Because the kernel is kind of living in its own protected memory space and we wanna have a very, very secure and narrow interface allowing applications to request attention of the kernel, right? That prevents them from running kernel code themselves, prevents them from modifying the kernel. I mean, if you write your application in C and you use the C library, you can blow away the C library. You can find out where the C library lives and you can just write over all its memory and you can destroy all of the useful functions that are there, right? I don't know why you would do that because presumably you loaded the C library because you wanted to use it, not mess with it, but you could, you could, right? We can't let that happen to the kernel, right? So what we do is CPUs overload or they reuse this interrupt mechanism to allow software to get control of the kernel. Remember, when an interrupt happens, the kernel starts to run, right? That's the main upshot of what happens is that I jump to the exception handlers which were installed by the kernel and my kernel starts running and handles the interrupt. So what I do is I provide a special instruction and on MIPS, this instruction is called syscall on x86 processors, I think it's called int for interrupt that generates a synthetic interrupt. So there's no logic level change on any line leading on to the CPU. Instead, this system called, sorry, this instruction, right? This assembly instruction, this instruction that's part of my ISA just causes the same things to happen, right? So this now provides a mechanism for software to request attention from the kernel, right? So when, you know, for example, I wanna read some data from disk, I need the kernel to do that for me, right? And so I need the kernel to start running and this is the instruction that will cause the kernel to start running. So this will cause a trap, this is a software interrupt. And essentially the rest of the interrupt handling path is unchanged. So I get a chance to put this up on the slide for like the fifth time, right? I enter privilege mode, I jump through specific instructions, start executing, oh, so I record the state and I jump to my predetermined memory location, I begin executing instructions, right? So again, if you guys look through your source code for, you know, OS 161, you'll see that the exception handling code eventually hits two big branches, right? One branch is hardware stuff, right? And all the hardware stuff essentially goes down the lane bus handling path and that ends up in all the device drivers and stuff like that. And the other path is system calls. And for assignment two, you guys right now, there's like one system call implemented on your system and after you guys finish the assignment two, there'll be like a dozen, right? So you guys have to handle these system call generated exceptions, right? So syscall itself is just this, on this is just this single instruction, right? That trips the trap that causes the rest of this interrupt handling mechanism to happen. Now the question is, how do I communicate with the kernel, right? Because remember, what I'm really trying to do is make a function call, right? But I need to tell the kernel what is it that I want, right? What am I requesting? And then normally I'm gonna need to provide some arguments or some other data associated with that request, right? So give me some examples. What are different things that applications might want their kernel to help them with? Give me an example of one, Jeff. I'm an application, I'm asked the kernel to do something, what's an example of something I might ask it to do? Access to memory, not usually memory. Lovely. Yeah, I wanna create a new process, I wanna fork, yeah. I wanna write something to disk, okay, fine. These are system calls, yeah, Jen. Yeah, yeah, send something over a network socket, right? What are examples of arguments to these calls, right? Jen, let's say I wanna open a file. What do I need to tell the kernel about it? Yeah, I need to give it a name, right? What about if I'm reading from the file, Tim? What else would I need to tell the kernel? I mean, say it's a read, but then what else? Okay, yeah, I need to tell it what file and then maybe like where in the file the read is supposed to come from and where it's supposed to go, right? So what I do here is that there are, for each system call on your kernel, there is a agreement, right? This is an interface. This is a contract between the kernel and applications. The kernel says if you make this type of system call and load these arguments in this predetermined places, then I will do, I will try to do what you've asked me to do, right? And you can, the nice thing is again, all this code is there so you guys can look and find the wrappers for the system calls that are provided by your kernel, right? So for example, for something like open, right? I have a string I need to pass in. That string doesn't fit in a register, so I need to pass the address of some memory where that string lives and then the kernel needs to copy that in, et cetera, et cetera. You guys will become intimately familiar with this when you do assignment two, right? But there are, but all I wanna point out is that there are well-defined agreements about where arguments are gonna be for system calls because there have to be because otherwise the kernel doesn't know where to find, right? Yeah. What is your name? Akshay. Akshay, right. So the kernel is approachable by all the applications, right? So any and every application can. Yep. Yep. And I cannot execute your job except for this. Oh, no, no, no. I mean, there are plenty of reasons, right? There are plenty of reasons. So someone came up after class on Wednesday and asked, maybe this was Monday, and asked a question about privilege escalation attacks, right? So how many people have heard about privilege escalation attacks? There's websites that you can go to that record, or people can provide examples of these. So what a privilege escalation attack is, and this gets confusing because we're not talking about kernel privilege on the CPU, we're talking about accessing root privilege on a machine, right? So a lot of times when someone wants a hack a machine, what they really wanna do is gain access to root power so they can read all the files, they can execute any program, et cetera, et cetera. They're not getting access to kernel privilege, right? So this is an important distinction. What they're trying to do is to just get access to root privilege on the machine, right? So yes, modern operating systems enforce a lot of different things about the semantics of system calls, right? So for example, if I try to open a file, it could fail because the file doesn't exist. It could fail because I don't have permission to open that file at all. It could fail because I don't have permission to write to that file, right? So yeah, there's a huge, I mean, just because I can ask the kernel to do something, doesn't mean that I can ask it to do anything, right? And the kernel will say no for all sorts of different reasons. Yeah, comment? All right. So yeah, we just did this, okay? Oh, no we didn't. Okay, sorry. Software exceptions, right? So okay, we're finally to the last little bit of hardware and software, the last little bit of the trap stuff. This is a good time. So a software exception indicates that there's something wrong with the code that's running on the CP, right? Something happened that shouldn't have happened, right? And I just gave away one of the answers, but could people try to get some examples of things that might happen? Yeah, Peppen? Yeah, okay, yeah. So an all pointer exception is actually a pretty good example of this. And the way that that manifests itself, we'll get back to this when we talk about memory. The way that that manifests itself is that when there are certain cases in which an application will try to access a certain memory instruction and the CPU will tell the operating system, I don't know where this memory is. Like, you haven't told me where this memory is and this requires a lot more context that we'll get to when we talk about memory management, but that's a good example. That will trigger an exception. Yeah, remove. Yeah, like various types of arithmetic overflow, right? I mean divide by zero is my favorite one. It just means like, what am I supposed to do? I'm the CPU, he tried to divide by zero, like I can't keep going, right? What's the, and undefined output, right? So I need to do something. And what the CPU will do is we'll say to the kernel, I need help, right? Like, this is what happened, this is what this process tried to do, and I don't know how to go on. Yeah, Jeremy. So that probably wouldn't trigger a software exception, right? Because that would probably be something that would happen in the kernel is the result of like a system call, right? So for example, if there are system calls that allow processes to ask for more heap, right? Which is where malloc memory goes. That system call can fail because the kernel is out of memory, right? But it wouldn't cause an exception, right? This is something that again, that software can do an unprivileged mode that basically just creates a condition that there's no other way to respond to other than ask for help. What's another example of this, right? I just gave a hint, right? I'm running an unprivileged mode, AJ. Yeah, that's similar to Bethany's example. That's something different. An infinite loop wouldn't create an exception immediately. Is it grr? Yeah, what's another example of a, I'm running an unprivileged mode, right? What's there something else that I could do that would cause a software exception? How, do you want to help him out? No? That's a good answer. I'm going to work the back of the room. Is it a grr? Overflow. This is much more basic stuff. Think about the CPU and Wembley. Yeah, I could try to do something that I need privilege to do, right? So I could try to write to a register on the CPU, for example, that I can't write to unless I'm running an unprivileged mode, right? This is another thing that would cause a software exception, right, Tom? Yeah. Yeah, I probably need a couple of slides on this now. So a lot of what, when we start talking about privilege, this gets very gooey, right? We're talking about privilege at a very, very, very low level, right? So installing stuff would probably require access to memory and other things that the kernel would need, but installing something itself probably wouldn't cause one of these type of software exceptions. Yeah, this is like very, very low level on the CPU itself, right? This is because, for example, the CPU doesn't know you're trying to install something, right? All it knows is that you ran this instruction and I don't know what to do now, right? Because I'm in unprivileged mode and he tried, you know, see, he, you know, I should switch back and forth, right? She, this process, tried to access this memory address that she wasn't supposed to and so I'm gonna kill. Should say it, I guess it sounds a little bit more mean, yeah. But again, so think about what does the CPU know about what I'm trying to do, right? The CPU doesn't know I'm trying to read a file. All the CPU knows is I tried to execute this instruction, right? So there's really only one more I had here, which was that this was Bethany's example, which is trying to use a memory address that the kernel has not told the CPU how to translate, right? And we're gonna get back to virtual memory in a couple weeks, right? Yeah, what? No, no, I mean, remember, the compiler outputs the instructions for your program, right? And you can do this. Like, you can go and you can do this in MIPS, you can do it and you can probably do it on an x86 machine as well, right? You know, right? You know, there's ways in C to include a little bit of inline assembly code, right? So do that. And find out things that you're not supposed to be able to do, try doing one, right? Your program will just be killed, right? You know, it'll just say, like, and we have tests in our testing suites to try this, right? They basically say, okay, let me try to write to the coprocessor register that controls whatever and it'll just die, right? Or it should if you do the right thing, right? What will happen on your system right now is that it will die and this is something you guys will have to fix for assignment too, right? Actually, right now, what will happen is your whole system will crash, right? Which is not what you want to happen. What you want to happen is just that process be killed. Yeah, do you have a follow-up? Do you know the fact that there are functions in C that allow you to... Yeah, I mean, again, when you're using C, you can, I mean, normal compilers will not output these privileged instructions, right? Because, you know, they're designed to compile user space programs. But that doesn't mean that you can't write a program that doesn't, right? You just have to write some assembly language. All right, so again, just to finish this up, you know, the difference between interrupts and exceptions. Interrupts are voluntary, right? Interrupts happen when an interrupt happens, sorry, software interrupts happen, the software generated them. So the software knows, right? The software knows that the kernel is about to run because it asks for help, right? It tried to open a file, okay? Exceptions are non-voluntary, right? So exceptions are cases where the kernel starts to run, the system will trap and the kernel will begin to run, but the software didn't necessarily expect it to happen, right? And sometimes, you know, I want to go back to the slide, not every software exception, and we'll talk about this when we get to virtual memory, will cause the process to be killed, right? Some of them are handled transparently by the kernel and this is used to do memory protection, right? But some of them will, right? And many of them will, right? But the difference is that, you know, the exceptions are kind of like the process is going along, it's only the kernel starts running, right, and it didn't expect that, right? And sometimes it doesn't even notice because it will just keep running after the kernel is finished. All right, any questions about this stuff? No, I don't think, no, exceptions are, exceptions will always cause the kernel to run, right? They have to, right? If they didn't, then again, a process could be like, oh, yeah, let's just try this, let me see if I can write to this register and see what happens, right? And then I won't tell the kernel about it and maybe it'll work and then maybe I'll get a chance to take control of the machine. No, no, no, I mean, exceptions are, again, exceptions are kind of cases where the CPU doesn't know how to continue, right? The CPU can't execute the next instruction until maybe never, right? But certainly not until the kernel helps it, right? So it's kind of like, again, this guy tried to do this thing, what should I do, right? Yeah, I don't know, I mean, I don't think for, again, software interrupts and software exceptions are synchronous, right? Like a system call will immediately cause control to transfer to the kernel, right? You'll immediately jump to the exception handlers. Same thing with software exceptions. Hardware interrupts, you could mask them and maybe at some point the disk would just give up and stop trying to get attention, but I don't think so. I mean, that wouldn't be that useful, right? Because it's still out there, like there's something that needs to happen, right? But that's a good question. Any other questions about this stuff? All right, so let me, let's see, I think we have, maybe we'll just finish a little bit early today, sort of good stopping point. Any other questions about this? We've had a few good ones. I think then we will just wrap up a little bit early today because this is kind of a nice cleavage point. And we will come back on Monday and talk about sort of historic view of CPU limitations and how some of these features and some of the scheduling algorithms and ideas about switching back and forth between processes emerged and all sorts of other fun things. So have a great weekend. Enjoy the Super Bowl if you watch it. It's funny, I know, like I'm right about at the same point I was last year because last year I had Tom Brady and Eli Manning jokes on this slide. Of course, if you see the videos, I was forced to suffer a class-long humiliation wearing a Giants jersey as a result of the outcome of the Super Bowl. At least I won't have to do that this year. So, see ya.