 All right. Hello. And welcome back to campus. So this might be your first. Is this your first time back in person in a very long time? Or no, we've had some other classes. Oh, okay. Two years and a half. All right. Well, welcome back to, I guess, back to almost normal after like two years. So to some of you that might be scary to some that might be amazing. No matter what it is, we'll work through it and try and make this semester actually good. So a little bit about me. Hello. I'm John. I prefer just John. You don't have to be super formal with me. My last name as you can see is a bit of a disaster. So no one can probably pronounce it. The easiest way is to pretend the Y and the O aren't there. So elf, like at Christmas time, sin. And then if you want to remember how to spell it, you just throw a yo right after the E. And then you can spell my last name. So hopefully you don't need to spell it. But if you do need to spell it, that's an easy way to remember. But easiest way is just to call me John, right? You can use whatever you're most comfortable with. If you want to say professor, that's fine. That's kind of weird. So I am just a brand new hire. So please be gentle with me. Don't scare me off. Hopefully that means I can change stuff, make things for the better, improve. You'll probably see if you went through lecture slides, there's already some new stuff. I've seen some of you already have found my stuff already somehow. I don't know if you're here, but if you are, congratulations. So yeah, I just started in July. So I'm kind of just back to campus with the rest of you. So a little bit about me. I've kind of always been interested in computers, right? Taking things apart, understanding how they work. Being an engineer, right? I'm sure I don't have to tell you guys that you're in third year. You're well aware of that. But yeah, so that's kind of how I'll try and break down this course, trying to give you understanding how things work, hopefully why they work. We can explore all the decisions and the fun trade-offs and all of that fun stuff. So a little bit of housekeeping. Ashfin Goel is your course coordinator, which means if there's any big structural things of the course, you go to him. Hopefully you won't need to go to him. Like you can just learn everything, but he's the one that is setting all the kind of evaluation stuff. So you'll find the overall course website at that URL, which is where you'll get the labs from and all that. I'll talk about the labs a bit later. They also have a piazza for discussion for everyone, but we're going to hopefully do something a little better than that. Because I've used piazza before. It's okay, but students don't super like it. So the course website for you, Lucky Bunch, is just this. You can use elfson.com if you don't want to log in to Corkus. I haven't used Corkus. Everyone has actually used Corkus. Do people like Corkus? It's fine. Okay, because the other places I was at, whatever online stuff they had, was terrible and they refused to use it. But if you don't want to log in to Corkus, that's the URL. I'll also try and upload stuff to Corkus, just so everything's there, although my course listings disappeared. So I don't know what's up with that. I'm sure I'll find someone to email. So a little bit about the lectures, right? We're back in person for the first time in a long time, which is nice. Well, or kind of back to a more normal campus. So at any time during the lectures, right, feel free to raise your hands. You can just interrupt me if you want as long as it's, you know, you're not like yelling and disgust at me. And if anything's unclear, right, even if you'd want to just like really look confused like that, you know, even that helps. And coming to class, right, it's kind of important for both you and me so I can see how you react. Even if you just sit there and look confused, that actually helps me. That means I kind of screwed up and I should probably teach something better or, you know, readjust my explanation or do all that. So hopefully you can come to course or come to class and make it, hopefully I'll do my best to make it kind of as interactive as possible, have little demos. We can play with code. We can break stuff. We can figure out why we broke it and kind of what's going on under the hood, right? So you kind of hopefully get out what you put in. Right, it's just more fun and also kind of keeps you honest, at least when I was an undergrad, right, from Crass Nation was a real thing. And forcing myself to even come to lectures just helped with that. But if you get sick, right, you don't feel like anything. I guess this is a 9am class. So if you don't feel like waking up or your commute is super long, then I'm going to live stream everything just on YouTube, just so if you don't feel comfortable going to class for whatever reason that day or, you know, hopefully you're tired, I applaud. Okay. So hopefully this is live right now. The camera angle is a bit terrible. So hopefully I can fix that so you're not like looking up at me. But that's kind of a later problem. So this should be streamed on YouTube. So should be fine, right? It'll have VODs. So you can use that before I use Twitch. But then there's like two platforms I had to upload videos on Twitch. So I mean, if you want, I can stream on Twitch too, but it doesn't seem to matter. It's probably easier if just everything's there and I don't even have to touch anything and the VODs are there. So that's a change. And yeah, the other fun thing. So discussions will be interactive on Discord. I used this before. People like it. Hopefully people like it here. Although this doesn't get any applause YouTube does. So anyways, okay. All right. One. All right. So I tried this before. I don't exactly know how I want to organize it with two sections. I don't know if you, you know, this section got up at 9 a.m. So clearly we have more grit than the other one maybe. So I'll do that there and just be on Discord. Plus I find it helps students kind of organize themselves. Have like a nice little community for the course. Sometimes, you know, you can answer questions immediately. It's better than I find it's better than Piazza where you just kind of throw things in and then maybe someone answers your question like an hour later. Discord, you pretty much get your answers immediately. So I'll also set office hours. They'll mostly be by appointment. I'm generally pretty flexible, but also it'll kind of be offset by me being on Discord all the time. Probably in actually answering your questions. But I'll set office hours. I'll probably put on a little pull on Discord or something because trying to pull the class and figuring it out what best time works for everyone is pretty much impossible since everyone's schedules are kind of, you know, it's an engineering schedule. So it's kind of a disaster. But of course, right. A, office hours or anything will be streamed or recorded, unfortunately. Right. It's a resource just for you guys to ask me because otherwise everything is just kind of freely available so you get some benefit. So instead of a midterm, there's going to be three quizzes. The quizzes are online. The first one is September 29th. They seem to all be at 8 p.m. So yep. I would assume so. There's partial marks. I think it'll be kind of open. Yeah, we'll see that when we get there. We'll have practice to go ahead and make sure you're prepared for that because the first one's at kind of the end of the month, which is probably going to come up sooner than we think. And then there's also going to be six labs. So totaling 30%. The first one, I guess, is released tomorrow. You have two weeks for all the labs. You should not need two weeks for the first one. Yeah. You have an old version. Yeah. So if I fix these, so if in your slides, right, there's all my slides are versions. So if you go to the front and it's not 1.0.4, you have an old version. So you probably have an old version. So everything's right. We'll follow some good software engineering practices. So even the slides are versions. So you can go ahead, check the website, see what the newest one is. So yeah, these are the breakdown of all the labs. Some build on the other ones. So the lab three builds on lab two, lab five builds on lab four. I guess just as a curiosity, has everyone even used threads before? Few? Like 20% of the class? Okay. So I guess these headings mean nothing to you now. But you will learn what they are and kind of how to do them. And yeah, there's going to be a web server lab and lab five builds on lab four. And then of course, there's a 40% final, which is, you know, we don't have a date for that yet, but the university will give us one. So I have to say something about academic honesty. I think it's in my contract. So you can so you can study together, right? You can work together. You but you can't do your labs and quizzes together. They're fairly big and calm. Well, they're fairly big and have lots of freedom in these labs. So it's like super obvious if you cheat off each other, trying to be smart and rename and variable names isn't very good, right? I had friends that tried that. It's like, it's probably one of the lamest things you can do kind of hurts everyone involved, right? Because you'll be assuming you're in computer, you'll be writing software. Eventually this course is kind of one of those big foundational courses that if you write any software, even if you don't care about the operating system, right, your application, whatever you write is going to use it and actually understanding the operating system and what's going on with that is the only way you can actually optimize your application. So if you write any software, knowing this stuff is all good because otherwise, right, you won't have a single clue on how to optimize it. You always have to go for the layer below and any software you write, the operating system is the layer below. So of course it won't be tolerated, blah, blah, blah. I think the University of Toronto has like public discipline hearings which are kind of fun to read. So you can see how long people get suspended for and like their degree taken away and stuff. So if you want some fun reading, you can do that. I had some fun doing that. So they seem to take it really seriously, so probably don't do that. So there's a few textbooks, right? They only complement the lectures. You don't have to go out and buy them. Everything should be covered in the lectures. All the examples and stuff, right, will be doing, right? You'll probably learn a bunch of stuff just by being on the discord. But these are the textbooks anyways if you want some additional material, right? There's modern operating systems, which I built, which you would have to buy. There's operating systems 3D pieces which has PDFs free on their website and all these are hyperlinks if you get the slides. And if you're kind of rusty on C, there's of course the C programming language book because everything we'll be doing is in C. But again, right? I'm new. Please provide feedback. So I want you to get the most out of the course. I don't want to just like sit up here and just talk into the void. That's really boring for me. That's really boring for you. No one wants that. So hopefully we can take advantage and write. I'm new here, so I don't know any better if you want me to switch anything or have any suggestions, right? You don't have to wait for coursey vows or anything like that. You can just come talk to me, right? I'm on a reduced teaching load now, so I even have more time. So if you just want to come to my office and chat, that's fine too. Eventually, I'll eventually I'll even have an espresso machine if you want free coffee, but I have to wait for my move to happen. So not yet, but coming soon. And yeah, so hopefully we can make this course really good because I find all this content really, really interesting and hopefully you do too. So let's go on to this quote I like that pretty much sums up the course and computer science in general. So all problems in computer science can be solved by another level of indirection. And that is what an operating system is at in the finest or the most grain terms you can think of, right? Operating systems are just another level of indirection. So they sit between applications and the hardware. So your application instead of, you know, dealing with the hardware directly would go ahead and instead, you know, go through a lay of indirection, talk to the operating system and the operating system talks to the hardware. That way you don't have to write your application from scratch every time, you know, Nvidia releases a new class of video card each time there's a new CPU, so on and so forth, right? You just let the operating system deal with it. Only they interact with the hardware. You don't have to care about it. And then your application runs on all sorts of hardware, right? Kind of at the very core idea of it. So and its role is just to manage and coordinate the resources, right? So and then I guess, yeah, what is an operating system, right? Could be Windows, Mac, Linux, everyone probably has their own one they use. And then that's pretty clear that they're all very different. But when you get into like Ubuntu versus Android, they're considered different operating systems or most people would consider them different operating systems, right? But under the hood, they both use the Linux kernel, which we're going to kind of explore in this class, which is kind of one of the big foundational pieces of the operating system. But both Android and Ubuntu run very different applications. And that's kind of why people consider them different operating systems, right? Sometimes the line isn't super clear. Like for desktop applications, right? If you have just like a little console application you want to run, you could run it on your phone or your computer and it would behave pretty much exactly the same. Although you probably wouldn't, you know, open up a terminal in your phone, maybe some of you have, but most people don't do that. They use GUI applications. So you'd consider them different operating systems. So the different stairs, they're kind of display manager and their APIs they use, right? Linux uses Wayland or, you know, older Linux uses X11 and Android uses something called Surface Flanger to actually, you know, show the window on the screen. It gets even more confusing when you go kind of in the Apple world, because really what's the difference between iOS and iPadOS? Are they considered different operating systems? Not really, but they like to market them as different operating systems, but it's just kind of how big the screen is. Otherwise, they're pretty much exactly the same. So the line kind of gets even more blurry when you get into the marketing speak. But the core, no matter what operating system it is, they just allow you to run more than one application. That's kind of their primary job, right? Without operating system. What happens when you press power on on your machine is your CPU just goes and starts executing code blindly at a fixed address, which if you're doing embedded work or just have a single application, maybe you can put your application at that fixed address. So when you turn on your computer, it just runs that application. So that's okay for an embedded system. But for, you know, your computer, that's probably not a great thing. So and also, it kind of has the problem we discussed before, where if the hardware changes, right, you would have to rewrite your application and no one wants to do that, right? If you've embedded thing that you just kind of write your application once for, you know the hardware, you kind of ship away and you never see it again, that's fine. But for anything more complex than that, you probably need a operating system. So instead of just, you know, that fixed address when you boot instead of just, you know, executing an application, you go ahead and execute an operating system. We might go into the boot process later, it's a bit more complicated than that. That's like a gross oversimplification. But at the core of it, that's what happens. So the first abstraction in this course is a process. So you can kind of think of it like a virtual CPU, right? Each process contains a set of registers, including a program counter, which you've seen, and, you know, you've done some assembly before, you kind of understand how that all works. So your operating system keeps track on a per application level, its own set of registers, including a program counter. So that's how you can, you know, switch between, you know, some office program and your web browser, for example. So when you start a process, the process itself, like the executable file, will go ahead and tell the operating system where to start executing code, because your executable is one part of it, it's just a bunch of program code. So part of the file format that we'll kind of see just tells it where to start executing. So we already can kind of figure out some tasks an operating system needs to do, and that we'll be learning about. So it needs to keep track, you know, keep track of a set of registers for each process. Again, that could be like your web browser versus your office program versus Discord versus whatever, right? And then you also have to switch between different processes, right? Even if you have only one CPU in your system, which no systems like that really exist today. But even if you only had one CPU, you have to kind of manage your time, when do you actually execute one versus when you execute the other. If you have a multi CPU system, right, which application runs on which core? Should I move them? How many cores does it run on? Right, it gets kind of more complicated. And then yeah, you have to decide when to switch. So do I let the web browser to sit there executing endlessly for, you know, forever? Or do I switch interrupt it and kind of let something else execute? So these are all problems we will have to solve in this course. Yep. This slide? Yeah. Yeah. But so this slide is actually a view of memory. But yeah. So yeah, so you know, even on one CPU, your operating system will kind of fool you that multiple things are running at the same time. So go ahead, execute Firefox for, you know, like one millisecond, then switch, execute Discord for one millisecond, and then each makes progress before you can actually perceive it. And it looks like multiple things are running at the same time. So that's kind of how an operating system at a very high level deals with managing the CPU. And then the next thing is memory. So if you write if you have a single application on a single board, you can use all the memory, it doesn't matter, you don't have to manage anything. When you have multiple applications using memory, it becomes a bit more difficult. One like super naive solution is just, you know, if I have eight gigs of RAM, I can just, you know, divide it up. So I'll give Firefox, you know, four gigs, I'll give LibreOffice two in the operating system to, although right, many of us probably open many, many tabs. So four gigs of RAM probably isn't good enough. So but this is one thing you could do. But the huge disadvantage of this is as soon as you set it, right, you can't change it anymore. So Firefox wants to use if you don't even have LibreOffice open, and Firefox wants to use six gigs of RAM, if you kind of have this fixed view of memory, you can't change anything. And then if you want to use another application, right, you'd have to section off another piece of RAM, make Firefox smaller, change LibreOffice, do something, it's just super, super inflexible and not a good solution. So we reach to virtualization. So what that does is it fools something into thinking it has all the resources. So we play a trick on, you know, LibreOffice, we tell it, it has the entire range of memory, so it can access any byte it wants to, and then the operating system has to deal with managing that. And then, you know, Firefox would have its own view of memory, right? So it would think it has all the memory, and it can use every byte, and then the operating system has to deal with that. But the nice thing about this is, you know, that start address for both Firefox and LibreOffice can actually be the same address, right? They can both think that's address 1000, for example, and access it and then the operating system will actually manage everything under the hood. So what does the operating system have to do if, you know, there's virtual memory and each one thinks it has its own unique addresses and they, you know, shouldn't be able to read each other's memory and they should be separated and all that. Well, if you're the operating system, you have to map a virtual memory address to a physical memory address. So, you know, if Firefox thinks it's, you know, using address 1000 on your physical RAM, right, you can't change, you can't grow it, you can't do anything, your operating system probably would, you know, map address 1000 to address 2000 on physical RAM, which, right, it's physical, so you can't actually overlap that. And then for LibreOffice, right, its address 1000 could map to address, I don't know, 3000 or 4000, right, just a different address and then your operating system is going to have to manage that, right. How many addresses is it using? How much RAM is it using? How much, you know, am I running out of physical memory? And then I have to, you know, do something about it. And then that's an error, right, if you run out of physical memory, one of the things you can do, if you're the Linux kernel, there's a special process that runs called the out of memory killer. And the easiest way to free up memory is just to pick an application and destroy it. And then boom, you have memory back, right. So that's one solution you can do if you want, if you actually run out of memory. So this concept of virtualization is really powerful. People have been building on it and using it for more and more things, right. So it applies both the kind of processes and virtual memory, right. Processes kind of act as a virtual CPU. Each one thinks it has the whole CPU when really it might not be executing at any point in time. And the operating system gets to decide that. But you can also extend that to the entire machine. So you can have a virtual machine, right. So you have a single physical machine that can run multiple operating systems at once. Like, for example, right, this machine right here is a running Mac OS. But, you know, throughout the lectures, I'll be showing everything on Linux, right. So here's a virtual machine. So this is actually Linux running on top of on top of Mac OS in a virtual machine. And another thing we have to do is handle concurrency, which is really, really fun once we start introducing threads and multiple things happening at once, right. In terms of like the high level of looking at applications, right. We want multiple applications running at once, right. You don't want to just be able to use a web browser and that's it. That would be pretty lame. And you also want your applications to do multiple things at once, right. If, you know, if you're running a web browser, right, you want multiple tabs open, you want maybe to play a game in one tab and, you know, do something else in another, right. You don't want your applications isolated either. You want them to be able to communicate and talk to each other and actually show you things on a screen, right. Your web browser, you want to see what web page you went to. Discord, you want to see, you know, whatever text is coming in, game, right. You want to actually see the game, probably hear it. And then to do that, right, you want, you want applications and libraries to communicate and kind of all work together and the offering system has to facilitate any communication between them. So yeah, as I was saying, right, completely isolated applications aren't useful if your application is completely isolated and can't talk to anything else, it will essentially just make your laptop or desktop hotter and not actually do anything, right. Even the simplest program that just prints hello world does some communication, right. It's printing, you know, it's sending hello world to the screen and you expect to see it. So there's something going on there that will kind of dispel in this course. But again, some more tasks for us to learn, right. If you're the offering system, you have to allow multiple applications or executions to run at once safely, right. So you don't want them to contend with each other. You don't want one application being able to affect another one. So if you had, you know, one misbehaving program on your machine, right, that maybe you wrote, you don't want to be able to destroy every other application running, right. Every time we write a buggy program and execute it, do you want your web browser to die? Probably not. Then another task for the operating systems to manage different kinds of communication. So they're called inter-process communication. So talking between processes can be anything from, you know, networking to, you know, just sending data back and forth, writing to a file, anything like that. And then, of course, when you want to share something, you have to have some permissions and security, right. You want to make sure that whatever applications are communicating together, it can't be intercepted by another one. And then the last piece of the puzzle is persistence. So for our basic operating system, we need some type of persistence, right. You want to be able to access data between boots. If when you turn off your computer and then turn it back on again, everything you've done is deleted and doesn't exist anymore, that's not very good. So you want to be able to persist data across boots and what does that is the file system and it specifies how to kind of organize, organize data on your storage medium, whatever it is, like a spinning rust, like those big hard drives that probably no one's really seen before or NVMe drives or SSDs or anything like that. It's just a bunch of bytes and you have to lay out things in a specific way to represent files and folders and everything like that and we'll see that towards the end of the course. But again if we're kind of, you know, listing everything an operating system needs to do, it also has to be able to store and retrieve data and kind of ensure that integrity of the data. So if you write, I don't know, solutions to your homework, to the disk, you don't want it to, you know, when you read it back later you don't want it to be different than when you actually saved it the first time. Because hard drives, you know, that hardware actually fails all the time but the operating system, you know, does a very good job of maintaining it, moving stuff around under the hood without you noticing so that your files stay your files, they don't get modified and nothing bad happens to them. So one of the kind of big abstractions is file descriptors, so they abstract both communication and persistence. So a file descriptors kind of, have people used file descriptors before? Not really. One person, alright. So has anyone written to a file before? Okay, so if you've written to a file and you've actually executed it on Linux or something like that or macOS, you've used file descriptors but there is a layer of abstraction that completely hit it from you. So we'll be learning about file descriptors in this class but basically all they are is just a number and then each process has, you know, a set of numbers that represent file descriptors that are just numbers that you can read bytes to and write bytes from. So it's like read some bytes from file descriptor zero, write some bytes to file descriptor one and then because it's abstracted like that those file descriptors can actually represent anything. It could be, you could actually be writing those bytes to a file. You could be writing them to a network. You could be doing all, writing them to whatever and the offering system is going to manage that. So yeah. So and that's kind of one of the big abstractions that you won't be able to get away from. And then if you're looking at the kernel stuff, right? The core part of the offering system that actually interacts with the hardware. Unsurprisingly, most of that code, right? If you open up Linux on GitHub or something like that, you'll find that most of the code doesn't actually do what we described before all that management and stuff. It's actually just device drivers. So it's stuff that talks directly to the hardware. So they're responsible for implementing the abstractions onto physical hardware. It's really, really boring. It involves just reading manufacturer specifications and then finding out that they're wrong and then trying to work around them, right? There's generally lots of inconsistencies between the documentation and reality. So this is like an actual comment from the Linux source tree. So there were two versions of a BIOS, which is kind of the first piece of software that executes when you turn on your computer. So the offering system, you know, has to kind of initialize it and deal with it. So there's two models of a Dell laptop here that were released pretty close together. One's bad and one's good. So the joke here is that this is the technique they use to write BIOS code instead of understanding what it should do, right? They just wrote some code, checked if it compiled. If it did compile, they wrote some more code. As soon as it compiled, they checked if it booted Windows 98, which is how old this it was. Then if it didn't, they'd go back, write some more code. And then as soon as it booted Windows 98, they'd ship it. And then so whatever bugs they had, right? No one writes perfect software, especially if you're doing a technique like this, where you just kind of hacking at it until it eventually works and then shipping it and then never seeing it again, right? Probably has a bunch of bugs. And then if you're writing the code that has to interact with someone that wrote software like that, you're going to have a bad time because you're going to have to work around it. So luckily in this course, we'll stay away from device drivers and all that. But if you really like kernel development, I'm just giving you a little bit of fair warning ahead of time that sometimes it can be very, very frustrating. All right. And to kind of motivate the rest of the class and to see how simple things actually are. Yep. Oh, you're good. Okay. So everyone can kind of read Hex, right? Okay. All right. So everyone can read Hex. So I'll dispel the magic of computers. So everything in computers is just a number. No matter what it is, it's just a number. And it's how you interpret it. So here are some raw bytes. So each number here right between the spaces is just one byte. And there are 168 of them here. And this is actually a program. So who is a who can tell me what this program does print and why does it print hello world? It says so at top. That's a very good answer. So right, which this seems kind of weird that it prints hello world. Because if we actually, you know, wrote a hello world and compiled it, right, even our text file would probably be bigger than this, right? Depending on how much white space you use. And then when you compile it, right, it's going to be like, it's going to be like three kilobytes or something like that, which is, you know, several thousand bytes, which is a lot more than 128. So we'll also kind of be dispelling all the fun magic that goes on with, you know, your compilers and other libraries and stuff. But to show you, I'm not lying because, you know, maybe I could be lying. Let's go ahead and see. So I have two main files. All right. So I have this file called 128 byte executable. This is just running Linux just on, you know, this. So it's running ARM, which you might have some assembly experience with. But you can see here, this column says what size it is. It is indeed a hundred and sixty eight bytes. And if I, you know, do a hex dump of it, we'll get some insight into it. But I can see that the bytes are the same that were on the slide. So if we go ahead, we see all the bytes. And, you know, if it's within an ASCII range, right, so everything's just a number. All your strings are just numbers. And then you interpret them as characters. So if you go ahead and look at the kind of right side here, you can see the contents of the file when you convert it to characters. So if it can't represent it, it just puts a period. So you can see the first three letters here are elf. That could be related to my last name. It could be not. You have no idea. But it's kind of weird that that's there. And then it looks like a bunch of gibberish. And then at the end, it kind of says hello world. So there's at least hello world somewhere in it. And if we go ahead and execute it, right, we actually get hello world, which is, you know, way, way smaller than if we wrote it and see. So that's one thing we have to look forward to. Because next time we'll go ahead, we'll explain every byte of this because, you know, part of the goal of the operating system, it has to take all those bytes, do something with them, execute them, right, that's kind of the smallest example of a program. And, you know, no one showed you that before, even though it's actually really, really simple, right, even if each byte does something crazy, it's only 168 of them. So it's not actually that complicated. We can kind of tell or raise these bytes what they do. And most of them zero. So it's probably actually not doing anything important. So, you know, just in summary, we get to end a bit early. There's three major concepts in this course, right, you'll learn how the following applies to offering systems, virtualization, concurrency and persistence. And with that, just remember, I'm pulling for you, we're all in this together.