 Alrighty, why don't we get started? What we're gonna be talking about in today's recitation is a wrap up of assignment 3.1, looking ahead to the beginnings of assignment 3.2. And next week's recitation, we're gonna be going a lot more into the details and the mechanics of 3.2. I know we've already hammered this before, but it goes without saying assignment 3.1 is relatively a lot easier compared to what is coming up in 3.2 and 3.3. So the sooner that you can have that wrapped up and move along, so much the better on that. So in terms of what's coming up, obviously, assignment 3.1 is due in the end of this week on this. If you have any lingering questions, definitely speak to the office staff on that. For the rest of the course, definitely get your design documents in to have one of the TAs look at it before you start coding. What we don't want you to do is pick a wrong or unworkable design and then go down a rabbit hole that you have to back out of. So there are certain known problems with approaching these issues. And so again, the sooner that you can have a staffer look over to make sure that you and your partner are going in the right path, so much the better on that too. So the last part of the assignment, 3.3, is probably the toughest part of the entire course. So once again, the sooner you can get started on this, so much the better on that. So aside from that, let's talk about what's going on with 3.1. What do we have so far? And then I'll pause for questions and then dive into 3.2 on this. And again, the next two slides is a review of what we talked about before spring break on this. But what you need to do for assignment 3.1 is a few things, obviously reconfigure for assignment three. Presumably you people have already done that and have dealt with the fact that your kernel no longer boots on this. You're implementing a core map, which is essentially the data structure of physical pages on this. And you're writing a few access routines on this. In other words, kernel get me a page of physical memory and if you will reclaim a page of physical memory on that. The goal is to pass test KM1 through KM5 on this. Again, these are tests that you run directly from the kernel menu on this. We talked a little bit about some problems with the core map. One of the biggest problems is getting the bugger set up on this. Part of the problem is that it occurs so early on that we need to kind of approach it specially on this. Well, what is the core map? Again, it's a data structure that essentially contains the state of physical memory of your OS161 system on this. So we talked a few things about this. Obviously it's going to be accessed a lot. We know in terms of when we need to set it up, we need to set it up very early on this. We also know that we have a bit of a chicken and egg problem. The core map is used by KMALIC to get memory that KMALIC gives out. So unfortunately we can't declare the core map by calling KMALIC because we'd have a circular dependency on this. So as a result, we're going to have to set it up manually. We do need to have it available in terms of global or static scoping on this, but since we don't know the size of the physical memory on boot up, we can't simply declare a statically declared array and not the compiler take care of everything. We're going to have to, if you will, set up the array or indirect array manually on this. And we talked a little bit about, again, look at ram.c that has a lot of nice nuggets of information that you presumably are already using to set up and use your core map on this. Aside from that, next issue on this, in terms of initialization, it has to be done very early. And oh yes, you also need to be aware that start off simple and then you're going to have to add additional fields to the core map as you go along. Also obviously the core map is a shared data structure, so you're going to have to handle some synchronization issues with this. In terms of its representation, roughly speaking, again we've got all a physical memory that you can determine from the fields in ram.c and the kernel and initial boot stuff is already given to you by the assembly code at the bottom of physical memory. And what you're going to need to do before you essentially get anything else done with the boot process is you need to tuck the core map in right above the kernel but below the rest of what is available for free memory on this. So that's kind of where the core map goes in terms of all memory, but again the core map itself is a data structure that contains a whole bunch of fields and what do these fields map? Well they map all of memory. So again the core map is in memory but it in turn maps all of memory which is kind of where some of this chicken and egg problem comes in. Questions so far about assignment 3.1? Again just kind of a recap of what went on just before spring break on this. Pretty straightforward, pretty not straightforward. All right, back to the next two slides just in terms of what are some of the function interfaces that you're going to have to deal with in the rest of the semester on this. Well some of these actually you're dealing with right now in terms of if you will allocate pages, free K pages that's assignment 3.1. And other things, VM bootstrap, we talked about how that was problematic. It used to be a way of approaching assignment 3.1, it does not work with the present test on this. You are going to need VM bootstrap or if you don't use that you're going to have to kind of create your own place for setting up the rest of your virtual memory manager for assignments 3.2 and 3.3. So this is going to be useful for the last part of the course here. TLB shoot down, kind of forget this for now but VM fault we're going to be talking a fair amount about that later on to today's class. Remember assignment 3.1 deals with stuff that can be addressed through kernel direct map addressing. I know there I had put a post on the forum about this but essentially up until now you don't really have to deal with or didn't have to deal with handling TLB fault, handling the code in VM fault that stuff. Well from now on you are going to need to be aware of that. The next two slides if you will contain the stuff in adderspace.h. These are a bunch of routines that are used by the process address spaces on this. They're pretty self-explanatory. We talked about this before. Create, destroy, copy, activate and deactivate that has to do with the TLB entries on this. Remember that the TLB entries are a mapping of virtual to physical addresses for a particular process. So as a result, when you contact switch from one process to another, you're going to need to take care of switching the entries in the TLB from one process to the other on this. Because remember the TLB is something in hardware and if you don't do that, it's simply going to blithely go along and continue to use the old entries for the previous process, which will create a fine mess. And the last part of these entries defined stack region we're going to be going through these. This deals with how your address space structures get set up. And this is definitely something you're going to need to dig into with your partner in the next couple of weeks or so. The last part of this is memory management S-break syscall. And again, this is roughly speaking how you're going to be managing the heap. This should be the last part of assignment 3.2 that you get to. It is the last syscall that you'll need to implement for this course on this. Questions I can answer about the function interfaces on this. Again, we're talking about the wrap up of virtual memory manager fault or yes? Essentially, yes. Except for TLB shoot down, that's one thing that you will not need until you get to a sign up 3.3. But again, allocate pages, pre-k pages. You've already done those, but yeah, let's see here. VM fault, bootstrap, all of this, and all of that with the exception that a couple of these functions you probably are not going to need at all for some reasons we'll get to. But yes, essentially everything on these slides, you're going to be needing to write a bunch of functions. That's kind of the nut of assignment 3.2. Other questions? All righty. Talk a little bit about the MIPS MMU in terms of how the hardware works or in this case the emulated hardware by sys161. And roughly speaking, by the way, most of this stuff you can look up yourself, it's in the Arc MIPS, I'm sorry, Arc MIPS include, if you will, TLB.h and there's some other files that are relevant to this. But roughly speaking, there are four, if you will, ways or approaches to addressing memory in the hardware. And what you need to do is look at the first digit of a virtual address. Again, when the MIPS chip is addressing memory, it's by definition addressing a virtual address. And what happens or how that virtual address gets translated to a physical address is determined by, if you will, the first hex digit on this. And first way of doing that is if the first hex digit begins with a zero through seven, it is in what we like to call the user segment here. And what happens is it goes to the TLB. In other words, the first thing that happens is, let's say, the CPU references address 40 million. Well, 40 million, the first digit is a four, it's between zero and seven. So it looks for an entry mapping in the TLB corresponding to 40 million on that. And it uses that mapping to kind of grab some location in physical memory on this. So that's one way of doing it, and this is the only way that user programs can access memory on this. This is something that you're going to be spending a lot of time with in assignment 3.2 and 3.3, i.e. for the rest of the semester. The other way of addressing memory you've already been dealing with, and this is kernel direct mapped. In other words, if the virtual address begins with an eight or a nine, essentially it does not go through the TLB. It's still a type of virtual address on this, but what's going on is if we reference, let's say, location 80 million, well, all the, if you will, the processor does is it just lops off 80 million and it winds up with a physical address of zero. By the way, people, I'm going to be noting this in a later slide on this, but this can tell you that, let's say, that we reference address 40 million, and let's say that 40 million maps to physical location 1,000. Well, you know what? Physical location 1,000 can also be accessed by referring to virtual address 1,000 plus 80 million. In other words, it's perfectly okay and sometimes you need to refer to a physical address through multiple different virtual addresses. Make sense? In other words, I can refer to a given physical address via multiple virtual addresses. I can always refer to it through kernel direct map addressing as long as I'm in kernel mode, but I can also refer to it through one and sometimes multiple entries in the TLB, depending upon if I'm in the kernel mode or user mode, either way on this. This is perfectly fine and sometimes you need to do that. Make sense on this so far? These are essentially the two ways of addressing memory that you need to be concerned about in this course. The next two, it's more informative on this if the first digit begins with, if you will, an A or a B. That is the next type of kernel direct mapping and it essentially shadows the previous way. In other words, location 80 million also maps to location a million. It's the same physical address. The only difference is that it does not go through memory caching and this is used for accessing memory mapped IO on this. So in other words, if we're reading the keyboard, we would go through this. This is something that you kind of need to keep in the back of your brains, but you really don't directly encounter it much in terms of your coding projects. The last type is, well, we have this great way of mapping and munging around memory that the users can use. Why can't the kernel use it? Well, yes, the kernel can use it. In other words, there is a way for the kernel to use, TLB mapping, kernel virtual memory, if you will. So we can have a way like production code like the Linux operating system has a function called Vmalloc. There's a Kmalloc in Linux, but there's also a Vmalloc and that stands for virtual malloc. In other words, give me, let's say, a batch of 10 virtual pages that are consecutive, but you know what? They don't need to be consecutive in physical memory. I know there was the question in lecture yesterday about that, so in other words, why is it or does it necessarily need to be the case that 10 virtual pages that are gotten with allocate pages, do they have to correspond to 10, if you will, contiguous physical pages on this? Well, if you get it through alloc K pages and Kmalloc, yes, that does need to be the case because we're using direct mapping. If we implemented Vmalloc, which is not part of your assignment, then you would be able to go through this Kseg 2 thingamabob, which also goes through the TLB. So again, it's something for you to know about. This is certainly something that would be fair game for a final exam question, but again, this is not part of your coding assignment. So the last two is something that you need to be aware about. It's the first two that you need to be aware and also are you're gonna be dealing with for your coding projects. Questions about ways of mapping memory? This is kind of just a summary of the same thing here. Direct mapping can only be used in kernel mode, user seg, yada yada goes through the TLB on this. And again, PIATR can be referred to multiple ways on this. This is just kind of a summary of what I was just feeling about in the last few minutes. Going once, going twice. All righty, moving right along. Let's talk about assignment 3.2. And as with everything in this course, start off with the old data structures on this. It's kind of the heart of where to begin. This is where you want to kind of do a lot of thinking on this. All right, what do your data structures for assignment 3.2 need to contain? Well, at a minimum. And by the way, we see data structures, there are several layers to this. You probably have already noticed there is a struct adder space. Now you can code your own, but I would obviously strongly suggest use kind of the templates that are already there. The struct adder space is, if you will, the uber bin for where you're gonna be cramming a lot of references on this. And it's gonna have to have, among other things, segment or region information on this. In other words, what you need to be able to deal with is, well, how many regions do we have? Like we have a stack, we've got a heap and whatnot. You're gonna have to have places to contain that information on this. You're going to need to expand the limits of dumb VM on this. So remember, dumb VM is a way of how not to approach this stuff. You're going to need to, in other words, kind of unhard code or at least expand the number of segments that your memory manager supports on this. You're gonna need to keep track of the start and size of each segment. That much is something that kind of is a holdover from dumb VM, because the segment is, if you will, simply a tracking of the base and bound of what is potentially a valid address on this. That's not the same thing as the base and bound of actually allocated memory. So this is the distinction between a memory segment and actual allocated underlying memory on this. Everyone clear on this distinction. So one of the cludges that dumb VM does is it kind of puts the two together on this. If you have a base and a bound, well, that's what is valid and it's also what is actually allocated on that. As opposed to a good memory manager which you need to pass the test, well, you need to keep track of what is possibly a good memory reference, but we're actually not gonna allocate the memory until we actually need it on this. So this is what we mean by segment information and then the page table structure that contains information about pages, that is virtual pages, that have already been allocated on this. So your address space needs to contain information about segments and it also needs to contain a page table structure which in turn contains information about page table entries. Your core map, remember, is a data structure that contains information about physical memory. Your page table is information about virtual memory on this. So remember, in a 32-bit system, there are two to the 32 possible memory references. We first need to determine whether or not a memory reference is valid. We can do that by checking the segments, but then even if it's valid, we need to know, tell me a little bit more about that. I have a virtual address. Well, what's the virtual page that it corresponds to? Well, I need to look at my page table structure. That's typically going to be, and this is kind of what you're probably most interested in today, the mechanics of the implementation, either a linked list or a multi-level array on this. So there are pros and cons with both on that and there's a bunch of slides and information out there in preceding years. And again, picture poison. There's pros and cons both theoretically and in terms of real implementation for this course itself. One small caveat that a two-level array, it will work fine for assignment 3.2. When you move on, or if you move on to assignment 3.3, you're probably going to need to up that to a four-level array if you go in that direction. That is a function of the fact that the data structures themselves take up significant areas of memory on this. So there's still very significant advantages of that to a list. There's also some disadvantages. Again, it's one of these trade-offs on this. So think about it either way. I know I myself personally did the multi-level array way back when it was easier for me to think about conceptually on this, and I was frankly scared of lists. Other people feel the exact opposite on this. Sometimes it's a toss up and flip a coin on this. But the upshot is that the page table structure, again, this is your data structure that you need to hold your page table entries, and this is essentially a way, if I have a virtual address, tell me more about it. Tell me, can I get the PTE, the page table entry, that corresponds to the virtual page that contains a particular virtual address on this? So, and this page table entry will contain a bunch of goo. The most important thing that it's going to need to contain and that is a reference to a physical page. Because we're gonna have to do a lot of mapping. If I have a virtual page, give me the corresponding physical page, where do I get that? It's going to be contained in your page table entry on this. Well, most of the time, sometimes that page table entry will map to, well, what's the state of it? Maybe it's the physical page, maybe it hasn't been allocated, or maybe it's been allocated, but it's already been evicted out to disk. That is information that we're gonna tell from looking at the page table entry on this. Again, think about where you might go with this. We don't want you to paint yourself in the corner, but at the same time, start simple. Don't allocate a whole bunch of information and think yourselves into a corner. Start simple. Start with the fact that you've got to have a reference to a physical address and then add stuff as you go along on this. One nice simplification for assignment 3.2 is since address spaces are not going to be accessed by any other process other than the process itself, you don't have to worry about synchronization in terms of page tables on this. So this is gonna greatly simplify this. When you get to assignment 3.3, that's essentially one of the big problems with assignment 3.3 is the processes are now munging on each other's address spaces and that's something that you will need to kind of stick some synchronization in. But for now, that's something that you don't have to worry about. So questions about the data structures, about what they are, about what the segments are, what the page tables are, the page table entries, the differences among them. Crystal clear. Moving on. Let's talk a little bit about the segments themselves. Crudely put, there are five segments that you need to worry about. In a real system, there could be potentially n segments and for details, you need to look at the, let's say the ELF format and like the data when XAC actually runs a new program on this. But for now, what do you need to be concerned about for the purposes of OS 161? Well, we've got a bunch of statically sized segments and obviously text, data and BSS, that's what are traditionally referred to as static segments. They don't change in size. We already know how big they are and essentially how big they will ever get and what's the maximum size that they will ever grow to on this. They are loaded in at runtime from load ELF calls AS defined region on this. The stack, it's kind of odd in one sense to call it statically sized. What we're talking about is the stack has a maximum potential size on this. So in other words, if we get a virtual address referenced to location 7FFFFFF, it's probably a stack reference on this and we can probably assume that there's gonna be one physical page allocated to the stack. But what happens if the stack grows? We're gonna need to be able to grow that thing dynamically. Well, by grow what I mean is grow the allocation of underlying physical pages. If I have a reference to virtual address 60 million, I can probably safely assume that it is not a reference to the stack. In other words, it's not a dynamic reference of the stack growth, rather it is probably something outside of the stack bounds. So this is something, look at the limits.h file on how this actually goes. But there is, if you will, a maxed upfront statically declared fixed size to the stack and within that maximum stack, we allocate pages as the thing grows as needed on this. So that's kind of why I put it up there. So again, this is not the same thing as allocating underlying physical pages. Remember this we have is, we have the segment to determine whether or not a virtual address reference is valid in the first place. But just because it's valid, there may not have yet been a physical page allocated. And that's actually the part that you need to do. What you need to do is change the approach of DumbVM because DumbVM allocates memory statically. It calls this function ASpreparedLoad. And if you look at it, you can see where it not only sets up the segments, but it also immediately when exec calls it, allocates the memory underneath it. So in other words, all physical memory in DumbVM is declared and allocated upfront. Even the stack you can see is set up and the pages are allocated right away and it never really grows after that, which can sometimes create a problem in a real living system on this. So this is where you need to change the approach to dynamic allocation. So the segment sizes don't grow, but the underlying pages within them, those are what need to be allocated on demand or dynamically on this. Questions about the first part, about what these segments are and again more on the interplay with the underlying physical pages. This is the mechanism that the test are gonna be looking for. As the last part deals with the heap on this. And this is something that there are essentially no pre-coded functions on this. You can think of it as being another generic segment that you do need to take care of. Now I would say the heap segment itself can grow in both directions. It can get bigger, it can get smaller and not only that, the pages that are allocated can also be de-allocated as the program is running. And again this is something that functionality of the test to do look for on this. So this is the last part of assignment 3.2 that you need to get going here. It can be somewhat tricky, but it's kind of nice to see that you actually have a working malloc on this. So essentially what there is a three classic segments, that is the tech segment, data and BSS, there is the stack segment and there is the heap segment on this. Moving right along. Let's actually talk a little bit about what happens when there is a reference to a virtual address. So this is actually what happens in a real box including OS 161. So when we have a reference to a virtual address, by the way that could be either a load or a store or it could be fetch an instruction. Remember whether or not we are getting data or whether we are getting the next opcode to execute in both cases, it is a memory reference on this. So we have a virtual address here and step number one is this part is done in hardware, the first if you will flower point. We look to see is there a translation entry in the TLB on that. And if so that means we got a TLB hit, no fault. This is something that the operating system doesn't even know about. This is done in hardware and again it has to be done in hardware for reasons of speed. We talked about that in lecture on this. But if we don't have a mapping, now we have a TLB miss or TLB fault or as I've sloppily called sometimes page fault, again there is that distinction. The next thing is we wanna do here is the virtual address in a segment. That's the thing, this occurs from in software. In other words, if we have a TLB miss then it generates a fault. We're going to MIPSTRAP and MIPSTRAP calls VM fault. And what you need to do, this is kind of what you need to do in real functional code, is is that virtual address in a segment? If it's not, this is where you spaz out and give a segmentation fault on this. You've had to deal with them on Timberlake. Now the fun part is you're actually the one enforcing the segmentation fault and killing off the bad process. And indeed that's what the test will be looking for. You need to kill off the bad process but not panic the entire kernel. There is that distinction. Now let's say that the virtual address is in a segment. Then what we want to do is we want to check to see, it's a valid reference but is there a page table entry that's already been set up for that? And here we have to go through our page table structure, either our array or our list or some whatever it happens to be on this and see where does this virtual address, this virtual page table occur. And if there is one, we need to take a look at it and remember the page table entry has a mapping to a physical address and we can update the TLB and resume execution. That's what happens most of the time. Sometimes that page will have been swapped out to disk and again we can tell that from the page table. We can't resume execution immediately. We've got a block while the disk drive loads in the data yada yada yada on this. So again if we had a TLB fault but we do have the page table entry we need to either just update the TLB or pull it in from disk. If we don't have a page table entry this is dynamic allocation. It means that it was a valid reference. Let's say we referred to location seven, F, F, F, F, O, whatever you do. It's probably the stack dynamically growing. We know it's a valid address because it is in the stack segment but we also know we don't have a page table entry by definition. We add a TLB fault on this which means we need to add more memory to the stack segment. So this is an example of dynamic allocation of the stack on this. With me on this, social hour at the trappist, quiet group today. I'm hoping the silence means that stuff is making sense. This is a piece of cake, what have you. All right. More about assignment VM fault or if you will let's talk through what VM fault currently is and what you actually need to do to get it to do what you want it to do. This is the current behavior in dumb VM. The first third, and I'll pull up some actual code in just a sec here, but essentially dumb VMs VM fault divided into three parts. The first part is sanitization. It goes to a bunch of checks on this. It does do some other stuff too like it checks for super permissions, I'm sorry, sub-permissions which is something that you don't need to do unless you want to get into something like copy on write and it also page aligns the fault address. The second and third thirds is where the meat of VM fault occurs. The second third, well we know that we had a TLB fault on a particular virtual address. Well how are we gonna handle that? We need to see well does it correspond to a real physical address and if so what is that physical address? So what we need to do is search our data structures and remember dumb VM uses the well basin bounds in a sense of multiple basin bounds. Jeff's slides refer to it as like the segment method of doing this. So it's pretty quick to implement and then if we don't find that the virtual address is in a particular memory segment, we just E fault, that's the segmentation fault on this. If we do find it, we now have the underlying physical page and we fall through to the last one third of VM fault and that is we update the information in the TLB. And dumb VM takes what I would say is an almost deliberately crude and hacky way of doing this. Frankly the good way of updating the TLB will be actually a lot simpler and easier and have a lot more functionality on this. So this is essentially how not to do things and if I can digress for just a moment here, where is it? Ah, here we are. Dumb VM. And let's see here. Ah, here we are. So here is VM fault and let's see here. All right, essentially a whole bunch of sanity checking. We go through, we get the fault type, we get the fault address and then we fall through eventually to right here. This is the next one third. In other words the fault address, that is the virtual address and we're checking to see is it in one of these base and bounds of the three segments that dumb VM has. Remember dumb VM has one hard coded stack segment and two additional segments that were statically allocated and it checks to see whether it's in one of these three segments. If not there's your seg fault right there, the E fault which it doesn't even return a seg fault. Remember originally it just crashes the kernel. But given a particular virtual address what it does is it returns a physical address. So essentially this is our virtual to physical mapping on here and then the last part of dumb VM that's where the update to the TLB occurs. In other words we know by definition that there was not a virtual to physical mapping in the TLB. Well given the virtual address we've now successfully located what the physical address should be so now we fall through and this code here essentially what it does is it searches for the first free available entry in the TLB and populates it and done. If it does not find a free entry it well just returns an error which will crash the system yada yada yada on this. So that's kind of the behavior of dumb VM. What you wanna do is rather than searching for the first available one well there might be an available one that's great but if there's not you're gonna need to evict an entry on this. So in other words never fault on lack of TLB entries. If you don't have one you're gonna have to create one on this. Not difficult it's probably one of the quicker changes but it's something that does need to be done because if you don't do that what happens is after you referred to more than 64 pages your user program is gonna bomb. Questions about the mechanics of dumb VM VM fault? The slide deck. So what do you need to do for VM fault here? Again we need to rewrite things, oops wait a minute. Okay and given a virtual fault determined again is it a potentially valid address? You again need to look at your segment information and then if it is a valid address search for a page table entry and then take a look at the page table entry for the state here. You may need to allocate a new page you may need to swap it in from disk here. So this essentially the second third of VM fault needs to be completely gutted and rewritten on this. Then the last third if you will the updating of the TLB entries here. Again it's you can look at how dumb VM does it but correct code that essentially evicts when you need to is actually gonna be a lot shorter. Like I say my thought is that at Harvard they were actually deliberately hacking it and try to force you to do something with that because correct code you can either like use round robin or random or what have you just always make sure that there's an entry and return. So questions about the behavior of what VM fault needs to do on this. Instead of searching the base and bounds search your own data structures, possibly return an error and possibly update the TLB. Alrighty, where do we go from here? How do you actually get started with assignment 3.2 on this? This would be my suggested approach to you. Yep, data structures sit down with your partner and stamp stuff out then talk to the staff on here and what you're gonna need is well the address space, the page table entry structures and the page table on that. And just kind of you're not gonna get it perfect obviously you're gonna make changes on this but what's gonna be your general approach to this thing here and what are some of the basic fields you need to put into this stuff just to get started. Then you wanna actually get stuff working. Again at this point I do assume once you've completed assignment 3.1 you should at least be able to boot to a kernel menu. You won't be able to run any user code until you get this next step going. But if you have a kernel menu prompt and you can pass test KM1 through KM5 that means you've got to work in core map because this assignment is gonna be building on top of that. Well what do I need to do to get a simple hello world program running? Remember how you needed to do that for assignment 2.1 and 2.2? Well same thing here true except now let's see if we can't run it on your brand spanking new memory manager on this. Well there's a lot of functions that you need to write but what's the bare minimum just to get a stupid hello world program running? Answer, AS create, AS define region, AS define stack and VM fault. You can use the AS activate just port that over. Essentially that functionality, remember what AS activate does is it's used to update the entries in the TLB and for now the approach that's taken by dumb VM is essentially flush the entire TLB on every and each context switch on this. That certainly works, you can change that if needed. Frankly have really not found that it needs to be done on this. So again just make sure that you do update or flush the TLB entries because if you don't do that then you will have problems. But what you need to write again is remember AS create that is to initialize your memory data structures when the process is created or forked. Define region that defines your segments. Define stack is really just a subset. You can possibly even have defined stack called defined region. It's really two sides of the same coin on this. And then the VM fault, we just talked about that, that there's going to be a significant amount of just redoing that from almost ground up on this. So questions about what you need to do just to get started. The reason I mentioned is in terms of prioritization. Some of this other stuff, fork and memory recommendation. Okay get a hello world program working first. But these other things like AS copy for most people is a pain. Well you're gonna need to write it but I'm just saying in terms of it's not something. Work out the bugs and the kinks with getting a hello world program working and then move on to AS copy because that's what you need for fork and creating multiple processes. And then AS destroy and once you have that you can start working on memory cleanup. And as we make a note here, at this point pause. Before you go on to heap, make sure that you have nailed down every and I do mean every last blooming memory leak in your kernel on this because it will be tested. Excuse me. Again, Scott's going to be using KHU when test 161. If you are leaking even a bite, it will be noted and detected and the tests will catch up.