 All right, this is Jeff Chalon again. This is part two of assignment zero. This is the second screencast looking at how to get your environment set up and get to the point where you can build and run an OS 161 kernel. So okay, so at this point, we've finished initializing our development environment. So I have a vagrant virtual machine running here that I can use. I'm gonna get into that again and just verified that the tool chain is installed. Okay, we're all good. So the next thing, so now what we have is we have the tools that you need to build a kernel, but we don't have the kernel sources yet. So to do those, you need to clone our repository. This is not the view you would get if you were logged in. Let me sign out here, show you how it looks when I'm not signed in. All right, so here's the URL you're gonna use. This is publicly available. So anybody can clone this. And so now what I want to do is I want to clone this into that source directory that's been shared with the guest. I created this file last time. It's gonna get rid of it. And now I'm going to do a git clone and I'm gonna put that right here. That clones into my current directory and here I am. So this is nice. I'm in a, I've obtained the OS 161 sources. My working directory is clean. You'll see that the remote that I've established is set up to point to the GitLab. These are the public sources that are maintained by the ops-class.org staff. So one thing you'll do in a later step is actually set up Git so that you can use your own private repository to share changes with your partner. This repository you do not have permission to push to. However, you need to keep our repository around so that you can get changes that we might distribute in the future. So I'm not gonna set up my private repository yet. But what I will do is I'll rename origin to staff. And then I can run git remote-v, show me that I've renamed that to staff. So this will allow me to set up an origin repository later, an origin remote later that points to my private repository. So now I've got the sources. Now I'm in good shape. So just to point out, now I have two directories that I care about here in my virtual machine. I have a root directory which is already created for you. That root directory is currently empty. Maybe it's empty. Oh, look at that. We even put a sys162.conf file in there for you. It was so nice of us. Okay, so this root directory has my sys162.conf file in it and my source directory in the VM has my git repository just cloned. Okay, so let's get started here. So the first thing I need to do is configure, run the configuration script in the root of my OS 161 directory. So that's right here. You see that there's a configuration script and I'm going to run it. And the only thing that this, the only argument the script takes is you'll see there's this, there's a debug. This allows me to compile these little programs to debug info. There's no reason for that. You can read in the comment. The only thing I care about here is that this only really sets one useful option, which is where my OS tree goes. So you'll see that this is by default an OS 161 root in my home directory. That's not where I want it in the virtual machine. If you're developing on a machine and you've installed things in other places, you may want to put this somewhere else. But what we're going to put it is we're going to put it home root. And that's it. So all that did is create a def.make in my, in this directory. You'll see there it is. And that's finished. That's a very quick step. Okay, so let's keep going. And go ahead and actually configure a kernel. So to configure a kernel, the kernel has its own configuration script and a configuration directory. That's in here. You run the config script without any arguments. It'll basically tell you what to do. So you need to run the configuration script and give it a configuration file. So all the configuration files use the shared configuration in comp.kern. You're encouraged to look into this and see how it works. Essentially what this does is it tells the kernel what files should be included in your build. So this build includes a bunch of different files. You can look through this. It also allows you to set options and have those options ensure that certain files get included only when they're set. So you can see when the sync props option is set, which is something we use for assignment one, then there's a couple of extra files that are included in the kernel build. Those files are not included if that option is not set. All right, so you guys will become more comfortable with the syntax of this file later. For now, all we're trying to do is configure a kernel that has done VM enabled. So if I look around in this directory, I see that there are four configurations, done VM opt and generic and generic opt. So what I'm just going to do is configure a kernel with VM enabled, right? That's not that difficult. Now look at the output of this command. So it's normally a really useful thing to do. What did it do? It used configuration done VM, it generated some files, and then it set up a compile directory for me where I can compile the kernel with this configuration, okay? And that is in compile done VM. So if I go into compile done VM, you'll notice that this directory was created, didn't exist before, and that there's a bunch of stuff in here, right? Now, the last thing it says is remember to make dependent, and it really should be remember to be make dependent because that's the first step in building our kernel. So if you go back here, what I'm going to do, there are three steps here. The first step is to build the dependencies. The second step is to build the kernel, and the third step is to install the kernel. So to build the dependencies, I run this command, be make depend, that completed successfully. So now I'm going to actually build my kernel by running be make. And so before I do this, just let me show you what my root directory looks like right now. All it has is my sysfont61.conf file in it because I have an installed kernel in it. So now, when I install my kernel, it's going to my root directory, there's my kernel. So the way that the kernel is installed, it's a kernel dash, the configuration, and it sets up a sim link from kernel to that file. So when I run sysfont61.kernel, sysfont61.kernel, it's going to use the kernel that I just created. Okay. So now I have a kernel. I've created an operating system kernel that's based on the base OS161 sources that you were given. Now this kernel, there's a lot of things that don't work. There are some things that do work, but there's a lot of things that don't work that you guys will add in the future during the next assignment. So now your kernel, in order to run, your kernel does not run in your virtual. It does not control your virtual machine. That would be difficult to compile a kernel that was that complicated in an instructional class. So what we do is we provide a system simulator for you to use. It's called sysfont61. This is not something that you're expected to understand how it works or to modify the code, all the code is available, but this is how you run your kernel. So sysfont61, you can see here it gives you some usage information. It takes one mandatory argument, which is the kernel to run, the file run, anything. So you also want to note that any options that come before the kernel name are options to the simulator. Anything that comes afterwards are arguments that are passed to the kernel itself. Now the last thing is that sysfont61 requires a configuration file in the directory in which you run it. So if I move the sysfont61.conf file that we gave you away and run sysfont61, even if I run it and give it a kernel, it says it can open its configuration file because that file doesn't exist. So let's move that file back into here. Now what does sysfont61.conf file do? Again, there's a lot of comments in this file, like everything that David has distributed as part of sysfont61. There's a lot of information here about what's in here. But here are the parts that are uncommented at the end. And the real critical bits here is right here, this line. This is the line that you will change the most often and the line that has the most useful options. So what this does, so the sysfont61.conf file configures the virtual machine that your kernel runs. It configures this system simulator. So what this says is the system should use 512k of RAM and one CPU. And this is the default configuration that we provide in your vagrant virtual machine. The one that we provide online is actually different. I'll show you that one right now. So here's the sysfont61 configuration file that we provide that just downloaded into on my Mac. So I'm going to move that download into the virtual machine by moving into the share directory. And then I'll move that from source here. Oops. And then look at this, right? So this one is a little bit different. This actually configures a machine with 8 megabytes of RAM and one CPU. Okay. So let's go back into our root directory. Look around. Okay. So now we're very close to being all ready to go. So we have the sysfont61.conf file that the simulator will use and we have our kernel. So let's see what happens. Let's run sysfont61 kernel. All right. Check that out. So now you booted a kernel. What does it tell you when it boots? It tells you the base system version, which is 201. Sysfont61 tells you it's release code when this was compiled earlier, well, just a couple of weeks ago. A little copyright notice, prints off some things during boot. It tells me that there's 260k of physical memory available. You might wonder, well, what happened to the other half of it? I configured it with 512k. The other half is used by the kernel. So the kernel itself, the kernel code takes up some space and the kernel configures memory for certain things that it needs when it boots. But this is a pretty minimal memory configuration. It's about the smallest. It is the smallest, I think, that the system will run with. All right. So now we're at this menu. So this is a weird feature of your kernel. It's not like most kernels because it's an instructional kernel. It doesn't actually run user programs yet, but it does provide this menu that does other things. So that menu includes tests that you can run. Some of these things test the core parts of the system that should work. For example, the Kmalloc test. This tests your kernel allocator. This is the allocator that allocates small pieces of kernel memory. And this is something we provide for you. And it works. And there are a bunch of tests that you'll allow you to confirm it works. So you're really encouraged to poke around here and try things out, see what works, what doesn't. Some of these tests will work. Some of these tests will not because they test things that you still need to build. So in particular, these synchronization tests over here, SY1 through SY5, are things that will not work until you finish a assignment. All right. So let's shut down. And let's play around in a little bit here just for fun, since we've got something to work and we're pretty proud of ourselves. Let's configure a system with eight megabytes of memory and eight CPUs. And let's see what happens when we run it. Oh, cool. Okay. So check this out. Now I have a lot more memory available. And this is interesting. This output is kind of strange. So before when I ran sys161, you'll see it printed off a nice thing, CPU 0 MIPS 161. This is weird. It looks kind of like the output of a bunch of different attempts to print CPU 1, 2, 3, 4, 5, 6, 7. So CPU 0 prints and then brings the other CPUs online. And because your locks don't work yet, all this output is interviewed. When you get your locks to work in assignment 2, all those CPUs will print sequentially and nicely. But now they're all sort of intermichled. All right. So we're going to shut down. You can see as we shut down that all the CPUs power off in sequence and we're done. All right. So now we've run our first kernel. This is pretty exciting. And I would encourage you to look at and try to answer some of these questions. And so for example, one of the things that the kernel will print out is how many times it was compiled, which is kind of interesting and maybe something that you'll find depressing in later assignments as you repeatedly try to get things to work. All right. So I'll leave these exercises to you guys. The last thing I just want to comment on is the workflow here. So normally when you're making changes to the kernel, you don't need to recompile from scratch every time. So let me show you an example of this. Let's change our kernel so that it prints out something new. This is not going to be here when it boots. All right. So let's print off let's make it print something funny. So why don't we say president and well, we should mess with Harvard College, right? Let's put something new here. All right. So let's say it prints off my system version. Okay. So now we can use get to show us that we've changed a file. I'm not going to check this in because this is going to change that I want to keep. But let's compile a kernel that has our change in it. Okay. I go back into the compilation directory I used before. And now I can start over. I can run be make dependent. I can run be make clean and be make and be make install. But if I run be make, the nice thing is that make is smart enough to figure out what to do. So you'll see that it only recompile one file main.c and then it rebuilt a kernel for me. So now if I run be make install and go back into my root directory, rerun my kernel, you'll see that it says my system version zero. It also points out that I've compiled it twice. All right. So now if things go start to go wrong, if you feel like there are changes that you made to your kernel that aren't being reflected in the kernel it's running, some things to check, some common mistakes, did you run be make install? Is the be make install going where you think it should go? So if I go into my root directory, I can see, for example, that this kernel was compiled just a minute ago. So that's the kernel I just compiled. You can also check the size of the kernel to make sure that that's being updated. In certain cases, if you've changed some of the header files or other things, you may actually need to reconfigure the kernel and rerun be make depend. If you've changed files that, if you've added files to your system and need to include them in the kernel, you need to reconfigure and you need to change the configuration in your configuration directory. So you'd have to actually change, need to change, add some things down here in a way that obeys the configuration file syntax. But normally your iteration loop is going to be changed something, run be make install, run like kernel, see if something works, does, check in my changes, and then keep going. But in general, if things aren't working, you can sort of back up here, try rerun in the dependencies, try making the dependencies, try reconfiguring your kernel. This step you should almost never have to do unless you've totally replaced your entire source directory, which you should hopefully not have to do. All right, so last thing really quickly is to just talk about how to build the user tools. So these are not things that you need yet because your kernel cannot run user programs and won't be able to finish assignment two. When you start assignment two, you'll want to make these and install them so you can use them for testing for assignment zero and assignment one are not required. But right now you'll notice that in the root directory, all that's here is my kernel, this is 161.conf and a couple of disk images that were created when I booted the kernel for the first time. All right, so now let's run, let's build the user space tools. Now one thing I would encourage is that be make will allow you to run jobs in parallel, right? So if I give be make eight, the date, the dash j eight, it'll run eight parallel makes and that can speed things up quite a bit. So you may want to do that by default. I would encourage you guys to set up shell aliases that allow you to run these commands without having to retype be make install that sort of thing. I'm sure you guys can figure out how to do that and that's pretty helpful. All right, so this is installing all of the user space tools. This takes a minute. Now, again, this is not part of the normal kernel build process. This is something that you should only have to do when you make changes to the user space tools. You are encouraged to create your own tests in user land when you get to assignment two and assignment three and use those to test things that the existing testing suite does not. And when you do that, you don't have to, you know, go through this build process. But if you don't do that, you should only have to do it once. Okay, so now I ran be make be make install in the root of my source directory. And you'll see if I go back over here to root, things look very different, right? So that build process install binaries in bin, it installed stuff in test bin, it installed man pages, which you can, which may not be useful. So this is all, this is all quite different. So this is what's happened is the result of building the user space tools. My kernel did not change, right? But all the user space tools are now here and can be used by your kernel once you get to assignment two and start to get that subtool. All right, so that's the end of the second screencast. The next thing we'll move on to is talking a little bit about how to poke around in your source directory. And then how do you use get in GD