diff --git a/labcodes/lab3/bin/bootblock b/labcodes/lab3/bin/bootblock new file mode 100644 index 0000000000000000000000000000000000000000..b04b04f58b3af9b64903fdd9b677a794735388c2 Binary files /dev/null and b/labcodes/lab3/bin/bootblock differ diff --git a/labcodes/lab3/bin/kernel b/labcodes/lab3/bin/kernel new file mode 100755 index 0000000000000000000000000000000000000000..5ee82a342f95c35a7a251f83a19a7cf55ba8d339 Binary files /dev/null and b/labcodes/lab3/bin/kernel differ diff --git a/labcodes/lab3/bin/sign b/labcodes/lab3/bin/sign new file mode 100755 index 0000000000000000000000000000000000000000..c67eea1f474b660c6ac8f3cd113f659071f6bd7b Binary files /dev/null and b/labcodes/lab3/bin/sign differ diff --git a/labcodes/lab3/bin/swap.img b/labcodes/lab3/bin/swap.img new file mode 100644 index 0000000000000000000000000000000000000000..52e65dd21c3fc2924229516cb140503b22ee21fb Binary files /dev/null and b/labcodes/lab3/bin/swap.img differ diff --git a/labcodes/lab3/bin/ucore.img b/labcodes/lab3/bin/ucore.img new file mode 100644 index 0000000000000000000000000000000000000000..13e60d9dd34d0c106435da110f22eb216655e69c Binary files /dev/null and b/labcodes/lab3/bin/ucore.img differ diff --git a/labcodes/lab3/kern/driver/console.c b/labcodes/lab3/kern/driver/console.c index d4cf56b32322444254cc39e569934880cd2a1f70..a32d04c49f8a492f86279b2f328e722bf1a19857 100644 --- a/labcodes/lab3/kern/driver/console.c +++ b/labcodes/lab3/kern/driver/console.c @@ -414,8 +414,11 @@ kbd_init(void) { /* cons_init - initializes the console devices */ void cons_init(void) { + //初始化CGA显示设备 cga_init(); + //初始化串行端口 serial_init(); + //初始化键盘 kbd_init(); if (!serial_exists) { cprintf("serial port does not exist!!\n"); diff --git a/labcodes/lab3/kern/driver/picirq.c b/labcodes/lab3/kern/driver/picirq.c index e7f7063a0fb278d40cc01e8c7276fe5bba8bae8a..1aed56fb4a212f62ad014a6c950ff4eb73aafc2c 100644 --- a/labcodes/lab3/kern/driver/picirq.c +++ b/labcodes/lab3/kern/driver/picirq.c @@ -12,43 +12,72 @@ // Initial IRQ mask has interrupt 2 enabled (for slave 8259A). static uint16_t irq_mask = 0xFFFF & ~(1 << IRQ_SLAVE); static bool did_init = 0; - +/** + * 设置中断请求(IRQ)掩码的函数 + * 此函数用于更新内部的IRQ掩码,并在设备初始化后,将掩码值写入到两个级联的可编程中断控制器(PIC)中 + * + * @param mask 一个16位的掩码值,用于配置IRQ线的掩码 + */ static void pic_setmask(uint16_t mask) { + // 更新内部的IRQ掩码 irq_mask = mask; + // 仅在设备已初始化的情况下执行后续操作 if (did_init) { + // 向主PIC发送低8位的掩码 outb(IO_PIC1 + 1, mask); + // 向从PIC发送高8位的掩码 outb(IO_PIC2 + 1, mask >> 8); } } - +/** + * 启用指定的中断源 + * 此函数通过更新中断掩码寄存器来启用特定的中断源 + * + * @param irq 要启用的中断源的编号 + */ void pic_enable(unsigned int irq) { + // 更新中断掩码,清除对应IRQ的掩码位以启用中断 pic_setmask(irq_mask & ~(1 << irq)); } /* pic_init - initialize the 8259A interrupt controllers */ +// 初始化可编程中断控制器(PIC) +// 此函数配置 PIC 以准备处理系统中的中断 void pic_init(void) { + // 标记 PIC 初始化完成 did_init = 1; // mask all interrupts + // 屏蔽所有中断 + // 初始时,屏蔽所有中断以防止在设置过程中发生意外中断 outb(IO_PIC1 + 1, 0xFF); outb(IO_PIC2 + 1, 0xFF); // Set up master (8259A-1) + // 配置主 PIC(8259A-1) + // 配置主 PIC 芯片 // ICW1: 0001g0hi // g: 0 = edge triggering, 1 = level triggering // h: 0 = cascaded PICs, 1 = master only // i: 0 = no ICW4, 1 = ICW4 required + // ICW1: 0001g0hi + // g: 0 = 边沿触发,1 = 电平触发 + // h: 0 = 级联 PIC,1 = 仅主 PIC + // i: 0 = 不需要 ICW4,1 = 需要 ICW4 outb(IO_PIC1, 0x11); + // ICW2: 中断向量偏移 // ICW2: Vector offset outb(IO_PIC1 + 1, IRQ_OFFSET); // ICW3: (master PIC) bit mask of IR lines connected to slaves // (slave PIC) 3-bit # of slave's connection to master + // ICW3: (主 PIC)IR 线连接到从 PIC 的位掩码 + // (从 PIC)从 PIC 连接到主 PIC 的 3 位编号 outb(IO_PIC1 + 1, 1 << IRQ_SLAVE); // ICW4: 000nbmap @@ -59,26 +88,41 @@ pic_init(void) { // can be hardwired). // a: 1 = Automatic EOI mode // p: 0 = MCS-80/85 mode, 1 = intel x86 mode + // ICW4: 000nbmap + // n: 1 = 特殊全嵌套模式 + // b: 1 = 缓冲模式 + // m: 0 = 从 PIC,1 = 主 PIC + // (当 b 为 0 时忽略,因为主/从角色可以硬连线) + // a: 1 = 自动 EOI 模式 + // p: 0 = MCS-80/85 模式,1 = Intel x86 模式 outb(IO_PIC1 + 1, 0x3); // Set up slave (8259A-2) + // 配置从 PIC(8259A-2) outb(IO_PIC2, 0x11); // ICW1 outb(IO_PIC2 + 1, IRQ_OFFSET + 8); // ICW2 outb(IO_PIC2 + 1, IRQ_SLAVE); // ICW3 // NB Automatic EOI mode doesn't tend to work on the slave. // Linux source code says it's "to be investigated". + // 注意:自动 EOI 模式通常在从 PIC 上不起作用 + // Linux 源代码中提到这是“待调查”的问题 outb(IO_PIC2 + 1, 0x3); // ICW4 // OCW3: 0ef01prs // ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask // p: 0 = no polling, 1 = polling mode // rs: 0x = NOP, 10 = read IRR, 11 = read ISR - outb(IO_PIC1, 0x68); // clear specific mask - outb(IO_PIC1, 0x0a); // read IRR by default + // OCW3: 0ef01prs + // ef: 0x = 无操作,10 = 清除特定掩码,11 = 设置特定掩码 + // p: 0 = 无轮询,1 = 轮询模式 + // rs: 0x = 无操作,10 = 读取 IRR,11 = 读取 ISR + outb(IO_PIC1, 0x68); // clear specific mask// 清除特定掩码 + outb(IO_PIC1, 0x0a); // read IRR by default// 默认读取 IRR outb(IO_PIC2, 0x68); // OCW3 outb(IO_PIC2, 0x0a); // OCW3 - + + // 如果有自定义的中断掩码,则设置中断掩码 if (irq_mask != 0xFFFF) { pic_setmask(irq_mask); } diff --git a/labcodes/lab3/kern/fs/swapfs.c b/labcodes/lab3/kern/fs/swapfs.c index d9f6090a6b3a29e8f0a078632d7b4576eb939cdb..11469749c669dc03e83debe1418d8981012ec736 100644 --- a/labcodes/lab3/kern/fs/swapfs.c +++ b/labcodes/lab3/kern/fs/swapfs.c @@ -15,6 +15,10 @@ swapfs_init(void) { max_swap_offset = ide_device_size(SWAP_DEV_NO) / (PGSIZE / SECTSIZE); } +//entry:表示要读取的交换条目。page:指向要填充的内存页的指针。 +//函数返回 ide_read_secs 的结果,表示读取操作是否成功 +//计算交换条目的偏移量 swap_offset(entry)。 +//使用 ide_read_secs 函数从交换设备 SWAP_DEV_NO 中读取指定数量的扇区(PAGE_NSECT)到内存页 page2kva(page) 中。 int swapfs_read(swap_entry_t entry, struct Page *page) { return ide_read_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT); diff --git a/labcodes/lab3/kern/mm/default_pmm.c b/labcodes/lab3/kern/mm/default_pmm.c index c0649e49adbe91abc6be253e7402340d74d8b3e3..30947df57c0232376a0924ef5b30aaf8b99b99fa 100644 --- a/labcodes/lab3/kern/mm/default_pmm.c +++ b/labcodes/lab3/kern/mm/default_pmm.c @@ -163,7 +163,7 @@ default_init_memmap(struct Page *base, size_t n) { base->property = n; SetPageProperty(base);// 设置当前页的有效标志 nr_free += n;// 更新空闲页计数 - list_add(&free_list, &(base->page_link));// 将该块添加到空闲列表中 + list_add_before(&free_list, &(base->page_link));// 将该块添加到空闲列表中 } //用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 @@ -184,12 +184,14 @@ default_alloc_pages(size_t n) { } } if (page != NULL) {// 如果找到合适的块 - list_del(&(page->page_link));// 从空闲列表中删除该块 + //list_del(&(page->page_link));// 从空闲列表中删除该块 if (page->property > n) { struct Page *p = page + n;// 指向剩余的页 p->property = page->property - n;// 更新剩余块的页数 - list_add(&free_list, &(p->page_link));// 将剩余块添加回空闲列表 + SetPageProperty(p); + list_add_after(&(page->page_link), &(p->page_link));// 将剩余块添加回空闲列表 } + list_del(&(page->page_link)); nr_free -= n;// 减少空闲页的计数 ClearPageProperty(page);// 清除已分配页的属性 } @@ -228,7 +230,19 @@ default_free_pages(struct Page *base, size_t n) { } } nr_free += n;// 更新空闲页的计数 - list_add(&free_list, &(base->page_link));// 将释放的页块添加到空闲列表中 + le = list_next(&free_list); + while (le != &free_list) + { + p = le2page(le, page_link); + if (base + base->property <= p) + { + assert(base + base->property != p); + break; + } + le = list_next(le); + } + + list_add_before(le, &(base->page_link));// 将释放的页块添加到空闲列表中 } //用于返回当前系统中可用的空闲页的数量。 diff --git a/labcodes/lab3/kern/mm/swap.c b/labcodes/lab3/kern/mm/swap.c index 0ce392fdf7783074b5979315d34a5932b8647500..6f38077cf9481058692ef54d8548c1f1d298e1bf 100644 --- a/labcodes/lab3/kern/mm/swap.c +++ b/labcodes/lab3/kern/mm/swap.c @@ -116,16 +116,19 @@ swap_out(struct mm_struct *mm, int n, int in_tick) return i; } +//实现一个页交换功能。 int swap_in(struct mm_struct *mm, uintptr_t addr, struct Page **ptr_result) { + //分配一个新的页面result struct Page *result = alloc_page(); assert(result!=NULL); - + //获取虚拟地址 addr 对应的页表项指针 ptep pte_t *ptep = get_pte(mm->pgdir, addr, 0); // cprintf("SWAP: load ptep %x swap entry %d to vaddr 0x%08x, page %x, No %d\n", ptep, (*ptep)>>8, addr, result, (result-pages)); int r; + //从交换文件中读取数据到新分配的页面 result 中 if ((r = swapfs_read((*ptep), result)) != 0) { assert(r!=0); diff --git a/labcodes/lab3/kern/mm/vmm.c b/labcodes/lab3/kern/mm/vmm.c index bbef092dbe76d88001137dcc28d99523c4a15c37..901c81c189a1e3f662173e6f29d185f85b96caea 100644 --- a/labcodes/lab3/kern/mm/vmm.c +++ b/labcodes/lab3/kern/mm/vmm.c @@ -428,35 +428,51 @@ volatile unsigned int pgfault_num=0; * -- The U/S flag (bit 2) indicates whether the processor was executing at user mode (1) * or supervisor mode (0) at the time of the exception. */ +/** + * 处理给定内存管理上下文的页面错误。 + * + * @param mm 指向内存管理结构的指针。 + * @param error_code 页面错误发生时硬件提供的错误代码。 + * @param addr 引发页面错误的线性地址。 + * + * @return 成功返回0,失败返回负错误码。 + */ int do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { - int ret = -E_INVAL; + int ret = -E_INVAL;// 初始化返回值为无效错误 //try to find a vma which include addr + // 尝试找到包含 addr 的 vma struct vma_struct *vma = find_vma(mm, addr); - pgfault_num++; + pgfault_num++;// 增加页面错误计数 + // 检查 addr 是否在 mm 的 vma 范围内 //If the addr is in the range of a mm's vma? if (vma == NULL || vma->vm_start > addr) { cprintf("not valid addr %x, and can not find it in vma\n", addr); - goto failed; + goto failed;// 跳转到错误处理部分 } //check the error_code + // 检查错误代码 switch (error_code & 3) { default: + /* 默认错误代码标志:3 (W/R=1, P=1): 写操作,存在 */ /* error code flag : default is 3 ( W/R=1, P=1): write, present */ case 2: /* error code flag : (W/R=1, P=0): write, not present */ + /* 错误代码标志:(W/R=1, P=0): 写操作,不存在 */ if (!(vma->vm_flags & VM_WRITE)) { cprintf("do_pgfault failed: error code flag = write AND not present, but the addr's vma cannot write\n"); - goto failed; + goto failed;// 跳转到错误处理部分 } break; case 1: /* error code flag : (W/R=0, P=1): read, present */ + /* 错误代码标志:(W/R=0, P=1): 读操作,存在 */ cprintf("do_pgfault failed: error code flag = read AND present\n"); - goto failed; + goto failed;// 跳转到错误处理部分 case 0: /* error code flag : (W/R=0, P=0): read, not present */ + /* 错误代码标志:(W/R=0, P=0): 读操作,不存在 */ if (!(vma->vm_flags & (VM_READ | VM_EXEC))) { cprintf("do_pgfault failed: error code flag = read AND not present, but the addr's vma cannot read or exec\n"); - goto failed; + goto failed;// 跳转到错误处理部分 } } /* IF (write an existed addr ) OR @@ -465,13 +481,18 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * THEN * continue process */ - uint32_t perm = PTE_U; + /* 如果 (写入已存在的地址) 或 + * (写入不存在的地址且地址可写) 或 + * (读取不存在的地址且地址可读) + * 则继续处理 + */ + uint32_t perm = PTE_U;// 初始化权限标志为用户可访问 if (vma->vm_flags & VM_WRITE) { - perm |= PTE_W; + perm |= PTE_W;// 如果 vma 可写,则设置写权限 } - addr = ROUNDDOWN(addr, PGSIZE); + addr = ROUNDDOWN(addr, PGSIZE);// 将地址对齐到页边界 - ret = -E_NO_MEM; + ret = -E_NO_MEM;// 初始化返回值为内存不足错误 pte_t *ptep=NULL; /*LAB3 EXERCISE 1: YOUR CODE @@ -491,12 +512,31 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * mm->pgdir : the PDT of these vma * */ + /* LAB3 练习 1: 你的代码 + * 可能需要帮助的注释,以下注释可以帮助你完成代码 + * + * 一些有用的宏和定义,你可以在下面的实现中使用它们。 + * 宏或函数: + * get_pte : 获取一个页表项并返回该页表项的内核虚拟地址 + * 如果包含该页表项的页表不存在,则分配一个页表 (注意第三个参数 '1') + * pgdir_alloc_page : 调用 alloc_page 和 page_insert 函数分配一页大小的内存并设置 + * 地址映射 pa<--->la 与页目录表 pgdir + * 定义: + * VM_WRITE : 如果 vma->vm_flags & VM_WRITE == 1/0,则 vma 是可写/不可写的 + * PTE_W 0x002 // 页表/目录项标志位:可写 + * PTE_U 0x004 // 页表/目录项标志位:用户可访问 + * 变量: + * mm->pgdir : 这些 vma 的页目录表 + * + */ #if 0 /*LAB3 EXERCISE 1: YOUR CODE*/ + /* LAB3 练习 1: 你的代码*/ ptep = ??? //(1) try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT. + // (1) 尝试找到一个页表项,如果该页表项的页表不存在,则创建一个页表。 if (*ptep == 0) { //(2) if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr - + // (2) 如果物理地址不存在,则分配一页内存并映射物理地址与逻辑地址 } else { /*LAB3 EXERCISE 2: YOUR CODE @@ -509,22 +549,71 @@ do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { * find the addr of disk page, read the content of disk page into this memroy page * page_insert : build the map of phy addr of an Page with the linear addr la * swap_map_swappable : set the page swappable + */ + /* LAB3 练习 2: 你的代码 + * 现在我们认为这个页表项是一个交换项,我们应该从磁盘加载数据到一个具有物理地址的页面, + * 并映射物理地址与逻辑地址,触发交换管理器记录该页面的访问情况。 + * + * 一些有用的宏和定义,你可以在下面的实现中使用它们。 + * 宏或函数: + * swap_in(mm, addr, &page) : 分配一个内存页面,然后根据 addr 的页表项中的交换项, + * 找到磁盘页面的地址,将磁盘页面的内容读入该内存页面 + * page_insert : 根据 mm 和 addr 设置物理地址与逻辑地址的映射 + * swap_map_swappable : 设置页面可交换 */ if(swap_init_ok) { struct Page *page=NULL; //(1)According to the mm AND addr, try to load the content of right disk page + // (1) 根据 mm 和 addr,尝试从正确的磁盘页面加载内容到 page 管理的内存中 // into the memory which page managed. + // (2) 根据 mm、addr 和 page,设置物理地址与逻辑地址的映射 //(2) According to the mm, addr AND page, setup the map of phy addr <---> logical addr //(3) make the page swappable. + // (3) 使页面可交换 } else { cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep); - goto failed; + goto failed;// 跳转到错误处理部分 } } + #endif - ret = 0; + // try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT. + // (notice the 3th parameter '1') + // 尝试找到一个页表项 pte,如果包含该 pte 的页表不存在,则创建一个页表。 + // 注意第三个参数 '1' 表示如果需要,可以创建新的页表。 + if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) { + cprintf("get_pte in do_pgfault failed\n");// 输出错误信息 + goto failed;// 跳转到错误处理部分 + } + // 如果页表项 pte 的物理地址不存在,则分配一页内存并映射物理地址与逻辑地址 + if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr + if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) { + cprintf("pgdir_alloc_page in do_pgfault failed\n");// 输出错误信息 + goto failed;// 跳转到错误处理部分 + } + } + else { // if this pte is a swap entry, then load data from disk to a page with phy addr + // and call page_insert to map the phy addr with logical addr + // 如果页表项 pte 是一个交换项,则从磁盘加载数据到 + //一个具有物理地址的页面,并映射物理地址与逻辑地址 + if(swap_init_ok) {// 检查交换初始化是否成功 + struct Page *page=NULL;// 声明一个页面指针 + if ((ret = swap_in(mm, addr, &page)) != 0) { + cprintf("swap_in in do_pgfault failed\n"); + goto failed; + } + page_insert(mm->pgdir, page, addr, perm);// 设置物理地址与逻辑地址的映射 + swap_map_swappable(mm, addr, page, 1);// 设置页面可交换 + page->pra_vaddr = addr;// 记录页面的虚拟地址 + } + else { + cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep); + goto failed;// 跳转到错误处理部分 + } + } + ret = 0;// 设置返回值为成功 failed: - return ret; + return ret;// 返回结果 } diff --git a/labcodes/lab3/kern/trap/trap.c b/labcodes/lab3/kern/trap/trap.c index 2e6bcf05fd4156d2670d9980f15f7334acd1acbc..ce2599e65e19195b23c59437518570163123ed90 100644 --- a/labcodes/lab3/kern/trap/trap.c +++ b/labcodes/lab3/kern/trap/trap.c @@ -161,7 +161,13 @@ print_regs(struct pushregs *regs) { cprintf(" ecx 0x%08x\n", regs->reg_ecx); cprintf(" eax 0x%08x\n", regs->reg_eax); } - +/** + * 打印关于页面故障的详细信息。 + * + * 此函数用于输出页面故障的详细信息,包括故障地址、访问类型(读/写)、访问模式(用户/内核)以及故障类型(未找到页面/保护故障)。 + * + * @param tf 指向 trapframe 结构的指针,包含故障发生时的寄存器状态和错误代码。 + */ static inline void print_pgfault(struct trapframe *tf) { /* error_code: @@ -169,19 +175,39 @@ print_pgfault(struct trapframe *tf) { * bit 1 == 0 means read, 1 means write * bit 2 == 0 means kernel, 1 means user * */ + /* error_code: + * bit 0 == 0 表示未找到页面,1 表示保护故障 + * bit 1 == 0 表示读操作,1 表示写操作 + * bit 2 == 0 表示内核模式,1 表示用户模式 + * */ cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), (tf->tf_err & 4) ? 'U' : 'K', (tf->tf_err & 2) ? 'W' : 'R', (tf->tf_err & 1) ? "protection fault" : "no page found"); } +/** + * 页面故障处理函数 + * + * 此函数负责处理页面故障异常,它首先打印出页面故障的信息, + * 然后根据是否有有效的内存管理结构来决定是否进行页面故障处理, + * 如果没有有效的内存管理结构,则引发系统崩溃 + * + * @param tf 指向陷阱帧的指针,包含故障发生时的CPU状态信息 + * @return 返回页面故障处理的结果,或者在无法处理时引发系统崩溃 + */ static int pgfault_handler(struct trapframe *tf) { + // 声明一个外部变量,用于检查内存管理结构 extern struct mm_struct *check_mm_struct; + // 打印页面故障信息 print_pgfault(tf); + // 检查是否存在有效的内存管理结构 if (check_mm_struct != NULL) { + // 如果存在,调用页面故障处理函数 return do_pgfault(check_mm_struct, tf->tf_err, rcr2()); } + // 如果没有有效的内存管理结构,引发系统崩溃 panic("unhandled page fault.\n"); } @@ -190,6 +216,7 @@ extern struct mm_struct *check_mm_struct; struct trapframe switchk2u, *switchu2k; //定义了一个名为 trap_dispatch 的静态函数,根据发生的陷阱类型进行相应的处理。 +// 参数 tf 是指向陷阱帧的指针,包含了关于陷阱发生时的CPU状态信息。 static void trap_dispatch(struct trapframe *tf) { char c; @@ -198,6 +225,7 @@ trap_dispatch(struct trapframe *tf) { //通过 switch 语句根据 tf->tf_trapno 的值来分发不同的陷阱处理逻辑。 switch (tf->tf_trapno) { case T_PGFLT: //page fault + // 处理页故障中断 if ((ret = pgfault_handler(tf)) != 0) { print_trapframe(tf); panic("handle pgfault failed. %e\n", ret); diff --git a/labcodes/lab3/kern/trap/trapentry.S b/labcodes/lab3/kern/trap/trapentry.S index 55e29b705c220ddcf9c3dc62218a416641e37f7d..1fa8751201d21d91f0bddd27e98cd41e77f4c915 100644 --- a/labcodes/lab3/kern/trap/trapentry.S +++ b/labcodes/lab3/kern/trap/trapentry.S @@ -1,11 +1,13 @@ #include # vectors.S sends all traps here. +# 定义了一个全局标签 __alltraps,这是处理所有异常的入口点。 .text .globl __alltraps __alltraps: # push registers to build a trap frame # therefore make the stack look like a struct trapframe + # 通过 push 指令,将数据段寄存器和所有通用寄存器(使用 pushal)的值压入栈中,以保存当前状态。 pushl %ds pushl %es pushl %fs @@ -13,32 +15,39 @@ __alltraps: pushal # load GD_KDATA into %ds and %es to set up data segments for kernel + # 将常量 GD_KDATA 加载到 %eax 中,然后将其值复制到 %ds 和 %es 中,设置内核的数据段。 movl $GD_KDATA, %eax movw %ax, %ds movw %ax, %es # push %esp to pass a pointer to the trapframe as an argument to trap() + # 将 %esp 压栈,以将指向 trapframe 的指针作为参数传递给 trap() pushl %esp # call trap(tf), where tf=%esp + # 调用 trap(tf),其中 tf=%esp call trap - # pop the pushed stack pointer + # pop the pushed stack pointer弹出之前压入的栈指针 popl %esp # return falls through to trapret... + # 返回后继续执行到 trapret... .globl __trapret __trapret: # restore registers from stack + # 定义了返回的入口点 __trapret。 popal # restore %ds, %es, %fs and %gs + # 这里会恢复之前保存的寄存器 popl %gs popl %fs popl %es popl %ds # get rid of the trap number and error code + # 通过 iret 指令返回中断处理 addl $0x8, %esp iret diff --git a/labcodes/lab3/obj/boot/bootasm.d b/labcodes/lab3/obj/boot/bootasm.d new file mode 100644 index 0000000000000000000000000000000000000000..0814674615b0e7471d87201075118ec74cb33a79 --- /dev/null +++ b/labcodes/lab3/obj/boot/bootasm.d @@ -0,0 +1 @@ +obj/boot/bootasm.o obj/boot/bootasm.d: boot/bootasm.S boot/asm.h diff --git a/labcodes/lab3/obj/boot/bootasm.o b/labcodes/lab3/obj/boot/bootasm.o new file mode 100644 index 0000000000000000000000000000000000000000..c1351642f78541fa53085ff53d15cc9aa3508572 Binary files /dev/null and b/labcodes/lab3/obj/boot/bootasm.o differ diff --git a/labcodes/lab3/obj/boot/bootmain.d b/labcodes/lab3/obj/boot/bootmain.d new file mode 100644 index 0000000000000000000000000000000000000000..c0d98e63cd309eaf0c4e92439e4ea83bd1c9acc0 --- /dev/null +++ b/labcodes/lab3/obj/boot/bootmain.d @@ -0,0 +1,2 @@ +obj/boot/bootmain.o obj/boot/bootmain.d: boot/bootmain.c libs/defs.h \ + libs/x86.h libs/elf.h diff --git a/labcodes/lab3/obj/boot/bootmain.o b/labcodes/lab3/obj/boot/bootmain.o new file mode 100644 index 0000000000000000000000000000000000000000..c72e25d0a0da0d07b6a528c4edddda1156d4be4d Binary files /dev/null and b/labcodes/lab3/obj/boot/bootmain.o differ diff --git a/labcodes/lab3/obj/bootblock.asm b/labcodes/lab3/obj/bootblock.asm new file mode 100644 index 0000000000000000000000000000000000000000..5cb635ae62ab0d3c1d4a525b21d698f348d20825 --- /dev/null +++ b/labcodes/lab3/obj/bootblock.asm @@ -0,0 +1,354 @@ + +obj/bootblock.o: file format elf32-i386 + + +Disassembly of section .startup: + +00007c00 : +# start address should be 0:7c00, in real mode, the beginning address of the running bootloader +# 起始地址应该是 0:7c00,在实模式下,这是运行的引导加载程序的起始地址。 +.globl start # 表示将 start 标签声明为全局可见的入口点。 +start: # 定义 start 标签 +.code16 # Assemble for 16-bit mode 指示编译器将后续代码编译为 16 位模式 + cli # Disable interrupts 禁用中断 + 7c00: fa cli + cld # String operations increment 清除方向标志(DF),使字符串操作在内存中从低地址到高地址进行增量操作。 + 7c01: fc cld + + # Set up the important data segment registers (DS, ES, SS). + xorw %ax, %ax # Segment number zero 将寄存器 AX 清零,准备将其作为段寄存器的值。 + 7c02: 31 c0 xor %eax,%eax + movw %ax, %ds # -> Data Segment 将 AX(值为 0)存入数据段寄存器 DS,初始化数据段为 0。 + 7c04: 8e d8 mov %eax,%ds + movw %ax, %es # -> Extra Segment 将 AX(仍然是 0)存入附加段寄存器 ES,初始化附加段为 0。 + 7c06: 8e c0 mov %eax,%es + movw %ax, %ss # -> Stack Segment 将 AX(仍然是 0)存入栈段寄存器 SS,初始化栈段为 0。 + 7c08: 8e d0 mov %eax,%ss + +00007c0a : + # Enable A20: + # For backwards compatibility with the earliest PCs, physical + # address line 20 is tied low, so that addresses higher than + # 1MB wrap around to zero by default. This code undoes this. +seta20.1: + inb $0x64, %al # Wait for not busy(8042 input buffer empty). 设置标签 seta20.1,从 I/O 端口 0x64 读取数据到寄存器 AL,等待8042控制器输入缓冲区为空。 + 7c0a: e4 64 in $0x64,%al + testb $0x2, %al + 7c0c: a8 02 test $0x2,%al + jnz seta20.1 # 测试 AL 中的第 2 位,如果不为零,则跳回 seta20.1,表示8042仍在忙。 + 7c0e: 75 fa jne 7c0a + + movb $0xd1, %al # 0xd1 -> port 0x64 将值 0xd1 存入 AL,这个值将被写入端口 0x64。 + 7c10: b0 d1 mov $0xd1,%al + outb %al, $0x64 # 0xd1 means: write data to 8042's P2 port 将 AL 的值(即 0xd1)写入端口 0x64 + 7c12: e6 64 out %al,$0x64 + +00007c14 : + +seta20.2: + inb $0x64, %al # Wait for not busy(8042 input buffer empty). 设置标签 seta20.2,同样从端口 0x64 读取数据到 AL,等待8042输入缓冲区为空。 + 7c14: e4 64 in $0x64,%al + testb $0x2, %al + 7c16: a8 02 test $0x2,%al + jnz seta20.2 # 再次测试 AL 中的第 2 位,如果不为零,则跳回 seta20.2。 + 7c18: 75 fa jne 7c14 + + movb $0xdf, %al # 0xdf -> port 0x60 将值 0xdf 存入 AL,此值将被写入端口 0x60。 + 7c1a: b0 df mov $0xdf,%al + outb %al, $0x60 # 0xdf = 11011111, means set P2's A20 bit(the 1 bit) to 1 将 AL 的值(即 0xdf)写入端口 0x60,这将设置8042控制器的 A20 地址线为高(1),允许访问超过1MB的内存。 + 7c1c: e6 60 out %al,$0x60 + +00007c1e : + +probe_memory: + movl $0, 0x8000 + 7c1e: 66 c7 06 00 80 movw $0x8000,(%esi) + 7c23: 00 00 add %al,(%eax) + 7c25: 00 00 add %al,(%eax) + xorl %ebx, %ebx + 7c27: 66 31 db xor %bx,%bx + movw $0x8004, %di + 7c2a: bf .byte 0xbf + 7c2b: 04 80 add $0x80,%al + +00007c2d : +start_probe: + movl $0xE820, %eax + 7c2d: 66 b8 20 e8 mov $0xe820,%ax + 7c31: 00 00 add %al,(%eax) + movl $20, %ecx + 7c33: 66 b9 14 00 mov $0x14,%cx + 7c37: 00 00 add %al,(%eax) + movl $SMAP, %edx + 7c39: 66 ba 50 41 mov $0x4150,%dx + 7c3d: 4d dec %ebp + 7c3e: 53 push %ebx + int $0x15 + 7c3f: cd 15 int $0x15 + jnc cont + 7c41: 73 08 jae 7c4b + movw $12345, 0x8000 + 7c43: c7 06 00 80 39 30 movl $0x30398000,(%esi) + jmp finish_probe + 7c49: eb 0e jmp 7c59 + +00007c4b : +cont: + addw $20, %di + 7c4b: 83 c7 14 add $0x14,%edi + incl 0x8000 + 7c4e: 66 ff 06 incw (%esi) + 7c51: 00 80 66 83 fb 00 add %al,0xfb8366(%eax) + cmpl $0, %ebx + jnz start_probe + 7c57: 75 d4 jne 7c2d + +00007c59 : + + # Switch from real to protected mode, using a bootstrap GDT + # and segment translation that makes virtual addresses + # identical to physical addresses, so that the + # effective memory map does not change during the switch. + lgdt gdtdesc #加载全局描述符表寄存器(GDTR)到 gdtdesc,以便设置保护模式的段描述符。 + 7c59: 0f 01 16 lgdtl (%esi) + 7c5c: b8 7d 0f 20 c0 mov $0xc0200f7d,%eax + movl %cr0, %eax #将控制寄存器 CR0 的值加载到寄存器 EAX 中 + orl $CR0_PE_ON, %eax #将 CR0 中的保护模式开启标志(CR0_PE_ON)与 EAX 相或,以便设置 CR0 的保护模式位。 + 7c61: 66 83 c8 01 or $0x1,%ax + movl %eax, %cr0 #将修改后的 EAX 的值存回 CR0,使处理器进入保护模式。 + 7c65: 0f 22 c0 mov %eax,%cr0 + + # Jump to next instruction, but in 32-bit code segment. + # Switches processor into 32-bit mode. + ljmp $PROT_MODE_CSEG, $protcseg #执行远跳转到保护模式的代码段 PROT_MODE_CSEG 和偏移地址 protcseg,实现模式切换并开始执行32位代码。 + 7c68: ea .byte 0xea + 7c69: 6d insl (%dx),%es:(%edi) + 7c6a: 7c 08 jl 7c74 + ... + +00007c6d : + +.code32 # Assemble for 32-bit mode +protcseg: #定义标签 protcseg,表示保护模式下的代码段开始。 + # Set up the protected-mode data segment registers + movw $PROT_MODE_DSEG, %ax # Our data segment selector 将数据段选择子 PROT_MODE_DSEG 的值加载到寄存器 AX 中。 + 7c6d: 66 b8 10 00 mov $0x10,%ax + movw %ax, %ds # -> DS: Data Segment 将 AX 中的数据段选择子存入数据段寄存器 DS,设置数据段 + 7c71: 8e d8 mov %eax,%ds + movw %ax, %es # -> ES: Extra Segment 将 AX 中的数据段选择子存入附加段寄存器 ES,设置附加段 + 7c73: 8e c0 mov %eax,%es + movw %ax, %fs # -> FS 将 AX 中的数据段选择子存入段寄存器 FS,设置 FS 段。 + 7c75: 8e e0 mov %eax,%fs + movw %ax, %gs # -> GS 将 AX 中的数据段选择子存入段寄存器 GS + 7c77: 8e e8 mov %eax,%gs + movw %ax, %ss # -> SS: Stack Segment 将 AX 中的数据段选择子存入栈段寄存器 SS,设置栈段。 + 7c79: 8e d0 mov %eax,%ss + + # Set up the stack pointer and call into C. The stack region is from 0--start(0x7c00) + movl $0x0, %ebp + 7c7b: bd 00 00 00 00 mov $0x0,%ebp + movl $start, %esp + 7c80: bc 00 7c 00 00 mov $0x7c00,%esp + call bootmain + 7c85: e8 a1 00 00 00 call 7d2b + +00007c8a : + + # If bootmain returns (it shouldn't), loop. +spin: + jmp spin + 7c8a: eb fe jmp 7c8a + +Disassembly of section .text: + +00007c8c : +/* * + * readseg - read @count bytes at @offset from kernel into virtual address @va, + * might copy more than asked. + * */ +static void +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7c8c: 55 push %ebp + 7c8d: 89 e5 mov %esp,%ebp + 7c8f: 57 push %edi + uintptr_t end_va = va + count; + 7c90: 8d 3c 10 lea (%eax,%edx,1),%edi + + // round down to sector boundary + va -= offset % SECTSIZE; + 7c93: 89 ca mov %ecx,%edx +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7c95: 56 push %esi + va -= offset % SECTSIZE; + 7c96: 81 e2 ff 01 00 00 and $0x1ff,%edx + + // translate from bytes to sectors; kernel starts at sector 1 + uint32_t secno = (offset / SECTSIZE) + 1; + 7c9c: c1 e9 09 shr $0x9,%ecx + va -= offset % SECTSIZE; + 7c9f: 29 d0 sub %edx,%eax +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7ca1: 53 push %ebx + va -= offset % SECTSIZE; + 7ca2: 89 c6 mov %eax,%esi + uint32_t secno = (offset / SECTSIZE) + 1; + 7ca4: 8d 41 01 lea 0x1(%ecx),%eax +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7ca7: 83 ec 08 sub $0x8,%esp + uintptr_t end_va = va + count; + 7caa: 89 7d ec mov %edi,-0x14(%ebp) +static inline void invlpg(void *addr) __attribute__((always_inline)); + +static inline uint8_t +inb(uint16_t port) { + uint8_t data; + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 7cad: bb f7 01 00 00 mov $0x1f7,%ebx + uint32_t secno = (offset / SECTSIZE) + 1; + 7cb2: 89 45 f0 mov %eax,-0x10(%ebp) + + // If this is too slow, we could read lots of sectors at a time. + // We'd write more to memory than asked, but it doesn't matter -- + // we load in increasing order. + for (; va < end_va; va += SECTSIZE, secno ++) { + 7cb5: 3b 75 ec cmp -0x14(%ebp),%esi + 7cb8: 73 6a jae 7d24 + 7cba: 89 da mov %ebx,%edx + 7cbc: ec in (%dx),%al + while ((inb(0x1F7) & 0xC0) != 0x40) + 7cbd: 24 c0 and $0xc0,%al + 7cbf: 3c 40 cmp $0x40,%al + 7cc1: 75 f7 jne 7cba + : "memory", "cc"); +} + +static inline void +outb(uint16_t port, uint8_t data) { + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 7cc3: ba f2 01 00 00 mov $0x1f2,%edx + 7cc8: b0 01 mov $0x1,%al + 7cca: ee out %al,(%dx) + 7ccb: ba f3 01 00 00 mov $0x1f3,%edx + 7cd0: 8a 45 f0 mov -0x10(%ebp),%al + 7cd3: ee out %al,(%dx) + outb(0x1F4, (secno >> 8) & 0xFF); + 7cd4: 8b 45 f0 mov -0x10(%ebp),%eax + 7cd7: ba f4 01 00 00 mov $0x1f4,%edx + 7cdc: c1 e8 08 shr $0x8,%eax + 7cdf: ee out %al,(%dx) + outb(0x1F5, (secno >> 16) & 0xFF); + 7ce0: 8b 45 f0 mov -0x10(%ebp),%eax + 7ce3: ba f5 01 00 00 mov $0x1f5,%edx + 7ce8: c1 e8 10 shr $0x10,%eax + 7ceb: ee out %al,(%dx) + outb(0x1F6, ((secno >> 24) & 0xF) | 0xE0); + 7cec: 8b 45 f0 mov -0x10(%ebp),%eax + 7cef: ba f6 01 00 00 mov $0x1f6,%edx + 7cf4: c1 e8 18 shr $0x18,%eax + 7cf7: 24 0f and $0xf,%al + 7cf9: 0c e0 or $0xe0,%al + 7cfb: ee out %al,(%dx) + 7cfc: b0 20 mov $0x20,%al + 7cfe: 89 da mov %ebx,%edx + 7d00: ee out %al,(%dx) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 7d01: 89 da mov %ebx,%edx + 7d03: ec in (%dx),%al + while ((inb(0x1F7) & 0xC0) != 0x40) + 7d04: 24 c0 and $0xc0,%al + 7d06: 3c 40 cmp $0x40,%al + 7d08: 75 f7 jne 7d01 + asm volatile ( + 7d0a: 89 f7 mov %esi,%edi + 7d0c: b9 80 00 00 00 mov $0x80,%ecx + 7d11: ba f0 01 00 00 mov $0x1f0,%edx + 7d16: fc cld + 7d17: f2 6d repnz insl (%dx),%es:(%edi) + for (; va < end_va; va += SECTSIZE, secno ++) { + 7d19: ff 45 f0 incl -0x10(%ebp) + 7d1c: 81 c6 00 02 00 00 add $0x200,%esi + 7d22: eb 91 jmp 7cb5 + readsect((void *)va, secno); + } +} + 7d24: 58 pop %eax + 7d25: 5a pop %edx + 7d26: 5b pop %ebx + 7d27: 5e pop %esi + 7d28: 5f pop %edi + 7d29: 5d pop %ebp + 7d2a: c3 ret + +00007d2b : + +/* bootmain - the entry of bootloader */ +void +bootmain(void) { + 7d2b: 55 push %ebp + // read the 1st page off disk + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d2c: 31 c9 xor %ecx,%ecx +bootmain(void) { + 7d2e: 89 e5 mov %esp,%ebp + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d30: ba 00 10 00 00 mov $0x1000,%edx +bootmain(void) { + 7d35: 56 push %esi + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d36: b8 00 00 01 00 mov $0x10000,%eax +bootmain(void) { + 7d3b: 53 push %ebx + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d3c: e8 4b ff ff ff call 7c8c + + // is this a valid ELF? + if (ELFHDR->e_magic != ELF_MAGIC) { + 7d41: 81 3d 00 00 01 00 7f cmpl $0x464c457f,0x10000 + 7d48: 45 4c 46 + 7d4b: 75 3f jne 7d8c + } + + struct proghdr *ph, *eph; + + // load each program segment (ignores ph flags) + ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff); + 7d4d: a1 1c 00 01 00 mov 0x1001c,%eax + eph = ph + ELFHDR->e_phnum; + 7d52: 0f b7 35 2c 00 01 00 movzwl 0x1002c,%esi + ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff); + 7d59: 8d 98 00 00 01 00 lea 0x10000(%eax),%ebx + eph = ph + ELFHDR->e_phnum; + 7d5f: c1 e6 05 shl $0x5,%esi + 7d62: 01 de add %ebx,%esi + for (; ph < eph; ph ++) { + 7d64: 39 f3 cmp %esi,%ebx + 7d66: 73 18 jae 7d80 + readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); + 7d68: 8b 43 08 mov 0x8(%ebx),%eax + for (; ph < eph; ph ++) { + 7d6b: 83 c3 20 add $0x20,%ebx + readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); + 7d6e: 8b 4b e4 mov -0x1c(%ebx),%ecx + 7d71: 8b 53 f4 mov -0xc(%ebx),%edx + 7d74: 25 ff ff ff 00 and $0xffffff,%eax + 7d79: e8 0e ff ff ff call 7c8c + 7d7e: eb e4 jmp 7d64 + } + + // call the entry point from the ELF header + // note: does not return + ((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))(); + 7d80: a1 18 00 01 00 mov 0x10018,%eax + 7d85: 25 ff ff ff 00 and $0xffffff,%eax + 7d8a: ff d0 call *%eax +} + +static inline void +outw(uint16_t port, uint16_t data) { + asm volatile ("outw %0, %1" :: "a" (data), "d" (port) : "memory"); + 7d8c: ba 00 8a ff ff mov $0xffff8a00,%edx + 7d91: 89 d0 mov %edx,%eax + 7d93: 66 ef out %ax,(%dx) + 7d95: b8 00 8e ff ff mov $0xffff8e00,%eax + 7d9a: 66 ef out %ax,(%dx) + 7d9c: eb fe jmp 7d9c diff --git a/labcodes/lab3/obj/bootblock.o b/labcodes/lab3/obj/bootblock.o new file mode 100755 index 0000000000000000000000000000000000000000..3a1b3fbe654167065b4e9fc60067af253d069418 Binary files /dev/null and b/labcodes/lab3/obj/bootblock.o differ diff --git a/labcodes/lab3/obj/bootblock.out b/labcodes/lab3/obj/bootblock.out new file mode 100755 index 0000000000000000000000000000000000000000..4bbb6755d2289c820b5c874c4ecdfe0a93460849 Binary files /dev/null and b/labcodes/lab3/obj/bootblock.out differ diff --git a/labcodes/lab3/obj/kern/debug/kdebug.d b/labcodes/lab3/obj/kern/debug/kdebug.d new file mode 100644 index 0000000000000000000000000000000000000000..61cab792070b9ed485adef8cc68384e4978048db --- /dev/null +++ b/labcodes/lab3/obj/kern/debug/kdebug.d @@ -0,0 +1,5 @@ +obj/kern/debug/kdebug.o obj/kern/debug/kdebug.d: kern/debug/kdebug.c \ + libs/defs.h libs/x86.h kern/debug/stab.h libs/stdio.h libs/stdarg.h \ + libs/string.h kern/sync/sync.h kern/driver/intr.h kern/mm/mmu.h \ + kern/debug/kdebug.h kern/trap/trap.h kern/debug/kmonitor.h \ + kern/debug/assert.h diff --git a/labcodes/lab3/obj/kern/debug/kdebug.o b/labcodes/lab3/obj/kern/debug/kdebug.o new file mode 100644 index 0000000000000000000000000000000000000000..f31d934ae957860b65b5cd56231804fb083be26a Binary files /dev/null and b/labcodes/lab3/obj/kern/debug/kdebug.o differ diff --git a/labcodes/lab3/obj/kern/debug/kmonitor.d b/labcodes/lab3/obj/kern/debug/kmonitor.d new file mode 100644 index 0000000000000000000000000000000000000000..11c2af26a538a8fae989f8ac595edba72ba9fdb0 --- /dev/null +++ b/labcodes/lab3/obj/kern/debug/kmonitor.d @@ -0,0 +1,4 @@ +obj/kern/debug/kmonitor.o obj/kern/debug/kmonitor.d: \ + kern/debug/kmonitor.c libs/stdio.h libs/defs.h libs/stdarg.h \ + libs/string.h kern/mm/mmu.h kern/trap/trap.h kern/debug/kmonitor.h \ + kern/debug/kdebug.h diff --git a/labcodes/lab3/obj/kern/debug/kmonitor.o b/labcodes/lab3/obj/kern/debug/kmonitor.o new file mode 100644 index 0000000000000000000000000000000000000000..c017d8b574656587ef3fa54b8fb2a3eefa687c2e Binary files /dev/null and b/labcodes/lab3/obj/kern/debug/kmonitor.o differ diff --git a/labcodes/lab3/obj/kern/debug/panic.d b/labcodes/lab3/obj/kern/debug/panic.d new file mode 100644 index 0000000000000000000000000000000000000000..084ebb66bb08c9eec69fc03aac82918ef9b8ae9e --- /dev/null +++ b/labcodes/lab3/obj/kern/debug/panic.d @@ -0,0 +1,3 @@ +obj/kern/debug/panic.o obj/kern/debug/panic.d: kern/debug/panic.c \ + libs/defs.h libs/stdio.h libs/stdarg.h kern/driver/intr.h \ + kern/debug/kmonitor.h kern/trap/trap.h diff --git a/labcodes/lab3/obj/kern/debug/panic.o b/labcodes/lab3/obj/kern/debug/panic.o new file mode 100644 index 0000000000000000000000000000000000000000..b96eab54e3e8c064ff8fbc46dcf963bc98851cd9 Binary files /dev/null and b/labcodes/lab3/obj/kern/debug/panic.o differ diff --git a/labcodes/lab3/obj/kern/driver/clock.d b/labcodes/lab3/obj/kern/driver/clock.d new file mode 100644 index 0000000000000000000000000000000000000000..bdff3ffda4b8e673a5a6103b981d74b45f82c665 --- /dev/null +++ b/labcodes/lab3/obj/kern/driver/clock.d @@ -0,0 +1,3 @@ +obj/kern/driver/clock.o obj/kern/driver/clock.d: kern/driver/clock.c \ + libs/x86.h libs/defs.h kern/trap/trap.h libs/stdio.h libs/stdarg.h \ + kern/driver/picirq.h diff --git a/labcodes/lab3/obj/kern/driver/clock.o b/labcodes/lab3/obj/kern/driver/clock.o new file mode 100644 index 0000000000000000000000000000000000000000..621e9a16d966fcd3554e8567fa51fcae9eeb6ffb Binary files /dev/null and b/labcodes/lab3/obj/kern/driver/clock.o differ diff --git a/labcodes/lab3/obj/kern/driver/console.d b/labcodes/lab3/obj/kern/driver/console.d new file mode 100644 index 0000000000000000000000000000000000000000..196db2fc19aa221ae97806823bed746f0f23bce9 --- /dev/null +++ b/labcodes/lab3/obj/kern/driver/console.d @@ -0,0 +1,5 @@ +obj/kern/driver/console.o obj/kern/driver/console.d: \ + kern/driver/console.c libs/defs.h libs/x86.h libs/stdio.h libs/stdarg.h \ + libs/string.h kern/driver/kbdreg.h kern/driver/picirq.h kern/trap/trap.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/sync/sync.h \ + kern/driver/intr.h kern/mm/mmu.h diff --git a/labcodes/lab3/obj/kern/driver/console.o b/labcodes/lab3/obj/kern/driver/console.o new file mode 100644 index 0000000000000000000000000000000000000000..a99691ff3cde0d772f1625450f95aa3d06250c1c Binary files /dev/null and b/labcodes/lab3/obj/kern/driver/console.o differ diff --git a/labcodes/lab3/obj/kern/driver/ide.d b/labcodes/lab3/obj/kern/driver/ide.d new file mode 100644 index 0000000000000000000000000000000000000000..8b6e6cf004553e071f0200416015ca08654780c0 --- /dev/null +++ b/labcodes/lab3/obj/kern/driver/ide.d @@ -0,0 +1,4 @@ +obj/kern/driver/ide.o obj/kern/driver/ide.d: kern/driver/ide.c \ + libs/defs.h libs/stdio.h libs/stdarg.h kern/trap/trap.h \ + kern/driver/picirq.h kern/fs/fs.h kern/mm/mmu.h kern/driver/ide.h \ + libs/x86.h kern/debug/assert.h diff --git a/labcodes/lab3/obj/kern/driver/ide.o b/labcodes/lab3/obj/kern/driver/ide.o new file mode 100644 index 0000000000000000000000000000000000000000..ff1525f333f8d9f6f585ebfa29a2c7dd9ee8d1c5 Binary files /dev/null and b/labcodes/lab3/obj/kern/driver/ide.o differ diff --git a/labcodes/lab3/obj/kern/driver/intr.d b/labcodes/lab3/obj/kern/driver/intr.d new file mode 100644 index 0000000000000000000000000000000000000000..d0f9177c9eaeab75af2601390be216c9e6129ec8 --- /dev/null +++ b/labcodes/lab3/obj/kern/driver/intr.d @@ -0,0 +1,2 @@ +obj/kern/driver/intr.o obj/kern/driver/intr.d: kern/driver/intr.c \ + libs/x86.h libs/defs.h kern/driver/intr.h diff --git a/labcodes/lab3/obj/kern/driver/intr.o b/labcodes/lab3/obj/kern/driver/intr.o new file mode 100644 index 0000000000000000000000000000000000000000..ae30eda041cbc61fe690d88a4c1694d2a98aa496 Binary files /dev/null and b/labcodes/lab3/obj/kern/driver/intr.o differ diff --git a/labcodes/lab3/obj/kern/driver/picirq.d b/labcodes/lab3/obj/kern/driver/picirq.d new file mode 100644 index 0000000000000000000000000000000000000000..2de8ab1899f9f2be93bd10d4b213864803b6e5b9 --- /dev/null +++ b/labcodes/lab3/obj/kern/driver/picirq.d @@ -0,0 +1,2 @@ +obj/kern/driver/picirq.o obj/kern/driver/picirq.d: kern/driver/picirq.c \ + libs/defs.h libs/x86.h kern/driver/picirq.h diff --git a/labcodes/lab3/obj/kern/driver/picirq.o b/labcodes/lab3/obj/kern/driver/picirq.o new file mode 100644 index 0000000000000000000000000000000000000000..dfe6e15530ccd3816950c4451023e53b232bf6e7 Binary files /dev/null and b/labcodes/lab3/obj/kern/driver/picirq.o differ diff --git a/labcodes/lab3/obj/kern/fs/swapfs.d b/labcodes/lab3/obj/kern/fs/swapfs.d new file mode 100644 index 0000000000000000000000000000000000000000..4a52b61babd402a8d5ed913708ca9a63334e094f --- /dev/null +++ b/labcodes/lab3/obj/kern/fs/swapfs.d @@ -0,0 +1,5 @@ +obj/kern/fs/swapfs.o obj/kern/fs/swapfs.d: kern/fs/swapfs.c \ + kern/mm/swap.h libs/defs.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/mm/pmm.h kern/mm/mmu.h kern/debug/assert.h kern/mm/vmm.h \ + kern/sync/sync.h libs/x86.h kern/driver/intr.h kern/fs/swapfs.h \ + kern/fs/fs.h kern/driver/ide.h diff --git a/labcodes/lab3/obj/kern/fs/swapfs.o b/labcodes/lab3/obj/kern/fs/swapfs.o new file mode 100644 index 0000000000000000000000000000000000000000..1eb3e4ccafc93b7c30d28e16bb1ffe44df09d048 Binary files /dev/null and b/labcodes/lab3/obj/kern/fs/swapfs.o differ diff --git a/labcodes/lab3/obj/kern/init/entry.d b/labcodes/lab3/obj/kern/init/entry.d new file mode 100644 index 0000000000000000000000000000000000000000..c6b2d371d41761b6f69cfb032098321e2ec91c41 --- /dev/null +++ b/labcodes/lab3/obj/kern/init/entry.d @@ -0,0 +1,2 @@ +obj/kern/init/entry.o obj/kern/init/entry.d: kern/init/entry.S \ + kern/mm/mmu.h kern/mm/memlayout.h diff --git a/labcodes/lab3/obj/kern/init/entry.o b/labcodes/lab3/obj/kern/init/entry.o new file mode 100644 index 0000000000000000000000000000000000000000..f3e6b8d88e79e25140e965988ab31da6c8742a88 Binary files /dev/null and b/labcodes/lab3/obj/kern/init/entry.o differ diff --git a/labcodes/lab3/obj/kern/init/init.d b/labcodes/lab3/obj/kern/init/init.d new file mode 100644 index 0000000000000000000000000000000000000000..fa29b734865681712b9607990f2db52f2e34d23d --- /dev/null +++ b/labcodes/lab3/obj/kern/init/init.d @@ -0,0 +1,7 @@ +obj/kern/init/init.o obj/kern/init/init.d: kern/init/init.c libs/defs.h \ + libs/stdio.h libs/stdarg.h libs/string.h kern/driver/console.h \ + kern/debug/kdebug.h kern/trap/trap.h kern/driver/picirq.h \ + kern/driver/clock.h kern/driver/intr.h kern/mm/pmm.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/debug/assert.h \ + kern/mm/vmm.h kern/sync/sync.h libs/x86.h kern/driver/ide.h \ + kern/mm/swap.h kern/debug/kmonitor.h diff --git a/labcodes/lab3/obj/kern/init/init.o b/labcodes/lab3/obj/kern/init/init.o new file mode 100644 index 0000000000000000000000000000000000000000..c95a9509672f430cb47aeac1d2c39aabe12d5259 Binary files /dev/null and b/labcodes/lab3/obj/kern/init/init.o differ diff --git a/labcodes/lab3/obj/kern/libs/readline.d b/labcodes/lab3/obj/kern/libs/readline.d new file mode 100644 index 0000000000000000000000000000000000000000..656abf96b4c816940c02189bdc6490372dfc3c49 --- /dev/null +++ b/labcodes/lab3/obj/kern/libs/readline.d @@ -0,0 +1,2 @@ +obj/kern/libs/readline.o obj/kern/libs/readline.d: kern/libs/readline.c \ + libs/stdio.h libs/defs.h libs/stdarg.h diff --git a/labcodes/lab3/obj/kern/libs/readline.o b/labcodes/lab3/obj/kern/libs/readline.o new file mode 100644 index 0000000000000000000000000000000000000000..ff86b2d49d90136bac3939da6bc1486807bd25d6 Binary files /dev/null and b/labcodes/lab3/obj/kern/libs/readline.o differ diff --git a/labcodes/lab3/obj/kern/libs/stdio.d b/labcodes/lab3/obj/kern/libs/stdio.d new file mode 100644 index 0000000000000000000000000000000000000000..5e205ace5babb64121955473f1af46dbc8b90e51 --- /dev/null +++ b/labcodes/lab3/obj/kern/libs/stdio.d @@ -0,0 +1,2 @@ +obj/kern/libs/stdio.o obj/kern/libs/stdio.d: kern/libs/stdio.c \ + libs/defs.h libs/stdio.h libs/stdarg.h kern/driver/console.h diff --git a/labcodes/lab3/obj/kern/libs/stdio.o b/labcodes/lab3/obj/kern/libs/stdio.o new file mode 100644 index 0000000000000000000000000000000000000000..11b8d8ca228c5be48a85dacc97347b50c7b57379 Binary files /dev/null and b/labcodes/lab3/obj/kern/libs/stdio.o differ diff --git a/labcodes/lab3/obj/kern/mm/default_pmm.d b/labcodes/lab3/obj/kern/mm/default_pmm.d new file mode 100644 index 0000000000000000000000000000000000000000..8c415bfea7b5a19a92a142688e8c23e11882b103 --- /dev/null +++ b/labcodes/lab3/obj/kern/mm/default_pmm.d @@ -0,0 +1,4 @@ +obj/kern/mm/default_pmm.o obj/kern/mm/default_pmm.d: \ + kern/mm/default_pmm.c kern/mm/pmm.h libs/defs.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/debug/assert.h \ + libs/string.h kern/mm/default_pmm.h diff --git a/labcodes/lab3/obj/kern/mm/default_pmm.o b/labcodes/lab3/obj/kern/mm/default_pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..71db021d90bcd0f08069f6e017b5c61886df3746 Binary files /dev/null and b/labcodes/lab3/obj/kern/mm/default_pmm.o differ diff --git a/labcodes/lab3/obj/kern/mm/pmm.d b/labcodes/lab3/obj/kern/mm/pmm.d new file mode 100644 index 0000000000000000000000000000000000000000..79963553241432ba202581476c780118b827c480 --- /dev/null +++ b/labcodes/lab3/obj/kern/mm/pmm.d @@ -0,0 +1,5 @@ +obj/kern/mm/pmm.o obj/kern/mm/pmm.d: kern/mm/pmm.c libs/defs.h libs/x86.h \ + libs/stdio.h libs/stdarg.h libs/string.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/mm/pmm.h \ + kern/debug/assert.h kern/mm/default_pmm.h kern/sync/sync.h \ + kern/driver/intr.h libs/error.h kern/mm/swap.h kern/mm/vmm.h diff --git a/labcodes/lab3/obj/kern/mm/pmm.o b/labcodes/lab3/obj/kern/mm/pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..35df5403080613e5590e799b90ad3a66e206d154 Binary files /dev/null and b/labcodes/lab3/obj/kern/mm/pmm.o differ diff --git a/labcodes/lab3/obj/kern/mm/swap.d b/labcodes/lab3/obj/kern/mm/swap.d new file mode 100644 index 0000000000000000000000000000000000000000..d7a504bc1951721531714f2978f953446fcbaa96 --- /dev/null +++ b/labcodes/lab3/obj/kern/mm/swap.d @@ -0,0 +1,5 @@ +obj/kern/mm/swap.o obj/kern/mm/swap.d: kern/mm/swap.c kern/mm/swap.h \ + libs/defs.h kern/mm/memlayout.h libs/atomic.h libs/list.h kern/mm/pmm.h \ + kern/mm/mmu.h kern/debug/assert.h kern/mm/vmm.h kern/sync/sync.h \ + libs/x86.h kern/driver/intr.h kern/fs/swapfs.h kern/mm/swap_fifo.h \ + libs/stdio.h libs/stdarg.h libs/string.h diff --git a/labcodes/lab3/obj/kern/mm/swap.o b/labcodes/lab3/obj/kern/mm/swap.o new file mode 100644 index 0000000000000000000000000000000000000000..a9f55c090875722b697f9876956849faf4da72af Binary files /dev/null and b/labcodes/lab3/obj/kern/mm/swap.o differ diff --git a/labcodes/lab3/obj/kern/mm/swap_fifo.d b/labcodes/lab3/obj/kern/mm/swap_fifo.d new file mode 100644 index 0000000000000000000000000000000000000000..34b94a674a72f158f2f2b30007199719a50acb77 --- /dev/null +++ b/labcodes/lab3/obj/kern/mm/swap_fifo.d @@ -0,0 +1,5 @@ +obj/kern/mm/swap_fifo.o obj/kern/mm/swap_fifo.d: kern/mm/swap_fifo.c \ + libs/defs.h libs/x86.h libs/stdio.h libs/stdarg.h libs/string.h \ + kern/mm/swap.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/mm/pmm.h kern/mm/mmu.h kern/debug/assert.h kern/mm/vmm.h \ + kern/sync/sync.h kern/driver/intr.h kern/mm/swap_fifo.h diff --git a/labcodes/lab3/obj/kern/mm/swap_fifo.o b/labcodes/lab3/obj/kern/mm/swap_fifo.o new file mode 100644 index 0000000000000000000000000000000000000000..65e6f5a255e3b67f61cfb92a7a738a6c19e75c70 Binary files /dev/null and b/labcodes/lab3/obj/kern/mm/swap_fifo.o differ diff --git a/labcodes/lab3/obj/kern/mm/vmm.d b/labcodes/lab3/obj/kern/mm/vmm.d new file mode 100644 index 0000000000000000000000000000000000000000..76e91d773abeb5b0d0c6af29642aaca4d6ee9bba --- /dev/null +++ b/labcodes/lab3/obj/kern/mm/vmm.d @@ -0,0 +1,5 @@ +obj/kern/mm/vmm.o obj/kern/mm/vmm.d: kern/mm/vmm.c kern/mm/vmm.h \ + libs/defs.h libs/list.h kern/mm/memlayout.h libs/atomic.h \ + kern/sync/sync.h libs/x86.h kern/driver/intr.h kern/mm/mmu.h \ + libs/string.h kern/debug/assert.h libs/stdio.h libs/stdarg.h \ + libs/error.h kern/mm/pmm.h kern/mm/swap.h diff --git a/labcodes/lab3/obj/kern/mm/vmm.o b/labcodes/lab3/obj/kern/mm/vmm.o new file mode 100644 index 0000000000000000000000000000000000000000..7029430d4e557317fa4f0f57514dd47357b8bef6 Binary files /dev/null and b/labcodes/lab3/obj/kern/mm/vmm.o differ diff --git a/labcodes/lab3/obj/kern/trap/trap.d b/labcodes/lab3/obj/kern/trap/trap.d new file mode 100644 index 0000000000000000000000000000000000000000..be9945435a3123c44df650abd19e6ffc5c805611 --- /dev/null +++ b/labcodes/lab3/obj/kern/trap/trap.d @@ -0,0 +1,6 @@ +obj/kern/trap/trap.o obj/kern/trap/trap.d: kern/trap/trap.c libs/defs.h \ + kern/mm/mmu.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/driver/clock.h kern/trap/trap.h libs/x86.h libs/stdio.h \ + libs/stdarg.h kern/debug/assert.h kern/driver/console.h kern/mm/vmm.h \ + kern/sync/sync.h kern/driver/intr.h kern/mm/swap.h kern/mm/pmm.h \ + kern/debug/kdebug.h diff --git a/labcodes/lab3/obj/kern/trap/trap.o b/labcodes/lab3/obj/kern/trap/trap.o new file mode 100644 index 0000000000000000000000000000000000000000..fd575bf936a817d7f83177174d8b3ac9feb95d74 Binary files /dev/null and b/labcodes/lab3/obj/kern/trap/trap.o differ diff --git a/labcodes/lab3/obj/kern/trap/trapentry.d b/labcodes/lab3/obj/kern/trap/trapentry.d new file mode 100644 index 0000000000000000000000000000000000000000..f37d596cc0396e7d31650d6b287624a3bdcdfdbb --- /dev/null +++ b/labcodes/lab3/obj/kern/trap/trapentry.d @@ -0,0 +1,2 @@ +obj/kern/trap/trapentry.o obj/kern/trap/trapentry.d: \ + kern/trap/trapentry.S kern/mm/memlayout.h diff --git a/labcodes/lab3/obj/kern/trap/trapentry.o b/labcodes/lab3/obj/kern/trap/trapentry.o new file mode 100644 index 0000000000000000000000000000000000000000..18b723b0031b8944bd30b588f195e7886bb9701a Binary files /dev/null and b/labcodes/lab3/obj/kern/trap/trapentry.o differ diff --git a/labcodes/lab3/obj/kern/trap/vectors.d b/labcodes/lab3/obj/kern/trap/vectors.d new file mode 100644 index 0000000000000000000000000000000000000000..e5813e7765cbb429b0beea10b102bb5b7897e374 --- /dev/null +++ b/labcodes/lab3/obj/kern/trap/vectors.d @@ -0,0 +1 @@ +obj/kern/trap/vectors.o obj/kern/trap/vectors.d: kern/trap/vectors.S diff --git a/labcodes/lab3/obj/kern/trap/vectors.o b/labcodes/lab3/obj/kern/trap/vectors.o new file mode 100644 index 0000000000000000000000000000000000000000..e26010ff7929b1fff17a17164debfcc5c374b959 Binary files /dev/null and b/labcodes/lab3/obj/kern/trap/vectors.o differ diff --git a/labcodes/lab3/obj/kernel.asm b/labcodes/lab3/obj/kernel.asm new file mode 100644 index 0000000000000000000000000000000000000000..485bab553f73d711309f2e732d202112933622e5 --- /dev/null +++ b/labcodes/lab3/obj/kernel.asm @@ -0,0 +1,17007 @@ + +bin/kernel: file format elf32-i386 + + +Disassembly of section .text: + +c0100000 : + +.text +.globl kern_entry +kern_entry: + # load pa of boot pgdir + movl $REALLOC(__boot_pgdir), %eax +c0100000: b8 00 30 12 00 mov $0x123000,%eax + movl %eax, %cr3 +c0100005: 0f 22 d8 mov %eax,%cr3 + + # enable paging + movl %cr0, %eax +c0100008: 0f 20 c0 mov %cr0,%eax + orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax +c010000b: 0d 2f 00 05 80 or $0x8005002f,%eax + andl $~(CR0_TS | CR0_EM), %eax +c0100010: 83 e0 f3 and $0xfffffff3,%eax + movl %eax, %cr0 +c0100013: 0f 22 c0 mov %eax,%cr0 + + # update eip + # now, eip = 0x1..... + leal next, %eax +c0100016: 8d 05 1e 00 10 c0 lea 0xc010001e,%eax + # set eip = KERNBASE + 0x1..... + jmp *%eax +c010001c: ff e0 jmp *%eax + +c010001e : +next: + + # unmap va 0 ~ 4M, it's temporary mapping + xorl %eax, %eax +c010001e: 31 c0 xor %eax,%eax + movl %eax, __boot_pgdir +c0100020: a3 00 30 12 c0 mov %eax,0xc0123000 + + # set ebp, esp + movl $0x0, %ebp +c0100025: bd 00 00 00 00 mov $0x0,%ebp + # the kernel stack region is from bootstack -- bootstacktop, + # the kernel stack size is KSTACKSIZE (8KB)defined in memlayout.h + movl $bootstacktop, %esp +c010002a: bc 00 20 12 c0 mov $0xc0122000,%esp + # now kernel stack is ready , call the first C function + call kern_init +c010002f: e8 02 00 00 00 call c0100036 + +c0100034 : + +# should never get here +spin: + jmp spin +c0100034: eb fe jmp c0100034 + +c0100036 : +int kern_init(void) __attribute__((noreturn)); +void grade_backtrace(void); +static void lab1_switch_test(void); + +int +kern_init(void) { +c0100036: 55 push %ebp +c0100037: 89 e5 mov %esp,%ebp +c0100039: 83 ec 28 sub $0x28,%esp + extern char edata[], end[]; //声明外部变量 edata 和 end + memset(edata, 0, end - edata); // 将数据段清零 +c010003c: b8 74 61 12 c0 mov $0xc0126174,%eax +c0100041: 2d 00 50 12 c0 sub $0xc0125000,%eax +c0100046: 89 44 24 08 mov %eax,0x8(%esp) +c010004a: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0100051: 00 +c0100052: c7 04 24 00 50 12 c0 movl $0xc0125000,(%esp) +c0100059: e8 70 8b 00 00 call c0108bce + + cons_init(); // init the console 初始化控制台 +c010005e: e8 51 15 00 00 call c01015b4 + + const char *message = "(THU.CST) os is loading ..."; +c0100063: c7 45 f4 60 8d 10 c0 movl $0xc0108d60,-0xc(%ebp) + cprintf("%s\n\n", message);// 将消息输出到控制台 +c010006a: 8b 45 f4 mov -0xc(%ebp),%eax +c010006d: 89 44 24 04 mov %eax,0x4(%esp) +c0100071: c7 04 24 7c 8d 10 c0 movl $0xc0108d7c,(%esp) +c0100078: e8 f8 02 00 00 call c0100375 + + print_kerninfo();// 输出内核信息的函数 +c010007d: e8 16 08 00 00 call c0100898 + + grade_backtrace(); //调用回溯函数,通常用于调试,显示函数调用栈。 +c0100082: e8 a4 00 00 00 call c010012b + + pmm_init(); // init physical memory management初始化物理内存管理 +c0100087: e8 e9 4d 00 00 call c0104e75 + + pic_init(); // init interrupt controller初始化可编程中断控制器 +c010008c: e8 01 1f 00 00 call c0101f92 + idt_init(); // init interrupt descriptor table初始化中断描述符表 +c0100091: e8 65 20 00 00 call c01020fb + + vmm_init(); // init virtual memory management 初始化虚拟内存管理 +c0100096: e8 83 75 00 00 call c010761e + + ide_init(); // init ide devices初始化IDE设备 +c010009b: e8 4e 16 00 00 call c01016ee + swap_init(); // init swap 初始化交换分区 +c01000a0: e8 4f 61 00 00 call c01061f4 + + clock_init(); // init clock interrupt 初始化时钟中断 +c01000a5: e8 69 0c 00 00 call c0100d13 + intr_enable(); // enable irq interrupt启用中断 +c01000aa: e8 41 1e 00 00 call c0101ef0 + + //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() + // user/kernel mode switch test + lab1_switch_test(); +c01000af: e8 76 01 00 00 call c010022a + + /* do nothing */ + while (1); +c01000b4: eb fe jmp c01000b4 + +c01000b6 : +} + +//不进行内联的回溯函数,调用 mon_backtrace 显示当前的调用栈。 +void __attribute__((noinline)) +grade_backtrace2(int arg0, int arg1, int arg2, int arg3) { +c01000b6: 55 push %ebp +c01000b7: 89 e5 mov %esp,%ebp +c01000b9: 83 ec 18 sub $0x18,%esp + mon_backtrace(0, NULL, NULL); +c01000bc: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01000c3: 00 +c01000c4: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01000cb: 00 +c01000cc: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c01000d3: e8 56 0b 00 00 call c0100c2e +} +c01000d8: 90 nop +c01000d9: 89 ec mov %ebp,%esp +c01000db: 5d pop %ebp +c01000dc: c3 ret + +c01000dd : +//不进行内联的回溯函数,传递参数到 grade_backtrace2 +void __attribute__((noinline)) +grade_backtrace1(int arg0, int arg1) { +c01000dd: 55 push %ebp +c01000de: 89 e5 mov %esp,%ebp +c01000e0: 83 ec 18 sub $0x18,%esp +c01000e3: 89 5d fc mov %ebx,-0x4(%ebp) + grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1); +c01000e6: 8d 4d 0c lea 0xc(%ebp),%ecx +c01000e9: 8b 55 0c mov 0xc(%ebp),%edx +c01000ec: 8d 5d 08 lea 0x8(%ebp),%ebx +c01000ef: 8b 45 08 mov 0x8(%ebp),%eax +c01000f2: 89 4c 24 0c mov %ecx,0xc(%esp) +c01000f6: 89 54 24 08 mov %edx,0x8(%esp) +c01000fa: 89 5c 24 04 mov %ebx,0x4(%esp) +c01000fe: 89 04 24 mov %eax,(%esp) +c0100101: e8 b0 ff ff ff call c01000b6 +} +c0100106: 90 nop +c0100107: 8b 5d fc mov -0x4(%ebp),%ebx +c010010a: 89 ec mov %ebp,%esp +c010010c: 5d pop %ebp +c010010d: c3 ret + +c010010e : +//不进行内联的回溯函数,传递参数到 grade_backtrace1 +void __attribute__((noinline)) +grade_backtrace0(int arg0, int arg1, int arg2) { +c010010e: 55 push %ebp +c010010f: 89 e5 mov %esp,%ebp +c0100111: 83 ec 18 sub $0x18,%esp + grade_backtrace1(arg0, arg2); +c0100114: 8b 45 10 mov 0x10(%ebp),%eax +c0100117: 89 44 24 04 mov %eax,0x4(%esp) +c010011b: 8b 45 08 mov 0x8(%ebp),%eax +c010011e: 89 04 24 mov %eax,(%esp) +c0100121: e8 b7 ff ff ff call c01000dd +} +c0100126: 90 nop +c0100127: 89 ec mov %ebp,%esp +c0100129: 5d pop %ebp +c010012a: c3 ret + +c010012b : +//触发回溯的起始点,传递初始化函数地址。 +void +grade_backtrace(void) { +c010012b: 55 push %ebp +c010012c: 89 e5 mov %esp,%ebp +c010012e: 83 ec 18 sub $0x18,%esp + grade_backtrace0(0, (int)kern_init, 0xffff0000); +c0100131: b8 36 00 10 c0 mov $0xc0100036,%eax +c0100136: c7 44 24 08 00 00 ff movl $0xffff0000,0x8(%esp) +c010013d: ff +c010013e: 89 44 24 04 mov %eax,0x4(%esp) +c0100142: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100149: e8 c0 ff ff ff call c010010e +} +c010014e: 90 nop +c010014f: 89 ec mov %ebp,%esp +c0100151: 5d pop %ebp +c0100152: c3 ret + +c0100153 : +//打印当前的段寄存器状态。 +static void +lab1_print_cur_status(void) { +c0100153: 55 push %ebp +c0100154: 89 e5 mov %esp,%ebp +c0100156: 83 ec 28 sub $0x28,%esp + static int round = 0; + uint16_t reg1, reg2, reg3, reg4; + //嵌入汇编代码,确保编译器不优化这些代码。 + asm volatile ( +c0100159: 8c 4d f6 mov %cs,-0xa(%ebp) +c010015c: 8c 5d f4 mov %ds,-0xc(%ebp) +c010015f: 8c 45 f2 mov %es,-0xe(%ebp) +c0100162: 8c 55 f0 mov %ss,-0x10(%ebp) + "mov %%cs, %0;"// 将当前代码段寄存器的值移动到 reg1 + "mov %%ds, %1;" + "mov %%es, %2;" + "mov %%ss, %3;" + : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4)); + cprintf("%d: @ring %d\n", round, reg1 & 3);//打印当前的 round、权限级(ring)和各段寄存器的值。 +c0100165: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100169: 83 e0 03 and $0x3,%eax +c010016c: 89 c2 mov %eax,%edx +c010016e: a1 00 50 12 c0 mov 0xc0125000,%eax +c0100173: 89 54 24 08 mov %edx,0x8(%esp) +c0100177: 89 44 24 04 mov %eax,0x4(%esp) +c010017b: c7 04 24 81 8d 10 c0 movl $0xc0108d81,(%esp) +c0100182: e8 ee 01 00 00 call c0100375 + cprintf("%d: cs = %x\n", round, reg1); +c0100187: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010018b: 89 c2 mov %eax,%edx +c010018d: a1 00 50 12 c0 mov 0xc0125000,%eax +c0100192: 89 54 24 08 mov %edx,0x8(%esp) +c0100196: 89 44 24 04 mov %eax,0x4(%esp) +c010019a: c7 04 24 8f 8d 10 c0 movl $0xc0108d8f,(%esp) +c01001a1: e8 cf 01 00 00 call c0100375 + cprintf("%d: ds = %x\n", round, reg2); +c01001a6: 0f b7 45 f4 movzwl -0xc(%ebp),%eax +c01001aa: 89 c2 mov %eax,%edx +c01001ac: a1 00 50 12 c0 mov 0xc0125000,%eax +c01001b1: 89 54 24 08 mov %edx,0x8(%esp) +c01001b5: 89 44 24 04 mov %eax,0x4(%esp) +c01001b9: c7 04 24 9d 8d 10 c0 movl $0xc0108d9d,(%esp) +c01001c0: e8 b0 01 00 00 call c0100375 + cprintf("%d: es = %x\n", round, reg3); +c01001c5: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c01001c9: 89 c2 mov %eax,%edx +c01001cb: a1 00 50 12 c0 mov 0xc0125000,%eax +c01001d0: 89 54 24 08 mov %edx,0x8(%esp) +c01001d4: 89 44 24 04 mov %eax,0x4(%esp) +c01001d8: c7 04 24 ab 8d 10 c0 movl $0xc0108dab,(%esp) +c01001df: e8 91 01 00 00 call c0100375 + cprintf("%d: ss = %x\n", round, reg4); +c01001e4: 0f b7 45 f0 movzwl -0x10(%ebp),%eax +c01001e8: 89 c2 mov %eax,%edx +c01001ea: a1 00 50 12 c0 mov 0xc0125000,%eax +c01001ef: 89 54 24 08 mov %edx,0x8(%esp) +c01001f3: 89 44 24 04 mov %eax,0x4(%esp) +c01001f7: c7 04 24 b9 8d 10 c0 movl $0xc0108db9,(%esp) +c01001fe: e8 72 01 00 00 call c0100375 + round ++;//将 round 增加1,以便每次调用时记录状态。 +c0100203: a1 00 50 12 c0 mov 0xc0125000,%eax +c0100208: 40 inc %eax +c0100209: a3 00 50 12 c0 mov %eax,0xc0125000 +} +c010020e: 90 nop +c010020f: 89 ec mov %ebp,%esp +c0100211: 5d pop %ebp +c0100212: c3 ret + +c0100213 : + +static void +lab1_switch_to_user(void) { +c0100213: 55 push %ebp +c0100214: 89 e5 mov %esp,%ebp + // 从内核模式切换到用户模式 + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100216: 83 ec 08 sub $0x8,%esp +c0100219: cd 78 int $0x78 +c010021b: 89 ec mov %ebp,%esp + "int %0 \n"//通过触发一个中断,将控制权转移到内核,切换到用户模式。 + "movl %%ebp, %%esp"// 将基指针(EBP)值移动到堆栈指针(ESP),恢复堆栈指针。 + : + : "i"(T_SWITCH_TOU)//T_SWITCH_TOU是一个常量,表示切换到用户态的中断号。传入常量 T_SWITCH_TOU + ); +} +c010021d: 90 nop +c010021e: 5d pop %ebp +c010021f: c3 ret + +c0100220 : + +static void +lab1_switch_to_kernel(void) { +c0100220: 55 push %ebp +c0100221: 89 e5 mov %esp,%ebp + // 从用户模式切换到内核模式 + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100223: cd 79 int $0x79 +c0100225: 89 ec mov %ebp,%esp + "int %0 \n"// 同样触发中断,这里用的是 T_SWITCH_TOK,从用户态切换回内核态。 + "movl %%ebp, %%esp \n"//恢复堆栈指针 + : + : "i"(T_SWITCH_TOK)//传入常量 T_SWITCH_TOU + ); +} +c0100227: 90 nop +c0100228: 5d pop %ebp +c0100229: c3 ret + +c010022a : + +//测试用户模式和内核模式切换。 +//调用 lab1_print_cur_status 打印当前状态,进行模式切换,然后再次打印状态。 +static void +lab1_switch_test(void) { +c010022a: 55 push %ebp +c010022b: 89 e5 mov %esp,%ebp +c010022d: 83 ec 18 sub $0x18,%esp + lab1_print_cur_status(); +c0100230: e8 1e ff ff ff call c0100153 + cprintf("+++ switch to user mode +++\n"); +c0100235: c7 04 24 c8 8d 10 c0 movl $0xc0108dc8,(%esp) +c010023c: e8 34 01 00 00 call c0100375 + lab1_switch_to_user(); +c0100241: e8 cd ff ff ff call c0100213 + lab1_print_cur_status(); +c0100246: e8 08 ff ff ff call c0100153 + cprintf("+++ switch to kernel mode +++\n"); +c010024b: c7 04 24 e8 8d 10 c0 movl $0xc0108de8,(%esp) +c0100252: e8 1e 01 00 00 call c0100375 + lab1_switch_to_kernel(); +c0100257: e8 c4 ff ff ff call c0100220 + lab1_print_cur_status(); +c010025c: e8 f2 fe ff ff call c0100153 +} +c0100261: 90 nop +c0100262: 89 ec mov %ebp,%esp +c0100264: 5d pop %ebp +c0100265: c3 ret + +c0100266 : + * The readline() function returns the text of the line read. If some errors + * are happened, NULL is returned. The return value is a global variable, + * thus it should be copied before it is used. + * */ +char * +readline(const char *prompt) { +c0100266: 55 push %ebp +c0100267: 89 e5 mov %esp,%ebp +c0100269: 83 ec 28 sub $0x28,%esp + if (prompt != NULL) { +c010026c: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100270: 74 13 je c0100285 + cprintf("%s", prompt); +c0100272: 8b 45 08 mov 0x8(%ebp),%eax +c0100275: 89 44 24 04 mov %eax,0x4(%esp) +c0100279: c7 04 24 07 8e 10 c0 movl $0xc0108e07,(%esp) +c0100280: e8 f0 00 00 00 call c0100375 + } + int i = 0, c; +c0100285: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + c = getchar(); +c010028c: e8 73 01 00 00 call c0100404 +c0100291: 89 45 f0 mov %eax,-0x10(%ebp) + if (c < 0) { +c0100294: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0100298: 79 07 jns c01002a1 + return NULL; +c010029a: b8 00 00 00 00 mov $0x0,%eax +c010029f: eb 78 jmp c0100319 + } + else if (c >= ' ' && i < BUFSIZE - 1) { +c01002a1: 83 7d f0 1f cmpl $0x1f,-0x10(%ebp) +c01002a5: 7e 28 jle c01002cf +c01002a7: 81 7d f4 fe 03 00 00 cmpl $0x3fe,-0xc(%ebp) +c01002ae: 7f 1f jg c01002cf + cputchar(c); +c01002b0: 8b 45 f0 mov -0x10(%ebp),%eax +c01002b3: 89 04 24 mov %eax,(%esp) +c01002b6: e8 e2 00 00 00 call c010039d + buf[i ++] = c; +c01002bb: 8b 45 f4 mov -0xc(%ebp),%eax +c01002be: 8d 50 01 lea 0x1(%eax),%edx +c01002c1: 89 55 f4 mov %edx,-0xc(%ebp) +c01002c4: 8b 55 f0 mov -0x10(%ebp),%edx +c01002c7: 88 90 20 50 12 c0 mov %dl,-0x3fedafe0(%eax) +c01002cd: eb 45 jmp c0100314 + } + else if (c == '\b' && i > 0) { +c01002cf: 83 7d f0 08 cmpl $0x8,-0x10(%ebp) +c01002d3: 75 16 jne c01002eb +c01002d5: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01002d9: 7e 10 jle c01002eb + cputchar(c); +c01002db: 8b 45 f0 mov -0x10(%ebp),%eax +c01002de: 89 04 24 mov %eax,(%esp) +c01002e1: e8 b7 00 00 00 call c010039d + i --; +c01002e6: ff 4d f4 decl -0xc(%ebp) +c01002e9: eb 29 jmp c0100314 + } + else if (c == '\n' || c == '\r') { +c01002eb: 83 7d f0 0a cmpl $0xa,-0x10(%ebp) +c01002ef: 74 06 je c01002f7 +c01002f1: 83 7d f0 0d cmpl $0xd,-0x10(%ebp) +c01002f5: 75 95 jne c010028c + cputchar(c); +c01002f7: 8b 45 f0 mov -0x10(%ebp),%eax +c01002fa: 89 04 24 mov %eax,(%esp) +c01002fd: e8 9b 00 00 00 call c010039d + buf[i] = '\0'; +c0100302: 8b 45 f4 mov -0xc(%ebp),%eax +c0100305: 05 20 50 12 c0 add $0xc0125020,%eax +c010030a: c6 00 00 movb $0x0,(%eax) + return buf; +c010030d: b8 20 50 12 c0 mov $0xc0125020,%eax +c0100312: eb 05 jmp c0100319 + c = getchar(); +c0100314: e9 73 ff ff ff jmp c010028c + } + } +} +c0100319: 89 ec mov %ebp,%esp +c010031b: 5d pop %ebp +c010031c: c3 ret + +c010031d : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { +c010031d: 55 push %ebp +c010031e: 89 e5 mov %esp,%ebp +c0100320: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c0100323: 8b 45 08 mov 0x8(%ebp),%eax +c0100326: 89 04 24 mov %eax,(%esp) +c0100329: e8 b5 12 00 00 call c01015e3 + (*cnt) ++; +c010032e: 8b 45 0c mov 0xc(%ebp),%eax +c0100331: 8b 00 mov (%eax),%eax +c0100333: 8d 50 01 lea 0x1(%eax),%edx +c0100336: 8b 45 0c mov 0xc(%ebp),%eax +c0100339: 89 10 mov %edx,(%eax) +} +c010033b: 90 nop +c010033c: 89 ec mov %ebp,%esp +c010033e: 5d pop %ebp +c010033f: c3 ret + +c0100340 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { +c0100340: 55 push %ebp +c0100341: 89 e5 mov %esp,%ebp +c0100343: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c0100346: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); +c010034d: 8b 45 0c mov 0xc(%ebp),%eax +c0100350: 89 44 24 0c mov %eax,0xc(%esp) +c0100354: 8b 45 08 mov 0x8(%ebp),%eax +c0100357: 89 44 24 08 mov %eax,0x8(%esp) +c010035b: 8d 45 f4 lea -0xc(%ebp),%eax +c010035e: 89 44 24 04 mov %eax,0x4(%esp) +c0100362: c7 04 24 1d 03 10 c0 movl $0xc010031d,(%esp) +c0100369: e8 b3 7f 00 00 call c0108321 + return cnt; +c010036e: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100371: 89 ec mov %ebp,%esp +c0100373: 5d pop %ebp +c0100374: c3 ret + +c0100375 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { +c0100375: 55 push %ebp +c0100376: 89 e5 mov %esp,%ebp +c0100378: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c010037b: 8d 45 0c lea 0xc(%ebp),%eax +c010037e: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vcprintf(fmt, ap); +c0100381: 8b 45 f0 mov -0x10(%ebp),%eax +c0100384: 89 44 24 04 mov %eax,0x4(%esp) +c0100388: 8b 45 08 mov 0x8(%ebp),%eax +c010038b: 89 04 24 mov %eax,(%esp) +c010038e: e8 ad ff ff ff call c0100340 +c0100393: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c0100396: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100399: 89 ec mov %ebp,%esp +c010039b: 5d pop %ebp +c010039c: c3 ret + +c010039d : + +/* cputchar - writes a single character to stdout */ +void +cputchar(int c) { +c010039d: 55 push %ebp +c010039e: 89 e5 mov %esp,%ebp +c01003a0: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c01003a3: 8b 45 08 mov 0x8(%ebp),%eax +c01003a6: 89 04 24 mov %eax,(%esp) +c01003a9: e8 35 12 00 00 call c01015e3 +} +c01003ae: 90 nop +c01003af: 89 ec mov %ebp,%esp +c01003b1: 5d pop %ebp +c01003b2: c3 ret + +c01003b3 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { +c01003b3: 55 push %ebp +c01003b4: 89 e5 mov %esp,%ebp +c01003b6: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c01003b9: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { +c01003c0: eb 13 jmp c01003d5 + cputch(c, &cnt); +c01003c2: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c01003c6: 8d 55 f0 lea -0x10(%ebp),%edx +c01003c9: 89 54 24 04 mov %edx,0x4(%esp) +c01003cd: 89 04 24 mov %eax,(%esp) +c01003d0: e8 48 ff ff ff call c010031d + while ((c = *str ++) != '\0') { +c01003d5: 8b 45 08 mov 0x8(%ebp),%eax +c01003d8: 8d 50 01 lea 0x1(%eax),%edx +c01003db: 89 55 08 mov %edx,0x8(%ebp) +c01003de: 0f b6 00 movzbl (%eax),%eax +c01003e1: 88 45 f7 mov %al,-0x9(%ebp) +c01003e4: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) +c01003e8: 75 d8 jne c01003c2 + } + cputch('\n', &cnt); +c01003ea: 8d 45 f0 lea -0x10(%ebp),%eax +c01003ed: 89 44 24 04 mov %eax,0x4(%esp) +c01003f1: c7 04 24 0a 00 00 00 movl $0xa,(%esp) +c01003f8: e8 20 ff ff ff call c010031d + return cnt; +c01003fd: 8b 45 f0 mov -0x10(%ebp),%eax +} +c0100400: 89 ec mov %ebp,%esp +c0100402: 5d pop %ebp +c0100403: c3 ret + +c0100404 : + +/* getchar - reads a single non-zero character from stdin */ +int +getchar(void) { +c0100404: 55 push %ebp +c0100405: 89 e5 mov %esp,%ebp +c0100407: 83 ec 18 sub $0x18,%esp + int c; + while ((c = cons_getc()) == 0) +c010040a: 90 nop +c010040b: e8 12 12 00 00 call c0101622 +c0100410: 89 45 f4 mov %eax,-0xc(%ebp) +c0100413: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0100417: 74 f2 je c010040b + /* do nothing */; + return c; +c0100419: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010041c: 89 ec mov %ebp,%esp +c010041e: 5d pop %ebp +c010041f: c3 ret + +c0100420 : + * stab_binsearch(stabs, &left, &right, N_SO, 0xf0100184); + * will exit setting left = 118, right = 554. + * */ +static void +stab_binsearch(const struct stab *stabs, int *region_left, int *region_right, + int type, uintptr_t addr) { +c0100420: 55 push %ebp +c0100421: 89 e5 mov %esp,%ebp +c0100423: 83 ec 20 sub $0x20,%esp + int l = *region_left, r = *region_right, any_matches = 0; +c0100426: 8b 45 0c mov 0xc(%ebp),%eax +c0100429: 8b 00 mov (%eax),%eax +c010042b: 89 45 fc mov %eax,-0x4(%ebp) +c010042e: 8b 45 10 mov 0x10(%ebp),%eax +c0100431: 8b 00 mov (%eax),%eax +c0100433: 89 45 f8 mov %eax,-0x8(%ebp) +c0100436: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + + while (l <= r) { +c010043d: e9 ca 00 00 00 jmp c010050c + int true_m = (l + r) / 2, m = true_m; +c0100442: 8b 55 fc mov -0x4(%ebp),%edx +c0100445: 8b 45 f8 mov -0x8(%ebp),%eax +c0100448: 01 d0 add %edx,%eax +c010044a: 89 c2 mov %eax,%edx +c010044c: c1 ea 1f shr $0x1f,%edx +c010044f: 01 d0 add %edx,%eax +c0100451: d1 f8 sar %eax +c0100453: 89 45 ec mov %eax,-0x14(%ebp) +c0100456: 8b 45 ec mov -0x14(%ebp),%eax +c0100459: 89 45 f0 mov %eax,-0x10(%ebp) + + // search for earliest stab with right type + while (m >= l && stabs[m].n_type != type) { +c010045c: eb 03 jmp c0100461 + m --; +c010045e: ff 4d f0 decl -0x10(%ebp) + while (m >= l && stabs[m].n_type != type) { +c0100461: 8b 45 f0 mov -0x10(%ebp),%eax +c0100464: 3b 45 fc cmp -0x4(%ebp),%eax +c0100467: 7c 1f jl c0100488 +c0100469: 8b 55 f0 mov -0x10(%ebp),%edx +c010046c: 89 d0 mov %edx,%eax +c010046e: 01 c0 add %eax,%eax +c0100470: 01 d0 add %edx,%eax +c0100472: c1 e0 02 shl $0x2,%eax +c0100475: 89 c2 mov %eax,%edx +c0100477: 8b 45 08 mov 0x8(%ebp),%eax +c010047a: 01 d0 add %edx,%eax +c010047c: 0f b6 40 04 movzbl 0x4(%eax),%eax +c0100480: 0f b6 c0 movzbl %al,%eax +c0100483: 39 45 14 cmp %eax,0x14(%ebp) +c0100486: 75 d6 jne c010045e + } + if (m < l) { // no match in [l, m] +c0100488: 8b 45 f0 mov -0x10(%ebp),%eax +c010048b: 3b 45 fc cmp -0x4(%ebp),%eax +c010048e: 7d 09 jge c0100499 + l = true_m + 1; +c0100490: 8b 45 ec mov -0x14(%ebp),%eax +c0100493: 40 inc %eax +c0100494: 89 45 fc mov %eax,-0x4(%ebp) + continue; +c0100497: eb 73 jmp c010050c + } + + // actual binary search + any_matches = 1; +c0100499: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) + if (stabs[m].n_value < addr) { +c01004a0: 8b 55 f0 mov -0x10(%ebp),%edx +c01004a3: 89 d0 mov %edx,%eax +c01004a5: 01 c0 add %eax,%eax +c01004a7: 01 d0 add %edx,%eax +c01004a9: c1 e0 02 shl $0x2,%eax +c01004ac: 89 c2 mov %eax,%edx +c01004ae: 8b 45 08 mov 0x8(%ebp),%eax +c01004b1: 01 d0 add %edx,%eax +c01004b3: 8b 40 08 mov 0x8(%eax),%eax +c01004b6: 39 45 18 cmp %eax,0x18(%ebp) +c01004b9: 76 11 jbe c01004cc + *region_left = m; +c01004bb: 8b 45 0c mov 0xc(%ebp),%eax +c01004be: 8b 55 f0 mov -0x10(%ebp),%edx +c01004c1: 89 10 mov %edx,(%eax) + l = true_m + 1; +c01004c3: 8b 45 ec mov -0x14(%ebp),%eax +c01004c6: 40 inc %eax +c01004c7: 89 45 fc mov %eax,-0x4(%ebp) +c01004ca: eb 40 jmp c010050c + } else if (stabs[m].n_value > addr) { +c01004cc: 8b 55 f0 mov -0x10(%ebp),%edx +c01004cf: 89 d0 mov %edx,%eax +c01004d1: 01 c0 add %eax,%eax +c01004d3: 01 d0 add %edx,%eax +c01004d5: c1 e0 02 shl $0x2,%eax +c01004d8: 89 c2 mov %eax,%edx +c01004da: 8b 45 08 mov 0x8(%ebp),%eax +c01004dd: 01 d0 add %edx,%eax +c01004df: 8b 40 08 mov 0x8(%eax),%eax +c01004e2: 39 45 18 cmp %eax,0x18(%ebp) +c01004e5: 73 14 jae c01004fb + *region_right = m - 1; +c01004e7: 8b 45 f0 mov -0x10(%ebp),%eax +c01004ea: 8d 50 ff lea -0x1(%eax),%edx +c01004ed: 8b 45 10 mov 0x10(%ebp),%eax +c01004f0: 89 10 mov %edx,(%eax) + r = m - 1; +c01004f2: 8b 45 f0 mov -0x10(%ebp),%eax +c01004f5: 48 dec %eax +c01004f6: 89 45 f8 mov %eax,-0x8(%ebp) +c01004f9: eb 11 jmp c010050c + } else { + // exact match for 'addr', but continue loop to find + // *region_right + *region_left = m; +c01004fb: 8b 45 0c mov 0xc(%ebp),%eax +c01004fe: 8b 55 f0 mov -0x10(%ebp),%edx +c0100501: 89 10 mov %edx,(%eax) + l = m; +c0100503: 8b 45 f0 mov -0x10(%ebp),%eax +c0100506: 89 45 fc mov %eax,-0x4(%ebp) + addr ++; +c0100509: ff 45 18 incl 0x18(%ebp) + while (l <= r) { +c010050c: 8b 45 fc mov -0x4(%ebp),%eax +c010050f: 3b 45 f8 cmp -0x8(%ebp),%eax +c0100512: 0f 8e 2a ff ff ff jle c0100442 + } + } + + if (!any_matches) { +c0100518: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010051c: 75 0f jne c010052d + *region_right = *region_left - 1; +c010051e: 8b 45 0c mov 0xc(%ebp),%eax +c0100521: 8b 00 mov (%eax),%eax +c0100523: 8d 50 ff lea -0x1(%eax),%edx +c0100526: 8b 45 10 mov 0x10(%ebp),%eax +c0100529: 89 10 mov %edx,(%eax) + l = *region_right; + for (; l > *region_left && stabs[l].n_type != type; l --) + /* do nothing */; + *region_left = l; + } +} +c010052b: eb 3e jmp c010056b + l = *region_right; +c010052d: 8b 45 10 mov 0x10(%ebp),%eax +c0100530: 8b 00 mov (%eax),%eax +c0100532: 89 45 fc mov %eax,-0x4(%ebp) + for (; l > *region_left && stabs[l].n_type != type; l --) +c0100535: eb 03 jmp c010053a +c0100537: ff 4d fc decl -0x4(%ebp) +c010053a: 8b 45 0c mov 0xc(%ebp),%eax +c010053d: 8b 00 mov (%eax),%eax +c010053f: 39 45 fc cmp %eax,-0x4(%ebp) +c0100542: 7e 1f jle c0100563 +c0100544: 8b 55 fc mov -0x4(%ebp),%edx +c0100547: 89 d0 mov %edx,%eax +c0100549: 01 c0 add %eax,%eax +c010054b: 01 d0 add %edx,%eax +c010054d: c1 e0 02 shl $0x2,%eax +c0100550: 89 c2 mov %eax,%edx +c0100552: 8b 45 08 mov 0x8(%ebp),%eax +c0100555: 01 d0 add %edx,%eax +c0100557: 0f b6 40 04 movzbl 0x4(%eax),%eax +c010055b: 0f b6 c0 movzbl %al,%eax +c010055e: 39 45 14 cmp %eax,0x14(%ebp) +c0100561: 75 d4 jne c0100537 + *region_left = l; +c0100563: 8b 45 0c mov 0xc(%ebp),%eax +c0100566: 8b 55 fc mov -0x4(%ebp),%edx +c0100569: 89 10 mov %edx,(%eax) +} +c010056b: 90 nop +c010056c: 89 ec mov %ebp,%esp +c010056e: 5d pop %ebp +c010056f: c3 ret + +c0100570 : + * the specified instruction address, @addr. Returns 0 if information + * was found, and negative if not. But even if it returns negative it + * has stored some information into '*info'. + * */ +int +debuginfo_eip(uintptr_t addr, struct eipdebuginfo *info) { +c0100570: 55 push %ebp +c0100571: 89 e5 mov %esp,%ebp +c0100573: 83 ec 58 sub $0x58,%esp + const struct stab *stabs, *stab_end; + const char *stabstr, *stabstr_end; + + info->eip_file = ""; +c0100576: 8b 45 0c mov 0xc(%ebp),%eax +c0100579: c7 00 0c 8e 10 c0 movl $0xc0108e0c,(%eax) + info->eip_line = 0; +c010057f: 8b 45 0c mov 0xc(%ebp),%eax +c0100582: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + info->eip_fn_name = ""; +c0100589: 8b 45 0c mov 0xc(%ebp),%eax +c010058c: c7 40 08 0c 8e 10 c0 movl $0xc0108e0c,0x8(%eax) + info->eip_fn_namelen = 9; +c0100593: 8b 45 0c mov 0xc(%ebp),%eax +c0100596: c7 40 0c 09 00 00 00 movl $0x9,0xc(%eax) + info->eip_fn_addr = addr; +c010059d: 8b 45 0c mov 0xc(%ebp),%eax +c01005a0: 8b 55 08 mov 0x8(%ebp),%edx +c01005a3: 89 50 10 mov %edx,0x10(%eax) + info->eip_fn_narg = 0; +c01005a6: 8b 45 0c mov 0xc(%ebp),%eax +c01005a9: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + + stabs = __STAB_BEGIN__; +c01005b0: c7 45 f4 ac ad 10 c0 movl $0xc010adac,-0xc(%ebp) + stab_end = __STAB_END__; +c01005b7: c7 45 f0 74 ae 11 c0 movl $0xc011ae74,-0x10(%ebp) + stabstr = __STABSTR_BEGIN__; +c01005be: c7 45 ec 75 ae 11 c0 movl $0xc011ae75,-0x14(%ebp) + stabstr_end = __STABSTR_END__; +c01005c5: c7 45 e8 ed fc 11 c0 movl $0xc011fced,-0x18(%ebp) + + // String table validity checks + if (stabstr_end <= stabstr || stabstr_end[-1] != 0) { +c01005cc: 8b 45 e8 mov -0x18(%ebp),%eax +c01005cf: 3b 45 ec cmp -0x14(%ebp),%eax +c01005d2: 76 0b jbe c01005df +c01005d4: 8b 45 e8 mov -0x18(%ebp),%eax +c01005d7: 48 dec %eax +c01005d8: 0f b6 00 movzbl (%eax),%eax +c01005db: 84 c0 test %al,%al +c01005dd: 74 0a je c01005e9 + return -1; +c01005df: b8 ff ff ff ff mov $0xffffffff,%eax +c01005e4: e9 ab 02 00 00 jmp c0100894 + // 'eip'. First, we find the basic source file containing 'eip'. + // Then, we look in that source file for the function. Then we look + // for the line number. + + // Search the entire set of stabs for the source file (type N_SO). + int lfile = 0, rfile = (stab_end - stabs) - 1; +c01005e9: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +c01005f0: 8b 45 f0 mov -0x10(%ebp),%eax +c01005f3: 2b 45 f4 sub -0xc(%ebp),%eax +c01005f6: c1 f8 02 sar $0x2,%eax +c01005f9: 69 c0 ab aa aa aa imul $0xaaaaaaab,%eax,%eax +c01005ff: 48 dec %eax +c0100600: 89 45 e0 mov %eax,-0x20(%ebp) + stab_binsearch(stabs, &lfile, &rfile, N_SO, addr); +c0100603: 8b 45 08 mov 0x8(%ebp),%eax +c0100606: 89 44 24 10 mov %eax,0x10(%esp) +c010060a: c7 44 24 0c 64 00 00 movl $0x64,0xc(%esp) +c0100611: 00 +c0100612: 8d 45 e0 lea -0x20(%ebp),%eax +c0100615: 89 44 24 08 mov %eax,0x8(%esp) +c0100619: 8d 45 e4 lea -0x1c(%ebp),%eax +c010061c: 89 44 24 04 mov %eax,0x4(%esp) +c0100620: 8b 45 f4 mov -0xc(%ebp),%eax +c0100623: 89 04 24 mov %eax,(%esp) +c0100626: e8 f5 fd ff ff call c0100420 + if (lfile == 0) +c010062b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010062e: 85 c0 test %eax,%eax +c0100630: 75 0a jne c010063c + return -1; +c0100632: b8 ff ff ff ff mov $0xffffffff,%eax +c0100637: e9 58 02 00 00 jmp c0100894 + + // Search within that file's stabs for the function definition + // (N_FUN). + int lfun = lfile, rfun = rfile; +c010063c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010063f: 89 45 dc mov %eax,-0x24(%ebp) +c0100642: 8b 45 e0 mov -0x20(%ebp),%eax +c0100645: 89 45 d8 mov %eax,-0x28(%ebp) + int lline, rline; + stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr); +c0100648: 8b 45 08 mov 0x8(%ebp),%eax +c010064b: 89 44 24 10 mov %eax,0x10(%esp) +c010064f: c7 44 24 0c 24 00 00 movl $0x24,0xc(%esp) +c0100656: 00 +c0100657: 8d 45 d8 lea -0x28(%ebp),%eax +c010065a: 89 44 24 08 mov %eax,0x8(%esp) +c010065e: 8d 45 dc lea -0x24(%ebp),%eax +c0100661: 89 44 24 04 mov %eax,0x4(%esp) +c0100665: 8b 45 f4 mov -0xc(%ebp),%eax +c0100668: 89 04 24 mov %eax,(%esp) +c010066b: e8 b0 fd ff ff call c0100420 + + if (lfun <= rfun) { +c0100670: 8b 55 dc mov -0x24(%ebp),%edx +c0100673: 8b 45 d8 mov -0x28(%ebp),%eax +c0100676: 39 c2 cmp %eax,%edx +c0100678: 7f 78 jg c01006f2 + // stabs[lfun] points to the function name + // in the string table, but check bounds just in case. + if (stabs[lfun].n_strx < stabstr_end - stabstr) { +c010067a: 8b 45 dc mov -0x24(%ebp),%eax +c010067d: 89 c2 mov %eax,%edx +c010067f: 89 d0 mov %edx,%eax +c0100681: 01 c0 add %eax,%eax +c0100683: 01 d0 add %edx,%eax +c0100685: c1 e0 02 shl $0x2,%eax +c0100688: 89 c2 mov %eax,%edx +c010068a: 8b 45 f4 mov -0xc(%ebp),%eax +c010068d: 01 d0 add %edx,%eax +c010068f: 8b 10 mov (%eax),%edx +c0100691: 8b 45 e8 mov -0x18(%ebp),%eax +c0100694: 2b 45 ec sub -0x14(%ebp),%eax +c0100697: 39 c2 cmp %eax,%edx +c0100699: 73 22 jae c01006bd + info->eip_fn_name = stabstr + stabs[lfun].n_strx; +c010069b: 8b 45 dc mov -0x24(%ebp),%eax +c010069e: 89 c2 mov %eax,%edx +c01006a0: 89 d0 mov %edx,%eax +c01006a2: 01 c0 add %eax,%eax +c01006a4: 01 d0 add %edx,%eax +c01006a6: c1 e0 02 shl $0x2,%eax +c01006a9: 89 c2 mov %eax,%edx +c01006ab: 8b 45 f4 mov -0xc(%ebp),%eax +c01006ae: 01 d0 add %edx,%eax +c01006b0: 8b 10 mov (%eax),%edx +c01006b2: 8b 45 ec mov -0x14(%ebp),%eax +c01006b5: 01 c2 add %eax,%edx +c01006b7: 8b 45 0c mov 0xc(%ebp),%eax +c01006ba: 89 50 08 mov %edx,0x8(%eax) + } + info->eip_fn_addr = stabs[lfun].n_value; +c01006bd: 8b 45 dc mov -0x24(%ebp),%eax +c01006c0: 89 c2 mov %eax,%edx +c01006c2: 89 d0 mov %edx,%eax +c01006c4: 01 c0 add %eax,%eax +c01006c6: 01 d0 add %edx,%eax +c01006c8: c1 e0 02 shl $0x2,%eax +c01006cb: 89 c2 mov %eax,%edx +c01006cd: 8b 45 f4 mov -0xc(%ebp),%eax +c01006d0: 01 d0 add %edx,%eax +c01006d2: 8b 50 08 mov 0x8(%eax),%edx +c01006d5: 8b 45 0c mov 0xc(%ebp),%eax +c01006d8: 89 50 10 mov %edx,0x10(%eax) + addr -= info->eip_fn_addr; +c01006db: 8b 45 0c mov 0xc(%ebp),%eax +c01006de: 8b 40 10 mov 0x10(%eax),%eax +c01006e1: 29 45 08 sub %eax,0x8(%ebp) + // Search within the function definition for the line number. + lline = lfun; +c01006e4: 8b 45 dc mov -0x24(%ebp),%eax +c01006e7: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfun; +c01006ea: 8b 45 d8 mov -0x28(%ebp),%eax +c01006ed: 89 45 d0 mov %eax,-0x30(%ebp) +c01006f0: eb 15 jmp c0100707 + } else { + // Couldn't find function stab! Maybe we're in an assembly + // file. Search the whole file for the line number. + info->eip_fn_addr = addr; +c01006f2: 8b 45 0c mov 0xc(%ebp),%eax +c01006f5: 8b 55 08 mov 0x8(%ebp),%edx +c01006f8: 89 50 10 mov %edx,0x10(%eax) + lline = lfile; +c01006fb: 8b 45 e4 mov -0x1c(%ebp),%eax +c01006fe: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfile; +c0100701: 8b 45 e0 mov -0x20(%ebp),%eax +c0100704: 89 45 d0 mov %eax,-0x30(%ebp) + } + info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name; +c0100707: 8b 45 0c mov 0xc(%ebp),%eax +c010070a: 8b 40 08 mov 0x8(%eax),%eax +c010070d: c7 44 24 04 3a 00 00 movl $0x3a,0x4(%esp) +c0100714: 00 +c0100715: 89 04 24 mov %eax,(%esp) +c0100718: e8 29 83 00 00 call c0108a46 +c010071d: 8b 55 0c mov 0xc(%ebp),%edx +c0100720: 8b 4a 08 mov 0x8(%edx),%ecx +c0100723: 29 c8 sub %ecx,%eax +c0100725: 89 c2 mov %eax,%edx +c0100727: 8b 45 0c mov 0xc(%ebp),%eax +c010072a: 89 50 0c mov %edx,0xc(%eax) + + // Search within [lline, rline] for the line number stab. + // If found, set info->eip_line to the right line number. + // If not found, return -1. + stab_binsearch(stabs, &lline, &rline, N_SLINE, addr); +c010072d: 8b 45 08 mov 0x8(%ebp),%eax +c0100730: 89 44 24 10 mov %eax,0x10(%esp) +c0100734: c7 44 24 0c 44 00 00 movl $0x44,0xc(%esp) +c010073b: 00 +c010073c: 8d 45 d0 lea -0x30(%ebp),%eax +c010073f: 89 44 24 08 mov %eax,0x8(%esp) +c0100743: 8d 45 d4 lea -0x2c(%ebp),%eax +c0100746: 89 44 24 04 mov %eax,0x4(%esp) +c010074a: 8b 45 f4 mov -0xc(%ebp),%eax +c010074d: 89 04 24 mov %eax,(%esp) +c0100750: e8 cb fc ff ff call c0100420 + if (lline <= rline) { +c0100755: 8b 55 d4 mov -0x2c(%ebp),%edx +c0100758: 8b 45 d0 mov -0x30(%ebp),%eax +c010075b: 39 c2 cmp %eax,%edx +c010075d: 7f 23 jg c0100782 + info->eip_line = stabs[rline].n_desc; +c010075f: 8b 45 d0 mov -0x30(%ebp),%eax +c0100762: 89 c2 mov %eax,%edx +c0100764: 89 d0 mov %edx,%eax +c0100766: 01 c0 add %eax,%eax +c0100768: 01 d0 add %edx,%eax +c010076a: c1 e0 02 shl $0x2,%eax +c010076d: 89 c2 mov %eax,%edx +c010076f: 8b 45 f4 mov -0xc(%ebp),%eax +c0100772: 01 d0 add %edx,%eax +c0100774: 0f b7 40 06 movzwl 0x6(%eax),%eax +c0100778: 89 c2 mov %eax,%edx +c010077a: 8b 45 0c mov 0xc(%ebp),%eax +c010077d: 89 50 04 mov %edx,0x4(%eax) + + // Search backwards from the line number for the relevant filename stab. + // We can't just use the "lfile" stab because inlined functions + // can interpolate code from a different file! + // Such included source files use the N_SOL stab type. + while (lline >= lfile +c0100780: eb 11 jmp c0100793 + return -1; +c0100782: b8 ff ff ff ff mov $0xffffffff,%eax +c0100787: e9 08 01 00 00 jmp c0100894 + && stabs[lline].n_type != N_SOL + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + lline --; +c010078c: 8b 45 d4 mov -0x2c(%ebp),%eax +c010078f: 48 dec %eax +c0100790: 89 45 d4 mov %eax,-0x2c(%ebp) + while (lline >= lfile +c0100793: 8b 55 d4 mov -0x2c(%ebp),%edx +c0100796: 8b 45 e4 mov -0x1c(%ebp),%eax + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c0100799: 39 c2 cmp %eax,%edx +c010079b: 7c 56 jl c01007f3 + && stabs[lline].n_type != N_SOL +c010079d: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007a0: 89 c2 mov %eax,%edx +c01007a2: 89 d0 mov %edx,%eax +c01007a4: 01 c0 add %eax,%eax +c01007a6: 01 d0 add %edx,%eax +c01007a8: c1 e0 02 shl $0x2,%eax +c01007ab: 89 c2 mov %eax,%edx +c01007ad: 8b 45 f4 mov -0xc(%ebp),%eax +c01007b0: 01 d0 add %edx,%eax +c01007b2: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01007b6: 3c 84 cmp $0x84,%al +c01007b8: 74 39 je c01007f3 + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c01007ba: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007bd: 89 c2 mov %eax,%edx +c01007bf: 89 d0 mov %edx,%eax +c01007c1: 01 c0 add %eax,%eax +c01007c3: 01 d0 add %edx,%eax +c01007c5: c1 e0 02 shl $0x2,%eax +c01007c8: 89 c2 mov %eax,%edx +c01007ca: 8b 45 f4 mov -0xc(%ebp),%eax +c01007cd: 01 d0 add %edx,%eax +c01007cf: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01007d3: 3c 64 cmp $0x64,%al +c01007d5: 75 b5 jne c010078c +c01007d7: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007da: 89 c2 mov %eax,%edx +c01007dc: 89 d0 mov %edx,%eax +c01007de: 01 c0 add %eax,%eax +c01007e0: 01 d0 add %edx,%eax +c01007e2: c1 e0 02 shl $0x2,%eax +c01007e5: 89 c2 mov %eax,%edx +c01007e7: 8b 45 f4 mov -0xc(%ebp),%eax +c01007ea: 01 d0 add %edx,%eax +c01007ec: 8b 40 08 mov 0x8(%eax),%eax +c01007ef: 85 c0 test %eax,%eax +c01007f1: 74 99 je c010078c + } + if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) { +c01007f3: 8b 55 d4 mov -0x2c(%ebp),%edx +c01007f6: 8b 45 e4 mov -0x1c(%ebp),%eax +c01007f9: 39 c2 cmp %eax,%edx +c01007fb: 7c 42 jl c010083f +c01007fd: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100800: 89 c2 mov %eax,%edx +c0100802: 89 d0 mov %edx,%eax +c0100804: 01 c0 add %eax,%eax +c0100806: 01 d0 add %edx,%eax +c0100808: c1 e0 02 shl $0x2,%eax +c010080b: 89 c2 mov %eax,%edx +c010080d: 8b 45 f4 mov -0xc(%ebp),%eax +c0100810: 01 d0 add %edx,%eax +c0100812: 8b 10 mov (%eax),%edx +c0100814: 8b 45 e8 mov -0x18(%ebp),%eax +c0100817: 2b 45 ec sub -0x14(%ebp),%eax +c010081a: 39 c2 cmp %eax,%edx +c010081c: 73 21 jae c010083f + info->eip_file = stabstr + stabs[lline].n_strx; +c010081e: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100821: 89 c2 mov %eax,%edx +c0100823: 89 d0 mov %edx,%eax +c0100825: 01 c0 add %eax,%eax +c0100827: 01 d0 add %edx,%eax +c0100829: c1 e0 02 shl $0x2,%eax +c010082c: 89 c2 mov %eax,%edx +c010082e: 8b 45 f4 mov -0xc(%ebp),%eax +c0100831: 01 d0 add %edx,%eax +c0100833: 8b 10 mov (%eax),%edx +c0100835: 8b 45 ec mov -0x14(%ebp),%eax +c0100838: 01 c2 add %eax,%edx +c010083a: 8b 45 0c mov 0xc(%ebp),%eax +c010083d: 89 10 mov %edx,(%eax) + } + + // Set eip_fn_narg to the number of arguments taken by the function, + // or 0 if there was no containing function. + if (lfun < rfun) { +c010083f: 8b 55 dc mov -0x24(%ebp),%edx +c0100842: 8b 45 d8 mov -0x28(%ebp),%eax +c0100845: 39 c2 cmp %eax,%edx +c0100847: 7d 46 jge c010088f + for (lline = lfun + 1; +c0100849: 8b 45 dc mov -0x24(%ebp),%eax +c010084c: 40 inc %eax +c010084d: 89 45 d4 mov %eax,-0x2c(%ebp) +c0100850: eb 16 jmp c0100868 + lline < rfun && stabs[lline].n_type == N_PSYM; + lline ++) { + info->eip_fn_narg ++; +c0100852: 8b 45 0c mov 0xc(%ebp),%eax +c0100855: 8b 40 14 mov 0x14(%eax),%eax +c0100858: 8d 50 01 lea 0x1(%eax),%edx +c010085b: 8b 45 0c mov 0xc(%ebp),%eax +c010085e: 89 50 14 mov %edx,0x14(%eax) + lline ++) { +c0100861: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100864: 40 inc %eax +c0100865: 89 45 d4 mov %eax,-0x2c(%ebp) + lline < rfun && stabs[lline].n_type == N_PSYM; +c0100868: 8b 55 d4 mov -0x2c(%ebp),%edx +c010086b: 8b 45 d8 mov -0x28(%ebp),%eax +c010086e: 39 c2 cmp %eax,%edx +c0100870: 7d 1d jge c010088f +c0100872: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100875: 89 c2 mov %eax,%edx +c0100877: 89 d0 mov %edx,%eax +c0100879: 01 c0 add %eax,%eax +c010087b: 01 d0 add %edx,%eax +c010087d: c1 e0 02 shl $0x2,%eax +c0100880: 89 c2 mov %eax,%edx +c0100882: 8b 45 f4 mov -0xc(%ebp),%eax +c0100885: 01 d0 add %edx,%eax +c0100887: 0f b6 40 04 movzbl 0x4(%eax),%eax +c010088b: 3c a0 cmp $0xa0,%al +c010088d: 74 c3 je c0100852 + } + } + return 0; +c010088f: b8 00 00 00 00 mov $0x0,%eax +} +c0100894: 89 ec mov %ebp,%esp +c0100896: 5d pop %ebp +c0100897: c3 ret + +c0100898 : + * print_kerninfo - print the information about kernel, including the location + * of kernel entry, the start addresses of data and text segements, the start + * address of free memory and how many memory that kernel has used. + * */ +void +print_kerninfo(void) { +c0100898: 55 push %ebp +c0100899: 89 e5 mov %esp,%ebp +c010089b: 83 ec 18 sub $0x18,%esp + extern char etext[], edata[], end[], kern_init[]; + cprintf("Special kernel symbols:\n"); +c010089e: c7 04 24 16 8e 10 c0 movl $0xc0108e16,(%esp) +c01008a5: e8 cb fa ff ff call c0100375 + cprintf(" entry 0x%08x (phys)\n", kern_init); +c01008aa: c7 44 24 04 36 00 10 movl $0xc0100036,0x4(%esp) +c01008b1: c0 +c01008b2: c7 04 24 2f 8e 10 c0 movl $0xc0108e2f,(%esp) +c01008b9: e8 b7 fa ff ff call c0100375 + cprintf(" etext 0x%08x (phys)\n", etext); +c01008be: c7 44 24 04 5a 8d 10 movl $0xc0108d5a,0x4(%esp) +c01008c5: c0 +c01008c6: c7 04 24 47 8e 10 c0 movl $0xc0108e47,(%esp) +c01008cd: e8 a3 fa ff ff call c0100375 + cprintf(" edata 0x%08x (phys)\n", edata); +c01008d2: c7 44 24 04 00 50 12 movl $0xc0125000,0x4(%esp) +c01008d9: c0 +c01008da: c7 04 24 5f 8e 10 c0 movl $0xc0108e5f,(%esp) +c01008e1: e8 8f fa ff ff call c0100375 + cprintf(" end 0x%08x (phys)\n", end); +c01008e6: c7 44 24 04 74 61 12 movl $0xc0126174,0x4(%esp) +c01008ed: c0 +c01008ee: c7 04 24 77 8e 10 c0 movl $0xc0108e77,(%esp) +c01008f5: e8 7b fa ff ff call c0100375 + cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024); +c01008fa: b8 74 61 12 c0 mov $0xc0126174,%eax +c01008ff: 2d 36 00 10 c0 sub $0xc0100036,%eax +c0100904: 05 ff 03 00 00 add $0x3ff,%eax +c0100909: 8d 90 ff 03 00 00 lea 0x3ff(%eax),%edx +c010090f: 85 c0 test %eax,%eax +c0100911: 0f 48 c2 cmovs %edx,%eax +c0100914: c1 f8 0a sar $0xa,%eax +c0100917: 89 44 24 04 mov %eax,0x4(%esp) +c010091b: c7 04 24 90 8e 10 c0 movl $0xc0108e90,(%esp) +c0100922: e8 4e fa ff ff call c0100375 +} +c0100927: 90 nop +c0100928: 89 ec mov %ebp,%esp +c010092a: 5d pop %ebp +c010092b: c3 ret + +c010092c : +/* * + * print_debuginfo - read and print the stat information for the address @eip, + * and info.eip_fn_addr should be the first address of the related function. + * */ +void +print_debuginfo(uintptr_t eip) { +c010092c: 55 push %ebp +c010092d: 89 e5 mov %esp,%ebp +c010092f: 81 ec 48 01 00 00 sub $0x148,%esp + struct eipdebuginfo info; + if (debuginfo_eip(eip, &info) != 0) { +c0100935: 8d 45 dc lea -0x24(%ebp),%eax +c0100938: 89 44 24 04 mov %eax,0x4(%esp) +c010093c: 8b 45 08 mov 0x8(%ebp),%eax +c010093f: 89 04 24 mov %eax,(%esp) +c0100942: e8 29 fc ff ff call c0100570 +c0100947: 85 c0 test %eax,%eax +c0100949: 74 15 je c0100960 + cprintf(" : -- 0x%08x --\n", eip); +c010094b: 8b 45 08 mov 0x8(%ebp),%eax +c010094e: 89 44 24 04 mov %eax,0x4(%esp) +c0100952: c7 04 24 ba 8e 10 c0 movl $0xc0108eba,(%esp) +c0100959: e8 17 fa ff ff call c0100375 + } + fnname[j] = '\0'; + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + fnname, eip - info.eip_fn_addr); + } +} +c010095e: eb 6c jmp c01009cc + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100960: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100967: eb 1b jmp c0100984 + fnname[j] = info.eip_fn_name[j]; +c0100969: 8b 55 e4 mov -0x1c(%ebp),%edx +c010096c: 8b 45 f4 mov -0xc(%ebp),%eax +c010096f: 01 d0 add %edx,%eax +c0100971: 0f b6 10 movzbl (%eax),%edx +c0100974: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c010097a: 8b 45 f4 mov -0xc(%ebp),%eax +c010097d: 01 c8 add %ecx,%eax +c010097f: 88 10 mov %dl,(%eax) + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100981: ff 45 f4 incl -0xc(%ebp) +c0100984: 8b 45 e8 mov -0x18(%ebp),%eax +c0100987: 39 45 f4 cmp %eax,-0xc(%ebp) +c010098a: 7c dd jl c0100969 + fnname[j] = '\0'; +c010098c: 8d 95 dc fe ff ff lea -0x124(%ebp),%edx +c0100992: 8b 45 f4 mov -0xc(%ebp),%eax +c0100995: 01 d0 add %edx,%eax +c0100997: c6 00 00 movb $0x0,(%eax) + fnname, eip - info.eip_fn_addr); +c010099a: 8b 55 ec mov -0x14(%ebp),%edx + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, +c010099d: 8b 45 08 mov 0x8(%ebp),%eax +c01009a0: 29 d0 sub %edx,%eax +c01009a2: 89 c1 mov %eax,%ecx +c01009a4: 8b 55 e0 mov -0x20(%ebp),%edx +c01009a7: 8b 45 dc mov -0x24(%ebp),%eax +c01009aa: 89 4c 24 10 mov %ecx,0x10(%esp) +c01009ae: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c01009b4: 89 4c 24 0c mov %ecx,0xc(%esp) +c01009b8: 89 54 24 08 mov %edx,0x8(%esp) +c01009bc: 89 44 24 04 mov %eax,0x4(%esp) +c01009c0: c7 04 24 d6 8e 10 c0 movl $0xc0108ed6,(%esp) +c01009c7: e8 a9 f9 ff ff call c0100375 +} +c01009cc: 90 nop +c01009cd: 89 ec mov %ebp,%esp +c01009cf: 5d pop %ebp +c01009d0: c3 ret + +c01009d1 : + +static __noinline uint32_t +read_eip(void) { +c01009d1: 55 push %ebp +c01009d2: 89 e5 mov %esp,%ebp +c01009d4: 83 ec 10 sub $0x10,%esp + uint32_t eip; + asm volatile("movl 4(%%ebp), %0" : "=r" (eip)); +c01009d7: 8b 45 04 mov 0x4(%ebp),%eax +c01009da: 89 45 fc mov %eax,-0x4(%ebp) + return eip; +c01009dd: 8b 45 fc mov -0x4(%ebp),%eax +} +c01009e0: 89 ec mov %ebp,%esp +c01009e2: 5d pop %ebp +c01009e3: c3 ret + +c01009e4 : + * + * Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping + * to the kernel entry, the value of ebp has been set to zero, that's the boundary. + * */ +void +print_stackframe(void) { +c01009e4: 55 push %ebp +c01009e5: 89 e5 mov %esp,%ebp + * (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc. + * (3.5) popup a calling stackframe + * NOTICE: the calling funciton's return addr eip = ss:[ebp+4] + * the calling funciton's ebp = ss:[ebp] + */ +} +c01009e7: 90 nop +c01009e8: 5d pop %ebp +c01009e9: c3 ret + +c01009ea : +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { +c01009ea: 55 push %ebp +c01009eb: 89 e5 mov %esp,%ebp +c01009ed: 83 ec 28 sub $0x28,%esp + int argc = 0; +c01009f0: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c01009f7: eb 0c jmp c0100a05 + *buf ++ = '\0'; +c01009f9: 8b 45 08 mov 0x8(%ebp),%eax +c01009fc: 8d 50 01 lea 0x1(%eax),%edx +c01009ff: 89 55 08 mov %edx,0x8(%ebp) +c0100a02: c6 00 00 movb $0x0,(%eax) + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c0100a05: 8b 45 08 mov 0x8(%ebp),%eax +c0100a08: 0f b6 00 movzbl (%eax),%eax +c0100a0b: 84 c0 test %al,%al +c0100a0d: 74 1d je c0100a2c +c0100a0f: 8b 45 08 mov 0x8(%ebp),%eax +c0100a12: 0f b6 00 movzbl (%eax),%eax +c0100a15: 0f be c0 movsbl %al,%eax +c0100a18: 89 44 24 04 mov %eax,0x4(%esp) +c0100a1c: c7 04 24 68 8f 10 c0 movl $0xc0108f68,(%esp) +c0100a23: e8 ea 7f 00 00 call c0108a12 +c0100a28: 85 c0 test %eax,%eax +c0100a2a: 75 cd jne c01009f9 + } + if (*buf == '\0') { +c0100a2c: 8b 45 08 mov 0x8(%ebp),%eax +c0100a2f: 0f b6 00 movzbl (%eax),%eax +c0100a32: 84 c0 test %al,%al +c0100a34: 74 65 je c0100a9b + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { +c0100a36: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +c0100a3a: 75 14 jne c0100a50 + cprintf("Too many arguments (max %d).\n", MAXARGS); +c0100a3c: c7 44 24 04 10 00 00 movl $0x10,0x4(%esp) +c0100a43: 00 +c0100a44: c7 04 24 6d 8f 10 c0 movl $0xc0108f6d,(%esp) +c0100a4b: e8 25 f9 ff ff call c0100375 + } + argv[argc ++] = buf; +c0100a50: 8b 45 f4 mov -0xc(%ebp),%eax +c0100a53: 8d 50 01 lea 0x1(%eax),%edx +c0100a56: 89 55 f4 mov %edx,-0xc(%ebp) +c0100a59: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0100a60: 8b 45 0c mov 0xc(%ebp),%eax +c0100a63: 01 c2 add %eax,%edx +c0100a65: 8b 45 08 mov 0x8(%ebp),%eax +c0100a68: 89 02 mov %eax,(%edx) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100a6a: eb 03 jmp c0100a6f + buf ++; +c0100a6c: ff 45 08 incl 0x8(%ebp) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100a6f: 8b 45 08 mov 0x8(%ebp),%eax +c0100a72: 0f b6 00 movzbl (%eax),%eax +c0100a75: 84 c0 test %al,%al +c0100a77: 74 8c je c0100a05 +c0100a79: 8b 45 08 mov 0x8(%ebp),%eax +c0100a7c: 0f b6 00 movzbl (%eax),%eax +c0100a7f: 0f be c0 movsbl %al,%eax +c0100a82: 89 44 24 04 mov %eax,0x4(%esp) +c0100a86: c7 04 24 68 8f 10 c0 movl $0xc0108f68,(%esp) +c0100a8d: e8 80 7f 00 00 call c0108a12 +c0100a92: 85 c0 test %eax,%eax +c0100a94: 74 d6 je c0100a6c + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c0100a96: e9 6a ff ff ff jmp c0100a05 + break; +c0100a9b: 90 nop + } + } + return argc; +c0100a9c: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100a9f: 89 ec mov %ebp,%esp +c0100aa1: 5d pop %ebp +c0100aa2: c3 ret + +c0100aa3 : +/* * + * runcmd - parse the input string, split it into separated arguments + * and then lookup and invoke some related commands/ + * */ +static int +runcmd(char *buf, struct trapframe *tf) { +c0100aa3: 55 push %ebp +c0100aa4: 89 e5 mov %esp,%ebp +c0100aa6: 83 ec 68 sub $0x68,%esp +c0100aa9: 89 5d fc mov %ebx,-0x4(%ebp) + char *argv[MAXARGS]; + int argc = parse(buf, argv); +c0100aac: 8d 45 b0 lea -0x50(%ebp),%eax +c0100aaf: 89 44 24 04 mov %eax,0x4(%esp) +c0100ab3: 8b 45 08 mov 0x8(%ebp),%eax +c0100ab6: 89 04 24 mov %eax,(%esp) +c0100ab9: e8 2c ff ff ff call c01009ea +c0100abe: 89 45 f0 mov %eax,-0x10(%ebp) + if (argc == 0) { +c0100ac1: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0100ac5: 75 0a jne c0100ad1 + return 0; +c0100ac7: b8 00 00 00 00 mov $0x0,%eax +c0100acc: e9 83 00 00 00 jmp c0100b54 + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100ad1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100ad8: eb 5a jmp c0100b34 + if (strcmp(commands[i].name, argv[0]) == 0) { +c0100ada: 8b 55 b0 mov -0x50(%ebp),%edx +c0100add: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100ae0: 89 c8 mov %ecx,%eax +c0100ae2: 01 c0 add %eax,%eax +c0100ae4: 01 c8 add %ecx,%eax +c0100ae6: c1 e0 02 shl $0x2,%eax +c0100ae9: 05 00 20 12 c0 add $0xc0122000,%eax +c0100aee: 8b 00 mov (%eax),%eax +c0100af0: 89 54 24 04 mov %edx,0x4(%esp) +c0100af4: 89 04 24 mov %eax,(%esp) +c0100af7: e8 7a 7e 00 00 call c0108976 +c0100afc: 85 c0 test %eax,%eax +c0100afe: 75 31 jne c0100b31 + return commands[i].func(argc - 1, argv + 1, tf); +c0100b00: 8b 55 f4 mov -0xc(%ebp),%edx +c0100b03: 89 d0 mov %edx,%eax +c0100b05: 01 c0 add %eax,%eax +c0100b07: 01 d0 add %edx,%eax +c0100b09: c1 e0 02 shl $0x2,%eax +c0100b0c: 05 08 20 12 c0 add $0xc0122008,%eax +c0100b11: 8b 10 mov (%eax),%edx +c0100b13: 8d 45 b0 lea -0x50(%ebp),%eax +c0100b16: 83 c0 04 add $0x4,%eax +c0100b19: 8b 4d f0 mov -0x10(%ebp),%ecx +c0100b1c: 8d 59 ff lea -0x1(%ecx),%ebx +c0100b1f: 8b 4d 0c mov 0xc(%ebp),%ecx +c0100b22: 89 4c 24 08 mov %ecx,0x8(%esp) +c0100b26: 89 44 24 04 mov %eax,0x4(%esp) +c0100b2a: 89 1c 24 mov %ebx,(%esp) +c0100b2d: ff d2 call *%edx +c0100b2f: eb 23 jmp c0100b54 + for (i = 0; i < NCOMMANDS; i ++) { +c0100b31: ff 45 f4 incl -0xc(%ebp) +c0100b34: 8b 45 f4 mov -0xc(%ebp),%eax +c0100b37: 83 f8 02 cmp $0x2,%eax +c0100b3a: 76 9e jbe c0100ada + } + } + cprintf("Unknown command '%s'\n", argv[0]); +c0100b3c: 8b 45 b0 mov -0x50(%ebp),%eax +c0100b3f: 89 44 24 04 mov %eax,0x4(%esp) +c0100b43: c7 04 24 8b 8f 10 c0 movl $0xc0108f8b,(%esp) +c0100b4a: e8 26 f8 ff ff call c0100375 + return 0; +c0100b4f: b8 00 00 00 00 mov $0x0,%eax +} +c0100b54: 8b 5d fc mov -0x4(%ebp),%ebx +c0100b57: 89 ec mov %ebp,%esp +c0100b59: 5d pop %ebp +c0100b5a: c3 ret + +c0100b5b : + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { +c0100b5b: 55 push %ebp +c0100b5c: 89 e5 mov %esp,%ebp +c0100b5e: 83 ec 28 sub $0x28,%esp + cprintf("Welcome to the kernel debug monitor!!\n"); +c0100b61: c7 04 24 a4 8f 10 c0 movl $0xc0108fa4,(%esp) +c0100b68: e8 08 f8 ff ff call c0100375 + cprintf("Type 'help' for a list of commands.\n"); +c0100b6d: c7 04 24 cc 8f 10 c0 movl $0xc0108fcc,(%esp) +c0100b74: e8 fc f7 ff ff call c0100375 + + if (tf != NULL) { +c0100b79: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100b7d: 74 0b je c0100b8a + print_trapframe(tf); +c0100b7f: 8b 45 08 mov 0x8(%ebp),%eax +c0100b82: 89 04 24 mov %eax,(%esp) +c0100b85: e8 2c 17 00 00 call c01022b6 + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { +c0100b8a: c7 04 24 f1 8f 10 c0 movl $0xc0108ff1,(%esp) +c0100b91: e8 d0 f6 ff ff call c0100266 +c0100b96: 89 45 f4 mov %eax,-0xc(%ebp) +c0100b99: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0100b9d: 74 eb je c0100b8a + if (runcmd(buf, tf) < 0) { +c0100b9f: 8b 45 08 mov 0x8(%ebp),%eax +c0100ba2: 89 44 24 04 mov %eax,0x4(%esp) +c0100ba6: 8b 45 f4 mov -0xc(%ebp),%eax +c0100ba9: 89 04 24 mov %eax,(%esp) +c0100bac: e8 f2 fe ff ff call c0100aa3 +c0100bb1: 85 c0 test %eax,%eax +c0100bb3: 78 02 js c0100bb7 + if ((buf = readline("K> ")) != NULL) { +c0100bb5: eb d3 jmp c0100b8a + break; +c0100bb7: 90 nop + } + } + } +} +c0100bb8: 90 nop +c0100bb9: 89 ec mov %ebp,%esp +c0100bbb: 5d pop %ebp +c0100bbc: c3 ret + +c0100bbd : + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { +c0100bbd: 55 push %ebp +c0100bbe: 89 e5 mov %esp,%ebp +c0100bc0: 83 ec 28 sub $0x28,%esp + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100bc3: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100bca: eb 3d jmp c0100c09 + cprintf("%s - %s\n", commands[i].name, commands[i].desc); +c0100bcc: 8b 55 f4 mov -0xc(%ebp),%edx +c0100bcf: 89 d0 mov %edx,%eax +c0100bd1: 01 c0 add %eax,%eax +c0100bd3: 01 d0 add %edx,%eax +c0100bd5: c1 e0 02 shl $0x2,%eax +c0100bd8: 05 04 20 12 c0 add $0xc0122004,%eax +c0100bdd: 8b 10 mov (%eax),%edx +c0100bdf: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100be2: 89 c8 mov %ecx,%eax +c0100be4: 01 c0 add %eax,%eax +c0100be6: 01 c8 add %ecx,%eax +c0100be8: c1 e0 02 shl $0x2,%eax +c0100beb: 05 00 20 12 c0 add $0xc0122000,%eax +c0100bf0: 8b 00 mov (%eax),%eax +c0100bf2: 89 54 24 08 mov %edx,0x8(%esp) +c0100bf6: 89 44 24 04 mov %eax,0x4(%esp) +c0100bfa: c7 04 24 f5 8f 10 c0 movl $0xc0108ff5,(%esp) +c0100c01: e8 6f f7 ff ff call c0100375 + for (i = 0; i < NCOMMANDS; i ++) { +c0100c06: ff 45 f4 incl -0xc(%ebp) +c0100c09: 8b 45 f4 mov -0xc(%ebp),%eax +c0100c0c: 83 f8 02 cmp $0x2,%eax +c0100c0f: 76 bb jbe c0100bcc + } + return 0; +c0100c11: b8 00 00 00 00 mov $0x0,%eax +} +c0100c16: 89 ec mov %ebp,%esp +c0100c18: 5d pop %ebp +c0100c19: c3 ret + +c0100c1a : +/* * + * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to + * print the memory occupancy in kernel. + * */ +int +mon_kerninfo(int argc, char **argv, struct trapframe *tf) { +c0100c1a: 55 push %ebp +c0100c1b: 89 e5 mov %esp,%ebp +c0100c1d: 83 ec 08 sub $0x8,%esp + print_kerninfo(); +c0100c20: e8 73 fc ff ff call c0100898 + return 0; +c0100c25: b8 00 00 00 00 mov $0x0,%eax +} +c0100c2a: 89 ec mov %ebp,%esp +c0100c2c: 5d pop %ebp +c0100c2d: c3 ret + +c0100c2e : +/* * + * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to + * print a backtrace of the stack. + * */ +int +mon_backtrace(int argc, char **argv, struct trapframe *tf) { +c0100c2e: 55 push %ebp +c0100c2f: 89 e5 mov %esp,%ebp +c0100c31: 83 ec 08 sub $0x8,%esp + print_stackframe(); +c0100c34: e8 ab fd ff ff call c01009e4 + return 0; +c0100c39: b8 00 00 00 00 mov $0x0,%eax +} +c0100c3e: 89 ec mov %ebp,%esp +c0100c40: 5d pop %ebp +c0100c41: c3 ret + +c0100c42 <__panic>: +/* * + * __panic - __panic is called on unresolvable fatal errors. it prints + * "panic: 'message'", and then enters the kernel monitor. + * */ +void +__panic(const char *file, int line, const char *fmt, ...) { +c0100c42: 55 push %ebp +c0100c43: 89 e5 mov %esp,%ebp +c0100c45: 83 ec 28 sub $0x28,%esp + if (is_panic) { +c0100c48: a1 20 54 12 c0 mov 0xc0125420,%eax +c0100c4d: 85 c0 test %eax,%eax +c0100c4f: 75 5b jne c0100cac <__panic+0x6a> + goto panic_dead; + } + is_panic = 1; +c0100c51: c7 05 20 54 12 c0 01 movl $0x1,0xc0125420 +c0100c58: 00 00 00 + + // print the 'message' + va_list ap; + va_start(ap, fmt); +c0100c5b: 8d 45 14 lea 0x14(%ebp),%eax +c0100c5e: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel panic at %s:%d:\n ", file, line); +c0100c61: 8b 45 0c mov 0xc(%ebp),%eax +c0100c64: 89 44 24 08 mov %eax,0x8(%esp) +c0100c68: 8b 45 08 mov 0x8(%ebp),%eax +c0100c6b: 89 44 24 04 mov %eax,0x4(%esp) +c0100c6f: c7 04 24 fe 8f 10 c0 movl $0xc0108ffe,(%esp) +c0100c76: e8 fa f6 ff ff call c0100375 + vcprintf(fmt, ap); +c0100c7b: 8b 45 f4 mov -0xc(%ebp),%eax +c0100c7e: 89 44 24 04 mov %eax,0x4(%esp) +c0100c82: 8b 45 10 mov 0x10(%ebp),%eax +c0100c85: 89 04 24 mov %eax,(%esp) +c0100c88: e8 b3 f6 ff ff call c0100340 + cprintf("\n"); +c0100c8d: c7 04 24 1a 90 10 c0 movl $0xc010901a,(%esp) +c0100c94: e8 dc f6 ff ff call c0100375 + + cprintf("stack trackback:\n"); +c0100c99: c7 04 24 1c 90 10 c0 movl $0xc010901c,(%esp) +c0100ca0: e8 d0 f6 ff ff call c0100375 + print_stackframe(); +c0100ca5: e8 3a fd ff ff call c01009e4 +c0100caa: eb 01 jmp c0100cad <__panic+0x6b> + goto panic_dead; +c0100cac: 90 nop + + va_end(ap); + +panic_dead: + intr_disable(); +c0100cad: e8 46 12 00 00 call c0101ef8 + while (1) { + kmonitor(NULL); +c0100cb2: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100cb9: e8 9d fe ff ff call c0100b5b +c0100cbe: eb f2 jmp c0100cb2 <__panic+0x70> + +c0100cc0 <__warn>: + } +} + +/* __warn - like panic, but don't */ +void +__warn(const char *file, int line, const char *fmt, ...) { +c0100cc0: 55 push %ebp +c0100cc1: 89 e5 mov %esp,%ebp +c0100cc3: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); +c0100cc6: 8d 45 14 lea 0x14(%ebp),%eax +c0100cc9: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel warning at %s:%d:\n ", file, line); +c0100ccc: 8b 45 0c mov 0xc(%ebp),%eax +c0100ccf: 89 44 24 08 mov %eax,0x8(%esp) +c0100cd3: 8b 45 08 mov 0x8(%ebp),%eax +c0100cd6: 89 44 24 04 mov %eax,0x4(%esp) +c0100cda: c7 04 24 2e 90 10 c0 movl $0xc010902e,(%esp) +c0100ce1: e8 8f f6 ff ff call c0100375 + vcprintf(fmt, ap); +c0100ce6: 8b 45 f4 mov -0xc(%ebp),%eax +c0100ce9: 89 44 24 04 mov %eax,0x4(%esp) +c0100ced: 8b 45 10 mov 0x10(%ebp),%eax +c0100cf0: 89 04 24 mov %eax,(%esp) +c0100cf3: e8 48 f6 ff ff call c0100340 + cprintf("\n"); +c0100cf8: c7 04 24 1a 90 10 c0 movl $0xc010901a,(%esp) +c0100cff: e8 71 f6 ff ff call c0100375 + va_end(ap); +} +c0100d04: 90 nop +c0100d05: 89 ec mov %ebp,%esp +c0100d07: 5d pop %ebp +c0100d08: c3 ret + +c0100d09 : + +bool +is_kernel_panic(void) { +c0100d09: 55 push %ebp +c0100d0a: 89 e5 mov %esp,%ebp + return is_panic; +c0100d0c: a1 20 54 12 c0 mov 0xc0125420,%eax +} +c0100d11: 5d pop %ebp +c0100d12: c3 ret + +c0100d13 : +/* * + * clock_init - initialize 8253 clock to interrupt 100 times per second, + * and then enable IRQ_TIMER. + * */ +void +clock_init(void) { +c0100d13: 55 push %ebp +c0100d14: 89 e5 mov %esp,%ebp +c0100d16: 83 ec 28 sub $0x28,%esp +c0100d19: 66 c7 45 ee 43 00 movw $0x43,-0x12(%ebp) +c0100d1f: c6 45 ed 34 movb $0x34,-0x13(%ebp) + : "memory", "cc"); +} + +static inline void +outb(uint16_t port, uint8_t data) { + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d23: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100d27: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100d2b: ee out %al,(%dx) +} +c0100d2c: 90 nop +c0100d2d: 66 c7 45 f2 40 00 movw $0x40,-0xe(%ebp) +c0100d33: c6 45 f1 9c movb $0x9c,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d37: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100d3b: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0100d3f: ee out %al,(%dx) +} +c0100d40: 90 nop +c0100d41: 66 c7 45 f6 40 00 movw $0x40,-0xa(%ebp) +c0100d47: c6 45 f5 2e movb $0x2e,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d4b: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0100d4f: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0100d53: ee out %al,(%dx) +} +c0100d54: 90 nop + outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(IO_TIMER1, TIMER_DIV(100) % 256); + outb(IO_TIMER1, TIMER_DIV(100) / 256); + + // initialize time counter 'ticks' to zero + ticks = 0; +c0100d55: c7 05 24 54 12 c0 00 movl $0x0,0xc0125424 +c0100d5c: 00 00 00 + + cprintf("++ setup timer interrupts\n"); +c0100d5f: c7 04 24 4c 90 10 c0 movl $0xc010904c,(%esp) +c0100d66: e8 0a f6 ff ff call c0100375 + pic_enable(IRQ_TIMER); +c0100d6b: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100d72: e8 e6 11 00 00 call c0101f5d +} +c0100d77: 90 nop +c0100d78: 89 ec mov %ebp,%esp +c0100d7a: 5d pop %ebp +c0100d7b: c3 ret + +c0100d7c <__intr_save>: +#include +#include +#include + +static inline bool +__intr_save(void) { +c0100d7c: 55 push %ebp +c0100d7d: 89 e5 mov %esp,%ebp +c0100d7f: 83 ec 18 sub $0x18,%esp +} + +static inline uint32_t +read_eflags(void) { + uint32_t eflags; + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0100d82: 9c pushf +c0100d83: 58 pop %eax +c0100d84: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c0100d87: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c0100d8a: 25 00 02 00 00 and $0x200,%eax +c0100d8f: 85 c0 test %eax,%eax +c0100d91: 74 0c je c0100d9f <__intr_save+0x23> + intr_disable(); +c0100d93: e8 60 11 00 00 call c0101ef8 + return 1; +c0100d98: b8 01 00 00 00 mov $0x1,%eax +c0100d9d: eb 05 jmp c0100da4 <__intr_save+0x28> + } + return 0; +c0100d9f: b8 00 00 00 00 mov $0x0,%eax +} +c0100da4: 89 ec mov %ebp,%esp +c0100da6: 5d pop %ebp +c0100da7: c3 ret + +c0100da8 <__intr_restore>: + +static inline void +__intr_restore(bool flag) { +c0100da8: 55 push %ebp +c0100da9: 89 e5 mov %esp,%ebp +c0100dab: 83 ec 08 sub $0x8,%esp + if (flag) { +c0100dae: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100db2: 74 05 je c0100db9 <__intr_restore+0x11> + intr_enable(); +c0100db4: e8 37 11 00 00 call c0101ef0 + } +} +c0100db9: 90 nop +c0100dba: 89 ec mov %ebp,%esp +c0100dbc: 5d pop %ebp +c0100dbd: c3 ret + +c0100dbe : +#include +#include + +/* stupid I/O delay routine necessitated by historical PC design flaws */ +static void +delay(void) { +c0100dbe: 55 push %ebp +c0100dbf: 89 e5 mov %esp,%ebp +c0100dc1: 83 ec 10 sub $0x10,%esp +c0100dc4: 66 c7 45 f2 84 00 movw $0x84,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100dca: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100dce: 89 c2 mov %eax,%edx +c0100dd0: ec in (%dx),%al +c0100dd1: 88 45 f1 mov %al,-0xf(%ebp) +c0100dd4: 66 c7 45 f6 84 00 movw $0x84,-0xa(%ebp) +c0100dda: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100dde: 89 c2 mov %eax,%edx +c0100de0: ec in (%dx),%al +c0100de1: 88 45 f5 mov %al,-0xb(%ebp) +c0100de4: 66 c7 45 fa 84 00 movw $0x84,-0x6(%ebp) +c0100dea: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0100dee: 89 c2 mov %eax,%edx +c0100df0: ec in (%dx),%al +c0100df1: 88 45 f9 mov %al,-0x7(%ebp) +c0100df4: 66 c7 45 fe 84 00 movw $0x84,-0x2(%ebp) +c0100dfa: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0100dfe: 89 c2 mov %eax,%edx +c0100e00: ec in (%dx),%al +c0100e01: 88 45 fd mov %al,-0x3(%ebp) + inb(0x84); + inb(0x84); + inb(0x84); + inb(0x84); +} +c0100e04: 90 nop +c0100e05: 89 ec mov %ebp,%esp +c0100e07: 5d pop %ebp +c0100e08: c3 ret + +c0100e09 : +static uint16_t addr_6845; + +/* TEXT-mode CGA/VGA display output */ + +static void +cga_init(void) { +c0100e09: 55 push %ebp +c0100e0a: 89 e5 mov %esp,%ebp +c0100e0c: 83 ec 20 sub $0x20,%esp + volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE); +c0100e0f: c7 45 fc 00 80 0b c0 movl $0xc00b8000,-0x4(%ebp) + uint16_t was = *cp; +c0100e16: 8b 45 fc mov -0x4(%ebp),%eax +c0100e19: 0f b7 00 movzwl (%eax),%eax +c0100e1c: 66 89 45 fa mov %ax,-0x6(%ebp) + *cp = (uint16_t) 0xA55A; +c0100e20: 8b 45 fc mov -0x4(%ebp),%eax +c0100e23: 66 c7 00 5a a5 movw $0xa55a,(%eax) + if (*cp != 0xA55A) { +c0100e28: 8b 45 fc mov -0x4(%ebp),%eax +c0100e2b: 0f b7 00 movzwl (%eax),%eax +c0100e2e: 0f b7 c0 movzwl %ax,%eax +c0100e31: 3d 5a a5 00 00 cmp $0xa55a,%eax +c0100e36: 74 12 je c0100e4a + cp = (uint16_t*)(MONO_BUF + KERNBASE); +c0100e38: c7 45 fc 00 00 0b c0 movl $0xc00b0000,-0x4(%ebp) + addr_6845 = MONO_BASE; +c0100e3f: 66 c7 05 46 54 12 c0 movw $0x3b4,0xc0125446 +c0100e46: b4 03 +c0100e48: eb 13 jmp c0100e5d + } else { + *cp = was; +c0100e4a: 8b 45 fc mov -0x4(%ebp),%eax +c0100e4d: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c0100e51: 66 89 10 mov %dx,(%eax) + addr_6845 = CGA_BASE; +c0100e54: 66 c7 05 46 54 12 c0 movw $0x3d4,0xc0125446 +c0100e5b: d4 03 + } + + // Extract cursor location + uint32_t pos; + outb(addr_6845, 14); +c0100e5d: 0f b7 05 46 54 12 c0 movzwl 0xc0125446,%eax +c0100e64: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c0100e68: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e6c: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0100e70: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0100e74: ee out %al,(%dx) +} +c0100e75: 90 nop + pos = inb(addr_6845 + 1) << 8; +c0100e76: 0f b7 05 46 54 12 c0 movzwl 0xc0125446,%eax +c0100e7d: 40 inc %eax +c0100e7e: 0f b7 c0 movzwl %ax,%eax +c0100e81: 66 89 45 ea mov %ax,-0x16(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100e85: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0100e89: 89 c2 mov %eax,%edx +c0100e8b: ec in (%dx),%al +c0100e8c: 88 45 e9 mov %al,-0x17(%ebp) + return data; +c0100e8f: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0100e93: 0f b6 c0 movzbl %al,%eax +c0100e96: c1 e0 08 shl $0x8,%eax +c0100e99: 89 45 f4 mov %eax,-0xc(%ebp) + outb(addr_6845, 15); +c0100e9c: 0f b7 05 46 54 12 c0 movzwl 0xc0125446,%eax +c0100ea3: 66 89 45 ee mov %ax,-0x12(%ebp) +c0100ea7: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100eab: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100eaf: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100eb3: ee out %al,(%dx) +} +c0100eb4: 90 nop + pos |= inb(addr_6845 + 1); +c0100eb5: 0f b7 05 46 54 12 c0 movzwl 0xc0125446,%eax +c0100ebc: 40 inc %eax +c0100ebd: 0f b7 c0 movzwl %ax,%eax +c0100ec0: 66 89 45 f2 mov %ax,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100ec4: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100ec8: 89 c2 mov %eax,%edx +c0100eca: ec in (%dx),%al +c0100ecb: 88 45 f1 mov %al,-0xf(%ebp) + return data; +c0100ece: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100ed2: 0f b6 c0 movzbl %al,%eax +c0100ed5: 09 45 f4 or %eax,-0xc(%ebp) + + crt_buf = (uint16_t*) cp; +c0100ed8: 8b 45 fc mov -0x4(%ebp),%eax +c0100edb: a3 40 54 12 c0 mov %eax,0xc0125440 + crt_pos = pos; +c0100ee0: 8b 45 f4 mov -0xc(%ebp),%eax +c0100ee3: 0f b7 c0 movzwl %ax,%eax +c0100ee6: 66 a3 44 54 12 c0 mov %ax,0xc0125444 +} +c0100eec: 90 nop +c0100eed: 89 ec mov %ebp,%esp +c0100eef: 5d pop %ebp +c0100ef0: c3 ret + +c0100ef1 : + +static bool serial_exists = 0; + +static void +serial_init(void) { +c0100ef1: 55 push %ebp +c0100ef2: 89 e5 mov %esp,%ebp +c0100ef4: 83 ec 48 sub $0x48,%esp +c0100ef7: 66 c7 45 d2 fa 03 movw $0x3fa,-0x2e(%ebp) +c0100efd: c6 45 d1 00 movb $0x0,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f01: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c0100f05: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c0100f09: ee out %al,(%dx) +} +c0100f0a: 90 nop +c0100f0b: 66 c7 45 d6 fb 03 movw $0x3fb,-0x2a(%ebp) +c0100f11: c6 45 d5 80 movb $0x80,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f15: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0100f19: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0100f1d: ee out %al,(%dx) +} +c0100f1e: 90 nop +c0100f1f: 66 c7 45 da f8 03 movw $0x3f8,-0x26(%ebp) +c0100f25: c6 45 d9 0c movb $0xc,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f29: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0100f2d: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0100f31: ee out %al,(%dx) +} +c0100f32: 90 nop +c0100f33: 66 c7 45 de f9 03 movw $0x3f9,-0x22(%ebp) +c0100f39: c6 45 dd 00 movb $0x0,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f3d: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0100f41: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0100f45: ee out %al,(%dx) +} +c0100f46: 90 nop +c0100f47: 66 c7 45 e2 fb 03 movw $0x3fb,-0x1e(%ebp) +c0100f4d: c6 45 e1 03 movb $0x3,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f51: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0100f55: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0100f59: ee out %al,(%dx) +} +c0100f5a: 90 nop +c0100f5b: 66 c7 45 e6 fc 03 movw $0x3fc,-0x1a(%ebp) +c0100f61: c6 45 e5 00 movb $0x0,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f65: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0100f69: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0100f6d: ee out %al,(%dx) +} +c0100f6e: 90 nop +c0100f6f: 66 c7 45 ea f9 03 movw $0x3f9,-0x16(%ebp) +c0100f75: c6 45 e9 01 movb $0x1,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f79: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0100f7d: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0100f81: ee out %al,(%dx) +} +c0100f82: 90 nop +c0100f83: 66 c7 45 ee fd 03 movw $0x3fd,-0x12(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100f89: 0f b7 45 ee movzwl -0x12(%ebp),%eax +c0100f8d: 89 c2 mov %eax,%edx +c0100f8f: ec in (%dx),%al +c0100f90: 88 45 ed mov %al,-0x13(%ebp) + return data; +c0100f93: 0f b6 45 ed movzbl -0x13(%ebp),%eax + // Enable rcv interrupts + outb(COM1 + COM_IER, COM_IER_RDI); + + // Clear any preexisting overrun indications and interrupts + // Serial port doesn't exist if COM_LSR returns 0xFF + serial_exists = (inb(COM1 + COM_LSR) != 0xFF); +c0100f97: 3c ff cmp $0xff,%al +c0100f99: 0f 95 c0 setne %al +c0100f9c: 0f b6 c0 movzbl %al,%eax +c0100f9f: a3 48 54 12 c0 mov %eax,0xc0125448 +c0100fa4: 66 c7 45 f2 fa 03 movw $0x3fa,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100faa: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100fae: 89 c2 mov %eax,%edx +c0100fb0: ec in (%dx),%al +c0100fb1: 88 45 f1 mov %al,-0xf(%ebp) +c0100fb4: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c0100fba: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100fbe: 89 c2 mov %eax,%edx +c0100fc0: ec in (%dx),%al +c0100fc1: 88 45 f5 mov %al,-0xb(%ebp) + (void) inb(COM1+COM_IIR); + (void) inb(COM1+COM_RX); + + if (serial_exists) { +c0100fc4: a1 48 54 12 c0 mov 0xc0125448,%eax +c0100fc9: 85 c0 test %eax,%eax +c0100fcb: 74 0c je c0100fd9 + pic_enable(IRQ_COM1); +c0100fcd: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c0100fd4: e8 84 0f 00 00 call c0101f5d + } +} +c0100fd9: 90 nop +c0100fda: 89 ec mov %ebp,%esp +c0100fdc: 5d pop %ebp +c0100fdd: c3 ret + +c0100fde : + +static void +lpt_putc_sub(int c) { +c0100fde: 55 push %ebp +c0100fdf: 89 e5 mov %esp,%ebp +c0100fe1: 83 ec 20 sub $0x20,%esp + int i; + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c0100fe4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c0100feb: eb 08 jmp c0100ff5 + delay(); +c0100fed: e8 cc fd ff ff call c0100dbe + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c0100ff2: ff 45 fc incl -0x4(%ebp) +c0100ff5: 66 c7 45 fa 79 03 movw $0x379,-0x6(%ebp) +c0100ffb: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0100fff: 89 c2 mov %eax,%edx +c0101001: ec in (%dx),%al +c0101002: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c0101005: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0101009: 84 c0 test %al,%al +c010100b: 78 09 js c0101016 +c010100d: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c0101014: 7e d7 jle c0100fed + } + outb(LPTPORT + 0, c); +c0101016: 8b 45 08 mov 0x8(%ebp),%eax +c0101019: 0f b6 c0 movzbl %al,%eax +c010101c: 66 c7 45 ee 78 03 movw $0x378,-0x12(%ebp) +c0101022: 88 45 ed mov %al,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101025: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101029: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c010102d: ee out %al,(%dx) +} +c010102e: 90 nop +c010102f: 66 c7 45 f2 7a 03 movw $0x37a,-0xe(%ebp) +c0101035: c6 45 f1 0d movb $0xd,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101039: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c010103d: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101041: ee out %al,(%dx) +} +c0101042: 90 nop +c0101043: 66 c7 45 f6 7a 03 movw $0x37a,-0xa(%ebp) +c0101049: c6 45 f5 08 movb $0x8,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010104d: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0101051: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101055: ee out %al,(%dx) +} +c0101056: 90 nop + outb(LPTPORT + 2, 0x08 | 0x04 | 0x01); + outb(LPTPORT + 2, 0x08); +} +c0101057: 90 nop +c0101058: 89 ec mov %ebp,%esp +c010105a: 5d pop %ebp +c010105b: c3 ret + +c010105c : + +/* lpt_putc - copy console output to parallel port */ +static void +lpt_putc(int c) { +c010105c: 55 push %ebp +c010105d: 89 e5 mov %esp,%ebp +c010105f: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c0101062: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c0101066: 74 0d je c0101075 + lpt_putc_sub(c); +c0101068: 8b 45 08 mov 0x8(%ebp),%eax +c010106b: 89 04 24 mov %eax,(%esp) +c010106e: e8 6b ff ff ff call c0100fde + else { + lpt_putc_sub('\b'); + lpt_putc_sub(' '); + lpt_putc_sub('\b'); + } +} +c0101073: eb 24 jmp c0101099 + lpt_putc_sub('\b'); +c0101075: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c010107c: e8 5d ff ff ff call c0100fde + lpt_putc_sub(' '); +c0101081: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0101088: e8 51 ff ff ff call c0100fde + lpt_putc_sub('\b'); +c010108d: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101094: e8 45 ff ff ff call c0100fde +} +c0101099: 90 nop +c010109a: 89 ec mov %ebp,%esp +c010109c: 5d pop %ebp +c010109d: c3 ret + +c010109e : + +/* cga_putc - print character to console */ +static void +cga_putc(int c) { +c010109e: 55 push %ebp +c010109f: 89 e5 mov %esp,%ebp +c01010a1: 83 ec 38 sub $0x38,%esp +c01010a4: 89 5d fc mov %ebx,-0x4(%ebp) + // set black on white + if (!(c & ~0xFF)) { +c01010a7: 8b 45 08 mov 0x8(%ebp),%eax +c01010aa: 25 00 ff ff ff and $0xffffff00,%eax +c01010af: 85 c0 test %eax,%eax +c01010b1: 75 07 jne c01010ba + c |= 0x0700; +c01010b3: 81 4d 08 00 07 00 00 orl $0x700,0x8(%ebp) + } + + switch (c & 0xff) { +c01010ba: 8b 45 08 mov 0x8(%ebp),%eax +c01010bd: 0f b6 c0 movzbl %al,%eax +c01010c0: 83 f8 0d cmp $0xd,%eax +c01010c3: 74 72 je c0101137 +c01010c5: 83 f8 0d cmp $0xd,%eax +c01010c8: 0f 8f a3 00 00 00 jg c0101171 +c01010ce: 83 f8 08 cmp $0x8,%eax +c01010d1: 74 0a je c01010dd +c01010d3: 83 f8 0a cmp $0xa,%eax +c01010d6: 74 4c je c0101124 +c01010d8: e9 94 00 00 00 jmp c0101171 + case '\b': + if (crt_pos > 0) { +c01010dd: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c01010e4: 85 c0 test %eax,%eax +c01010e6: 0f 84 af 00 00 00 je c010119b + crt_pos --; +c01010ec: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c01010f3: 48 dec %eax +c01010f4: 0f b7 c0 movzwl %ax,%eax +c01010f7: 66 a3 44 54 12 c0 mov %ax,0xc0125444 + crt_buf[crt_pos] = (c & ~0xff) | ' '; +c01010fd: 8b 45 08 mov 0x8(%ebp),%eax +c0101100: 98 cwtl +c0101101: 25 00 ff ff ff and $0xffffff00,%eax +c0101106: 98 cwtl +c0101107: 83 c8 20 or $0x20,%eax +c010110a: 98 cwtl +c010110b: 8b 0d 40 54 12 c0 mov 0xc0125440,%ecx +c0101111: 0f b7 15 44 54 12 c0 movzwl 0xc0125444,%edx +c0101118: 01 d2 add %edx,%edx +c010111a: 01 ca add %ecx,%edx +c010111c: 0f b7 c0 movzwl %ax,%eax +c010111f: 66 89 02 mov %ax,(%edx) + } + break; +c0101122: eb 77 jmp c010119b + case '\n': + crt_pos += CRT_COLS; +c0101124: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c010112b: 83 c0 50 add $0x50,%eax +c010112e: 0f b7 c0 movzwl %ax,%eax +c0101131: 66 a3 44 54 12 c0 mov %ax,0xc0125444 + case '\r': + crt_pos -= (crt_pos % CRT_COLS); +c0101137: 0f b7 1d 44 54 12 c0 movzwl 0xc0125444,%ebx +c010113e: 0f b7 0d 44 54 12 c0 movzwl 0xc0125444,%ecx +c0101145: ba cd cc cc cc mov $0xcccccccd,%edx +c010114a: 89 c8 mov %ecx,%eax +c010114c: f7 e2 mul %edx +c010114e: c1 ea 06 shr $0x6,%edx +c0101151: 89 d0 mov %edx,%eax +c0101153: c1 e0 02 shl $0x2,%eax +c0101156: 01 d0 add %edx,%eax +c0101158: c1 e0 04 shl $0x4,%eax +c010115b: 29 c1 sub %eax,%ecx +c010115d: 89 ca mov %ecx,%edx +c010115f: 0f b7 d2 movzwl %dx,%edx +c0101162: 89 d8 mov %ebx,%eax +c0101164: 29 d0 sub %edx,%eax +c0101166: 0f b7 c0 movzwl %ax,%eax +c0101169: 66 a3 44 54 12 c0 mov %ax,0xc0125444 + break; +c010116f: eb 2b jmp c010119c + default: + crt_buf[crt_pos ++] = c; // write the character +c0101171: 8b 0d 40 54 12 c0 mov 0xc0125440,%ecx +c0101177: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c010117e: 8d 50 01 lea 0x1(%eax),%edx +c0101181: 0f b7 d2 movzwl %dx,%edx +c0101184: 66 89 15 44 54 12 c0 mov %dx,0xc0125444 +c010118b: 01 c0 add %eax,%eax +c010118d: 8d 14 01 lea (%ecx,%eax,1),%edx +c0101190: 8b 45 08 mov 0x8(%ebp),%eax +c0101193: 0f b7 c0 movzwl %ax,%eax +c0101196: 66 89 02 mov %ax,(%edx) + break; +c0101199: eb 01 jmp c010119c + break; +c010119b: 90 nop + } + + // What is the purpose of this? + if (crt_pos >= CRT_SIZE) { +c010119c: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c01011a3: 3d cf 07 00 00 cmp $0x7cf,%eax +c01011a8: 76 5e jbe c0101208 + int i; + memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); +c01011aa: a1 40 54 12 c0 mov 0xc0125440,%eax +c01011af: 8d 90 a0 00 00 00 lea 0xa0(%eax),%edx +c01011b5: a1 40 54 12 c0 mov 0xc0125440,%eax +c01011ba: c7 44 24 08 00 0f 00 movl $0xf00,0x8(%esp) +c01011c1: 00 +c01011c2: 89 54 24 04 mov %edx,0x4(%esp) +c01011c6: 89 04 24 mov %eax,(%esp) +c01011c9: e8 42 7a 00 00 call c0108c10 + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01011ce: c7 45 f4 80 07 00 00 movl $0x780,-0xc(%ebp) +c01011d5: eb 15 jmp c01011ec + crt_buf[i] = 0x0700 | ' '; +c01011d7: 8b 15 40 54 12 c0 mov 0xc0125440,%edx +c01011dd: 8b 45 f4 mov -0xc(%ebp),%eax +c01011e0: 01 c0 add %eax,%eax +c01011e2: 01 d0 add %edx,%eax +c01011e4: 66 c7 00 20 07 movw $0x720,(%eax) + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01011e9: ff 45 f4 incl -0xc(%ebp) +c01011ec: 81 7d f4 cf 07 00 00 cmpl $0x7cf,-0xc(%ebp) +c01011f3: 7e e2 jle c01011d7 + } + crt_pos -= CRT_COLS; +c01011f5: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c01011fc: 83 e8 50 sub $0x50,%eax +c01011ff: 0f b7 c0 movzwl %ax,%eax +c0101202: 66 a3 44 54 12 c0 mov %ax,0xc0125444 + } + + // move that little blinky thing + outb(addr_6845, 14); +c0101208: 0f b7 05 46 54 12 c0 movzwl 0xc0125446,%eax +c010120f: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c0101213: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101217: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c010121b: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c010121f: ee out %al,(%dx) +} +c0101220: 90 nop + outb(addr_6845 + 1, crt_pos >> 8); +c0101221: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c0101228: c1 e8 08 shr $0x8,%eax +c010122b: 0f b7 c0 movzwl %ax,%eax +c010122e: 0f b6 c0 movzbl %al,%eax +c0101231: 0f b7 15 46 54 12 c0 movzwl 0xc0125446,%edx +c0101238: 42 inc %edx +c0101239: 0f b7 d2 movzwl %dx,%edx +c010123c: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101240: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101243: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101247: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c010124b: ee out %al,(%dx) +} +c010124c: 90 nop + outb(addr_6845, 15); +c010124d: 0f b7 05 46 54 12 c0 movzwl 0xc0125446,%eax +c0101254: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101258: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010125c: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101260: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101264: ee out %al,(%dx) +} +c0101265: 90 nop + outb(addr_6845 + 1, crt_pos); +c0101266: 0f b7 05 44 54 12 c0 movzwl 0xc0125444,%eax +c010126d: 0f b6 c0 movzbl %al,%eax +c0101270: 0f b7 15 46 54 12 c0 movzwl 0xc0125446,%edx +c0101277: 42 inc %edx +c0101278: 0f b7 d2 movzwl %dx,%edx +c010127b: 66 89 55 f2 mov %dx,-0xe(%ebp) +c010127f: 88 45 f1 mov %al,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101282: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0101286: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c010128a: ee out %al,(%dx) +} +c010128b: 90 nop +} +c010128c: 90 nop +c010128d: 8b 5d fc mov -0x4(%ebp),%ebx +c0101290: 89 ec mov %ebp,%esp +c0101292: 5d pop %ebp +c0101293: c3 ret + +c0101294 : + +static void +serial_putc_sub(int c) { +c0101294: 55 push %ebp +c0101295: 89 e5 mov %esp,%ebp +c0101297: 83 ec 10 sub $0x10,%esp + int i; + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c010129a: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c01012a1: eb 08 jmp c01012ab + delay(); +c01012a3: e8 16 fb ff ff call c0100dbe + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c01012a8: ff 45 fc incl -0x4(%ebp) +c01012ab: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01012b1: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c01012b5: 89 c2 mov %eax,%edx +c01012b7: ec in (%dx),%al +c01012b8: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c01012bb: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01012bf: 0f b6 c0 movzbl %al,%eax +c01012c2: 83 e0 20 and $0x20,%eax +c01012c5: 85 c0 test %eax,%eax +c01012c7: 75 09 jne c01012d2 +c01012c9: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c01012d0: 7e d1 jle c01012a3 + } + outb(COM1 + COM_TX, c); +c01012d2: 8b 45 08 mov 0x8(%ebp),%eax +c01012d5: 0f b6 c0 movzbl %al,%eax +c01012d8: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c01012de: 88 45 f5 mov %al,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01012e1: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c01012e5: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01012e9: ee out %al,(%dx) +} +c01012ea: 90 nop +} +c01012eb: 90 nop +c01012ec: 89 ec mov %ebp,%esp +c01012ee: 5d pop %ebp +c01012ef: c3 ret + +c01012f0 : + +/* serial_putc - print character to serial port */ +static void +serial_putc(int c) { +c01012f0: 55 push %ebp +c01012f1: 89 e5 mov %esp,%ebp +c01012f3: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c01012f6: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c01012fa: 74 0d je c0101309 + serial_putc_sub(c); +c01012fc: 8b 45 08 mov 0x8(%ebp),%eax +c01012ff: 89 04 24 mov %eax,(%esp) +c0101302: e8 8d ff ff ff call c0101294 + else { + serial_putc_sub('\b'); + serial_putc_sub(' '); + serial_putc_sub('\b'); + } +} +c0101307: eb 24 jmp c010132d + serial_putc_sub('\b'); +c0101309: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101310: e8 7f ff ff ff call c0101294 + serial_putc_sub(' '); +c0101315: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c010131c: e8 73 ff ff ff call c0101294 + serial_putc_sub('\b'); +c0101321: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101328: e8 67 ff ff ff call c0101294 +} +c010132d: 90 nop +c010132e: 89 ec mov %ebp,%esp +c0101330: 5d pop %ebp +c0101331: c3 ret + +c0101332 : +/* * + * cons_intr - called by device interrupt routines to feed input + * characters into the circular console input buffer. + * */ +static void +cons_intr(int (*proc)(void)) { +c0101332: 55 push %ebp +c0101333: 89 e5 mov %esp,%ebp +c0101335: 83 ec 18 sub $0x18,%esp + int c; + while ((c = (*proc)()) != -1) { +c0101338: eb 33 jmp c010136d + if (c != 0) { +c010133a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010133e: 74 2d je c010136d + cons.buf[cons.wpos ++] = c; +c0101340: a1 64 56 12 c0 mov 0xc0125664,%eax +c0101345: 8d 50 01 lea 0x1(%eax),%edx +c0101348: 89 15 64 56 12 c0 mov %edx,0xc0125664 +c010134e: 8b 55 f4 mov -0xc(%ebp),%edx +c0101351: 88 90 60 54 12 c0 mov %dl,-0x3fedaba0(%eax) + if (cons.wpos == CONSBUFSIZE) { +c0101357: a1 64 56 12 c0 mov 0xc0125664,%eax +c010135c: 3d 00 02 00 00 cmp $0x200,%eax +c0101361: 75 0a jne c010136d + cons.wpos = 0; +c0101363: c7 05 64 56 12 c0 00 movl $0x0,0xc0125664 +c010136a: 00 00 00 + while ((c = (*proc)()) != -1) { +c010136d: 8b 45 08 mov 0x8(%ebp),%eax +c0101370: ff d0 call *%eax +c0101372: 89 45 f4 mov %eax,-0xc(%ebp) +c0101375: 83 7d f4 ff cmpl $0xffffffff,-0xc(%ebp) +c0101379: 75 bf jne c010133a + } + } + } +} +c010137b: 90 nop +c010137c: 90 nop +c010137d: 89 ec mov %ebp,%esp +c010137f: 5d pop %ebp +c0101380: c3 ret + +c0101381 : + +/* serial_proc_data - get data from serial port */ +static int +serial_proc_data(void) { +c0101381: 55 push %ebp +c0101382: 89 e5 mov %esp,%ebp +c0101384: 83 ec 10 sub $0x10,%esp +c0101387: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c010138d: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0101391: 89 c2 mov %eax,%edx +c0101393: ec in (%dx),%al +c0101394: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c0101397: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) { +c010139b: 0f b6 c0 movzbl %al,%eax +c010139e: 83 e0 01 and $0x1,%eax +c01013a1: 85 c0 test %eax,%eax +c01013a3: 75 07 jne c01013ac + return -1; +c01013a5: b8 ff ff ff ff mov $0xffffffff,%eax +c01013aa: eb 2a jmp c01013d6 +c01013ac: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01013b2: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c01013b6: 89 c2 mov %eax,%edx +c01013b8: ec in (%dx),%al +c01013b9: 88 45 f5 mov %al,-0xb(%ebp) + return data; +c01013bc: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + } + int c = inb(COM1 + COM_RX); +c01013c0: 0f b6 c0 movzbl %al,%eax +c01013c3: 89 45 fc mov %eax,-0x4(%ebp) + if (c == 127) { +c01013c6: 83 7d fc 7f cmpl $0x7f,-0x4(%ebp) +c01013ca: 75 07 jne c01013d3 + c = '\b'; +c01013cc: c7 45 fc 08 00 00 00 movl $0x8,-0x4(%ebp) + } + return c; +c01013d3: 8b 45 fc mov -0x4(%ebp),%eax +} +c01013d6: 89 ec mov %ebp,%esp +c01013d8: 5d pop %ebp +c01013d9: c3 ret + +c01013da : + +/* serial_intr - try to feed input characters from serial port */ +void +serial_intr(void) { +c01013da: 55 push %ebp +c01013db: 89 e5 mov %esp,%ebp +c01013dd: 83 ec 18 sub $0x18,%esp + if (serial_exists) { +c01013e0: a1 48 54 12 c0 mov 0xc0125448,%eax +c01013e5: 85 c0 test %eax,%eax +c01013e7: 74 0c je c01013f5 + cons_intr(serial_proc_data); +c01013e9: c7 04 24 81 13 10 c0 movl $0xc0101381,(%esp) +c01013f0: e8 3d ff ff ff call c0101332 + } +} +c01013f5: 90 nop +c01013f6: 89 ec mov %ebp,%esp +c01013f8: 5d pop %ebp +c01013f9: c3 ret + +c01013fa : + * + * The kbd_proc_data() function gets data from the keyboard. + * If we finish a character, return it, else 0. And return -1 if no data. + * */ +static int +kbd_proc_data(void) { +c01013fa: 55 push %ebp +c01013fb: 89 e5 mov %esp,%ebp +c01013fd: 83 ec 38 sub $0x38,%esp +c0101400: 66 c7 45 f0 64 00 movw $0x64,-0x10(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0101406: 8b 45 f0 mov -0x10(%ebp),%eax +c0101409: 89 c2 mov %eax,%edx +c010140b: ec in (%dx),%al +c010140c: 88 45 ef mov %al,-0x11(%ebp) + return data; +c010140f: 0f b6 45 ef movzbl -0x11(%ebp),%eax + int c; + uint8_t data; + static uint32_t shift; + + if ((inb(KBSTATP) & KBS_DIB) == 0) { +c0101413: 0f b6 c0 movzbl %al,%eax +c0101416: 83 e0 01 and $0x1,%eax +c0101419: 85 c0 test %eax,%eax +c010141b: 75 0a jne c0101427 + return -1; +c010141d: b8 ff ff ff ff mov $0xffffffff,%eax +c0101422: e9 56 01 00 00 jmp c010157d +c0101427: 66 c7 45 ec 60 00 movw $0x60,-0x14(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c010142d: 8b 45 ec mov -0x14(%ebp),%eax +c0101430: 89 c2 mov %eax,%edx +c0101432: ec in (%dx),%al +c0101433: 88 45 eb mov %al,-0x15(%ebp) + return data; +c0101436: 0f b6 45 eb movzbl -0x15(%ebp),%eax + } + + data = inb(KBDATAP); +c010143a: 88 45 f3 mov %al,-0xd(%ebp) + + if (data == 0xE0) { +c010143d: 80 7d f3 e0 cmpb $0xe0,-0xd(%ebp) +c0101441: 75 17 jne c010145a + // E0 escape character + shift |= E0ESC; +c0101443: a1 68 56 12 c0 mov 0xc0125668,%eax +c0101448: 83 c8 40 or $0x40,%eax +c010144b: a3 68 56 12 c0 mov %eax,0xc0125668 + return 0; +c0101450: b8 00 00 00 00 mov $0x0,%eax +c0101455: e9 23 01 00 00 jmp c010157d + } else if (data & 0x80) { +c010145a: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010145e: 84 c0 test %al,%al +c0101460: 79 45 jns c01014a7 + // Key released + data = (shift & E0ESC ? data : data & 0x7F); +c0101462: a1 68 56 12 c0 mov 0xc0125668,%eax +c0101467: 83 e0 40 and $0x40,%eax +c010146a: 85 c0 test %eax,%eax +c010146c: 75 08 jne c0101476 +c010146e: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101472: 24 7f and $0x7f,%al +c0101474: eb 04 jmp c010147a +c0101476: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010147a: 88 45 f3 mov %al,-0xd(%ebp) + shift &= ~(shiftcode[data] | E0ESC); +c010147d: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101481: 0f b6 80 40 20 12 c0 movzbl -0x3feddfc0(%eax),%eax +c0101488: 0c 40 or $0x40,%al +c010148a: 0f b6 c0 movzbl %al,%eax +c010148d: f7 d0 not %eax +c010148f: 89 c2 mov %eax,%edx +c0101491: a1 68 56 12 c0 mov 0xc0125668,%eax +c0101496: 21 d0 and %edx,%eax +c0101498: a3 68 56 12 c0 mov %eax,0xc0125668 + return 0; +c010149d: b8 00 00 00 00 mov $0x0,%eax +c01014a2: e9 d6 00 00 00 jmp c010157d + } else if (shift & E0ESC) { +c01014a7: a1 68 56 12 c0 mov 0xc0125668,%eax +c01014ac: 83 e0 40 and $0x40,%eax +c01014af: 85 c0 test %eax,%eax +c01014b1: 74 11 je c01014c4 + // Last character was an E0 escape; or with 0x80 + data |= 0x80; +c01014b3: 80 4d f3 80 orb $0x80,-0xd(%ebp) + shift &= ~E0ESC; +c01014b7: a1 68 56 12 c0 mov 0xc0125668,%eax +c01014bc: 83 e0 bf and $0xffffffbf,%eax +c01014bf: a3 68 56 12 c0 mov %eax,0xc0125668 + } + + shift |= shiftcode[data]; +c01014c4: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014c8: 0f b6 80 40 20 12 c0 movzbl -0x3feddfc0(%eax),%eax +c01014cf: 0f b6 d0 movzbl %al,%edx +c01014d2: a1 68 56 12 c0 mov 0xc0125668,%eax +c01014d7: 09 d0 or %edx,%eax +c01014d9: a3 68 56 12 c0 mov %eax,0xc0125668 + shift ^= togglecode[data]; +c01014de: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014e2: 0f b6 80 40 21 12 c0 movzbl -0x3feddec0(%eax),%eax +c01014e9: 0f b6 d0 movzbl %al,%edx +c01014ec: a1 68 56 12 c0 mov 0xc0125668,%eax +c01014f1: 31 d0 xor %edx,%eax +c01014f3: a3 68 56 12 c0 mov %eax,0xc0125668 + + c = charcode[shift & (CTL | SHIFT)][data]; +c01014f8: a1 68 56 12 c0 mov 0xc0125668,%eax +c01014fd: 83 e0 03 and $0x3,%eax +c0101500: 8b 14 85 40 25 12 c0 mov -0x3feddac0(,%eax,4),%edx +c0101507: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010150b: 01 d0 add %edx,%eax +c010150d: 0f b6 00 movzbl (%eax),%eax +c0101510: 0f b6 c0 movzbl %al,%eax +c0101513: 89 45 f4 mov %eax,-0xc(%ebp) + if (shift & CAPSLOCK) { +c0101516: a1 68 56 12 c0 mov 0xc0125668,%eax +c010151b: 83 e0 08 and $0x8,%eax +c010151e: 85 c0 test %eax,%eax +c0101520: 74 22 je c0101544 + if ('a' <= c && c <= 'z') +c0101522: 83 7d f4 60 cmpl $0x60,-0xc(%ebp) +c0101526: 7e 0c jle c0101534 +c0101528: 83 7d f4 7a cmpl $0x7a,-0xc(%ebp) +c010152c: 7f 06 jg c0101534 + c += 'A' - 'a'; +c010152e: 83 6d f4 20 subl $0x20,-0xc(%ebp) +c0101532: eb 10 jmp c0101544 + else if ('A' <= c && c <= 'Z') +c0101534: 83 7d f4 40 cmpl $0x40,-0xc(%ebp) +c0101538: 7e 0a jle c0101544 +c010153a: 83 7d f4 5a cmpl $0x5a,-0xc(%ebp) +c010153e: 7f 04 jg c0101544 + c += 'a' - 'A'; +c0101540: 83 45 f4 20 addl $0x20,-0xc(%ebp) + } + + // Process special keys + // Ctrl-Alt-Del: reboot + if (!(~shift & (CTL | ALT)) && c == KEY_DEL) { +c0101544: a1 68 56 12 c0 mov 0xc0125668,%eax +c0101549: f7 d0 not %eax +c010154b: 83 e0 06 and $0x6,%eax +c010154e: 85 c0 test %eax,%eax +c0101550: 75 28 jne c010157a +c0101552: 81 7d f4 e9 00 00 00 cmpl $0xe9,-0xc(%ebp) +c0101559: 75 1f jne c010157a + cprintf("Rebooting!\n"); +c010155b: c7 04 24 67 90 10 c0 movl $0xc0109067,(%esp) +c0101562: e8 0e ee ff ff call c0100375 +c0101567: 66 c7 45 e8 92 00 movw $0x92,-0x18(%ebp) +c010156d: c6 45 e7 03 movb $0x3,-0x19(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101571: 0f b6 45 e7 movzbl -0x19(%ebp),%eax +c0101575: 8b 55 e8 mov -0x18(%ebp),%edx +c0101578: ee out %al,(%dx) +} +c0101579: 90 nop + outb(0x92, 0x3); // courtesy of Chris Frost + } + return c; +c010157a: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010157d: 89 ec mov %ebp,%esp +c010157f: 5d pop %ebp +c0101580: c3 ret + +c0101581 : + +/* kbd_intr - try to feed input characters from keyboard */ +static void +kbd_intr(void) { +c0101581: 55 push %ebp +c0101582: 89 e5 mov %esp,%ebp +c0101584: 83 ec 18 sub $0x18,%esp + cons_intr(kbd_proc_data); +c0101587: c7 04 24 fa 13 10 c0 movl $0xc01013fa,(%esp) +c010158e: e8 9f fd ff ff call c0101332 +} +c0101593: 90 nop +c0101594: 89 ec mov %ebp,%esp +c0101596: 5d pop %ebp +c0101597: c3 ret + +c0101598 : + +static void +kbd_init(void) { +c0101598: 55 push %ebp +c0101599: 89 e5 mov %esp,%ebp +c010159b: 83 ec 18 sub $0x18,%esp + // drain the kbd buffer + kbd_intr(); +c010159e: e8 de ff ff ff call c0101581 + pic_enable(IRQ_KBD); +c01015a3: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01015aa: e8 ae 09 00 00 call c0101f5d +} +c01015af: 90 nop +c01015b0: 89 ec mov %ebp,%esp +c01015b2: 5d pop %ebp +c01015b3: c3 ret + +c01015b4 : + +/* cons_init - initializes the console devices */ +void +cons_init(void) { +c01015b4: 55 push %ebp +c01015b5: 89 e5 mov %esp,%ebp +c01015b7: 83 ec 18 sub $0x18,%esp + cga_init(); +c01015ba: e8 4a f8 ff ff call c0100e09 + serial_init(); +c01015bf: e8 2d f9 ff ff call c0100ef1 + kbd_init(); +c01015c4: e8 cf ff ff ff call c0101598 + if (!serial_exists) { +c01015c9: a1 48 54 12 c0 mov 0xc0125448,%eax +c01015ce: 85 c0 test %eax,%eax +c01015d0: 75 0c jne c01015de + cprintf("serial port does not exist!!\n"); +c01015d2: c7 04 24 73 90 10 c0 movl $0xc0109073,(%esp) +c01015d9: e8 97 ed ff ff call c0100375 + } +} +c01015de: 90 nop +c01015df: 89 ec mov %ebp,%esp +c01015e1: 5d pop %ebp +c01015e2: c3 ret + +c01015e3 : + +/* cons_putc - print a single character @c to console devices */ +void +cons_putc(int c) { +c01015e3: 55 push %ebp +c01015e4: 89 e5 mov %esp,%ebp +c01015e6: 83 ec 28 sub $0x28,%esp + bool intr_flag; + local_intr_save(intr_flag); +c01015e9: e8 8e f7 ff ff call c0100d7c <__intr_save> +c01015ee: 89 45 f4 mov %eax,-0xc(%ebp) + { + lpt_putc(c); +c01015f1: 8b 45 08 mov 0x8(%ebp),%eax +c01015f4: 89 04 24 mov %eax,(%esp) +c01015f7: e8 60 fa ff ff call c010105c + cga_putc(c); +c01015fc: 8b 45 08 mov 0x8(%ebp),%eax +c01015ff: 89 04 24 mov %eax,(%esp) +c0101602: e8 97 fa ff ff call c010109e + serial_putc(c); +c0101607: 8b 45 08 mov 0x8(%ebp),%eax +c010160a: 89 04 24 mov %eax,(%esp) +c010160d: e8 de fc ff ff call c01012f0 + } + local_intr_restore(intr_flag); +c0101612: 8b 45 f4 mov -0xc(%ebp),%eax +c0101615: 89 04 24 mov %eax,(%esp) +c0101618: e8 8b f7 ff ff call c0100da8 <__intr_restore> +} +c010161d: 90 nop +c010161e: 89 ec mov %ebp,%esp +c0101620: 5d pop %ebp +c0101621: c3 ret + +c0101622 : +/* * + * cons_getc - return the next input character from console, + * or 0 if none waiting. + * */ +int +cons_getc(void) { +c0101622: 55 push %ebp +c0101623: 89 e5 mov %esp,%ebp +c0101625: 83 ec 28 sub $0x28,%esp + int c = 0; +c0101628: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + local_intr_save(intr_flag); +c010162f: e8 48 f7 ff ff call c0100d7c <__intr_save> +c0101634: 89 45 f0 mov %eax,-0x10(%ebp) + { + // poll for any pending input characters, + // so that this function works even when interrupts are disabled + // (e.g., when called from the kernel monitor). + serial_intr(); +c0101637: e8 9e fd ff ff call c01013da + kbd_intr(); +c010163c: e8 40 ff ff ff call c0101581 + + // grab the next character from the input buffer. + if (cons.rpos != cons.wpos) { +c0101641: 8b 15 60 56 12 c0 mov 0xc0125660,%edx +c0101647: a1 64 56 12 c0 mov 0xc0125664,%eax +c010164c: 39 c2 cmp %eax,%edx +c010164e: 74 31 je c0101681 + c = cons.buf[cons.rpos ++]; +c0101650: a1 60 56 12 c0 mov 0xc0125660,%eax +c0101655: 8d 50 01 lea 0x1(%eax),%edx +c0101658: 89 15 60 56 12 c0 mov %edx,0xc0125660 +c010165e: 0f b6 80 60 54 12 c0 movzbl -0x3fedaba0(%eax),%eax +c0101665: 0f b6 c0 movzbl %al,%eax +c0101668: 89 45 f4 mov %eax,-0xc(%ebp) + if (cons.rpos == CONSBUFSIZE) { +c010166b: a1 60 56 12 c0 mov 0xc0125660,%eax +c0101670: 3d 00 02 00 00 cmp $0x200,%eax +c0101675: 75 0a jne c0101681 + cons.rpos = 0; +c0101677: c7 05 60 56 12 c0 00 movl $0x0,0xc0125660 +c010167e: 00 00 00 + } + } + } + local_intr_restore(intr_flag); +c0101681: 8b 45 f0 mov -0x10(%ebp),%eax +c0101684: 89 04 24 mov %eax,(%esp) +c0101687: e8 1c f7 ff ff call c0100da8 <__intr_restore> + return c; +c010168c: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010168f: 89 ec mov %ebp,%esp +c0101691: 5d pop %ebp +c0101692: c3 ret + +c0101693 : + unsigned int size; // Size in Sectors + unsigned char model[41]; // Model in String +} ide_devices[MAX_IDE]; + +static int +ide_wait_ready(unsigned short iobase, bool check_error) { +c0101693: 55 push %ebp +c0101694: 89 e5 mov %esp,%ebp +c0101696: 83 ec 14 sub $0x14,%esp +c0101699: 8b 45 08 mov 0x8(%ebp),%eax +c010169c: 66 89 45 ec mov %ax,-0x14(%ebp) + int r; + while ((r = inb(iobase + ISA_STATUS)) & IDE_BSY) +c01016a0: 90 nop +c01016a1: 8b 45 ec mov -0x14(%ebp),%eax +c01016a4: 83 c0 07 add $0x7,%eax +c01016a7: 0f b7 c0 movzwl %ax,%eax +c01016aa: 66 89 45 fa mov %ax,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01016ae: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c01016b2: 89 c2 mov %eax,%edx +c01016b4: ec in (%dx),%al +c01016b5: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c01016b8: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01016bc: 0f b6 c0 movzbl %al,%eax +c01016bf: 89 45 fc mov %eax,-0x4(%ebp) +c01016c2: 8b 45 fc mov -0x4(%ebp),%eax +c01016c5: 25 80 00 00 00 and $0x80,%eax +c01016ca: 85 c0 test %eax,%eax +c01016cc: 75 d3 jne c01016a1 + /* nothing */; + if (check_error && (r & (IDE_DF | IDE_ERR)) != 0) { +c01016ce: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01016d2: 74 11 je c01016e5 +c01016d4: 8b 45 fc mov -0x4(%ebp),%eax +c01016d7: 83 e0 21 and $0x21,%eax +c01016da: 85 c0 test %eax,%eax +c01016dc: 74 07 je c01016e5 + return -1; +c01016de: b8 ff ff ff ff mov $0xffffffff,%eax +c01016e3: eb 05 jmp c01016ea + } + return 0; +c01016e5: b8 00 00 00 00 mov $0x0,%eax +} +c01016ea: 89 ec mov %ebp,%esp +c01016ec: 5d pop %ebp +c01016ed: c3 ret + +c01016ee : + +void +ide_init(void) { +c01016ee: 55 push %ebp +c01016ef: 89 e5 mov %esp,%ebp +c01016f1: 57 push %edi +c01016f2: 53 push %ebx +c01016f3: 81 ec 50 02 00 00 sub $0x250,%esp + static_assert((SECTSIZE % 4) == 0); + unsigned short ideno, iobase; + for (ideno = 0; ideno < MAX_IDE; ideno ++) { +c01016f9: 66 c7 45 f6 00 00 movw $0x0,-0xa(%ebp) +c01016ff: e9 bd 02 00 00 jmp c01019c1 + /* assume that no device here */ + ide_devices[ideno].valid = 0; +c0101704: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101708: 89 d0 mov %edx,%eax +c010170a: c1 e0 03 shl $0x3,%eax +c010170d: 29 d0 sub %edx,%eax +c010170f: c1 e0 03 shl $0x3,%eax +c0101712: 05 80 56 12 c0 add $0xc0125680,%eax +c0101717: c6 00 00 movb $0x0,(%eax) + + iobase = IO_BASE(ideno); +c010171a: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010171e: d1 e8 shr %eax +c0101720: 0f b7 c0 movzwl %ax,%eax +c0101723: 8b 04 85 94 90 10 c0 mov -0x3fef6f6c(,%eax,4),%eax +c010172a: 66 89 45 ea mov %ax,-0x16(%ebp) + + /* wait device ready */ + ide_wait_ready(iobase, 0); +c010172e: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0101732: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0101739: 00 +c010173a: 89 04 24 mov %eax,(%esp) +c010173d: e8 51 ff ff ff call c0101693 + + /* step1: select drive */ + outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4)); +c0101742: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0101746: c1 e0 04 shl $0x4,%eax +c0101749: 24 10 and $0x10,%al +c010174b: 0c e0 or $0xe0,%al +c010174d: 0f b6 c0 movzbl %al,%eax +c0101750: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0101754: 83 c2 06 add $0x6,%edx +c0101757: 0f b7 d2 movzwl %dx,%edx +c010175a: 66 89 55 ca mov %dx,-0x36(%ebp) +c010175e: 88 45 c9 mov %al,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101761: 0f b6 45 c9 movzbl -0x37(%ebp),%eax +c0101765: 0f b7 55 ca movzwl -0x36(%ebp),%edx +c0101769: ee out %al,(%dx) +} +c010176a: 90 nop + ide_wait_ready(iobase, 0); +c010176b: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c010176f: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0101776: 00 +c0101777: 89 04 24 mov %eax,(%esp) +c010177a: e8 14 ff ff ff call c0101693 + + /* step2: send ATA identify command */ + outb(iobase + ISA_COMMAND, IDE_CMD_IDENTIFY); +c010177f: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0101783: 83 c0 07 add $0x7,%eax +c0101786: 0f b7 c0 movzwl %ax,%eax +c0101789: 66 89 45 ce mov %ax,-0x32(%ebp) +c010178d: c6 45 cd ec movb $0xec,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101791: 0f b6 45 cd movzbl -0x33(%ebp),%eax +c0101795: 0f b7 55 ce movzwl -0x32(%ebp),%edx +c0101799: ee out %al,(%dx) +} +c010179a: 90 nop + ide_wait_ready(iobase, 0); +c010179b: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c010179f: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01017a6: 00 +c01017a7: 89 04 24 mov %eax,(%esp) +c01017aa: e8 e4 fe ff ff call c0101693 + + /* step3: polling */ + if (inb(iobase + ISA_STATUS) == 0 || ide_wait_ready(iobase, 1) != 0) { +c01017af: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c01017b3: 83 c0 07 add $0x7,%eax +c01017b6: 0f b7 c0 movzwl %ax,%eax +c01017b9: 66 89 45 d2 mov %ax,-0x2e(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01017bd: 0f b7 45 d2 movzwl -0x2e(%ebp),%eax +c01017c1: 89 c2 mov %eax,%edx +c01017c3: ec in (%dx),%al +c01017c4: 88 45 d1 mov %al,-0x2f(%ebp) + return data; +c01017c7: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c01017cb: 84 c0 test %al,%al +c01017cd: 0f 84 e4 01 00 00 je c01019b7 +c01017d3: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c01017d7: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01017de: 00 +c01017df: 89 04 24 mov %eax,(%esp) +c01017e2: e8 ac fe ff ff call c0101693 +c01017e7: 85 c0 test %eax,%eax +c01017e9: 0f 85 c8 01 00 00 jne c01019b7 + continue ; + } + + /* device is ok */ + ide_devices[ideno].valid = 1; +c01017ef: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01017f3: 89 d0 mov %edx,%eax +c01017f5: c1 e0 03 shl $0x3,%eax +c01017f8: 29 d0 sub %edx,%eax +c01017fa: c1 e0 03 shl $0x3,%eax +c01017fd: 05 80 56 12 c0 add $0xc0125680,%eax +c0101802: c6 00 01 movb $0x1,(%eax) + + /* read identification space of the device */ + unsigned int buffer[128]; + insl(iobase + ISA_DATA, buffer, sizeof(buffer) / sizeof(unsigned int)); +c0101805: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0101809: 89 45 c4 mov %eax,-0x3c(%ebp) +c010180c: 8d 85 bc fd ff ff lea -0x244(%ebp),%eax +c0101812: 89 45 c0 mov %eax,-0x40(%ebp) +c0101815: c7 45 bc 80 00 00 00 movl $0x80,-0x44(%ebp) + asm volatile ( +c010181c: 8b 55 c4 mov -0x3c(%ebp),%edx +c010181f: 8b 4d c0 mov -0x40(%ebp),%ecx +c0101822: 8b 45 bc mov -0x44(%ebp),%eax +c0101825: 89 cb mov %ecx,%ebx +c0101827: 89 df mov %ebx,%edi +c0101829: 89 c1 mov %eax,%ecx +c010182b: fc cld +c010182c: f2 6d repnz insl (%dx),%es:(%edi) +c010182e: 89 c8 mov %ecx,%eax +c0101830: 89 fb mov %edi,%ebx +c0101832: 89 5d c0 mov %ebx,-0x40(%ebp) +c0101835: 89 45 bc mov %eax,-0x44(%ebp) +} +c0101838: 90 nop + + unsigned char *ident = (unsigned char *)buffer; +c0101839: 8d 85 bc fd ff ff lea -0x244(%ebp),%eax +c010183f: 89 45 e4 mov %eax,-0x1c(%ebp) + unsigned int sectors; + unsigned int cmdsets = *(unsigned int *)(ident + IDE_IDENT_CMDSETS); +c0101842: 8b 45 e4 mov -0x1c(%ebp),%eax +c0101845: 8b 80 a4 00 00 00 mov 0xa4(%eax),%eax +c010184b: 89 45 e0 mov %eax,-0x20(%ebp) + /* device use 48-bits or 28-bits addressing */ + if (cmdsets & (1 << 26)) { +c010184e: 8b 45 e0 mov -0x20(%ebp),%eax +c0101851: 25 00 00 00 04 and $0x4000000,%eax +c0101856: 85 c0 test %eax,%eax +c0101858: 74 0e je c0101868 + sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA_EXT); +c010185a: 8b 45 e4 mov -0x1c(%ebp),%eax +c010185d: 8b 80 c8 00 00 00 mov 0xc8(%eax),%eax +c0101863: 89 45 f0 mov %eax,-0x10(%ebp) +c0101866: eb 09 jmp c0101871 + } + else { + sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA); +c0101868: 8b 45 e4 mov -0x1c(%ebp),%eax +c010186b: 8b 40 78 mov 0x78(%eax),%eax +c010186e: 89 45 f0 mov %eax,-0x10(%ebp) + } + ide_devices[ideno].sets = cmdsets; +c0101871: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101875: 89 d0 mov %edx,%eax +c0101877: c1 e0 03 shl $0x3,%eax +c010187a: 29 d0 sub %edx,%eax +c010187c: c1 e0 03 shl $0x3,%eax +c010187f: 8d 90 84 56 12 c0 lea -0x3feda97c(%eax),%edx +c0101885: 8b 45 e0 mov -0x20(%ebp),%eax +c0101888: 89 02 mov %eax,(%edx) + ide_devices[ideno].size = sectors; +c010188a: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c010188e: 89 d0 mov %edx,%eax +c0101890: c1 e0 03 shl $0x3,%eax +c0101893: 29 d0 sub %edx,%eax +c0101895: c1 e0 03 shl $0x3,%eax +c0101898: 8d 90 88 56 12 c0 lea -0x3feda978(%eax),%edx +c010189e: 8b 45 f0 mov -0x10(%ebp),%eax +c01018a1: 89 02 mov %eax,(%edx) + + /* check if supports LBA */ + assert((*(unsigned short *)(ident + IDE_IDENT_CAPABILITIES) & 0x200) != 0); +c01018a3: 8b 45 e4 mov -0x1c(%ebp),%eax +c01018a6: 83 c0 62 add $0x62,%eax +c01018a9: 0f b7 00 movzwl (%eax),%eax +c01018ac: 25 00 02 00 00 and $0x200,%eax +c01018b1: 85 c0 test %eax,%eax +c01018b3: 75 24 jne c01018d9 +c01018b5: c7 44 24 0c 9c 90 10 movl $0xc010909c,0xc(%esp) +c01018bc: c0 +c01018bd: c7 44 24 08 df 90 10 movl $0xc01090df,0x8(%esp) +c01018c4: c0 +c01018c5: c7 44 24 04 7d 00 00 movl $0x7d,0x4(%esp) +c01018cc: 00 +c01018cd: c7 04 24 f4 90 10 c0 movl $0xc01090f4,(%esp) +c01018d4: e8 69 f3 ff ff call c0100c42 <__panic> + + unsigned char *model = ide_devices[ideno].model, *data = ident + IDE_IDENT_MODEL; +c01018d9: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01018dd: 89 d0 mov %edx,%eax +c01018df: c1 e0 03 shl $0x3,%eax +c01018e2: 29 d0 sub %edx,%eax +c01018e4: c1 e0 03 shl $0x3,%eax +c01018e7: 05 80 56 12 c0 add $0xc0125680,%eax +c01018ec: 83 c0 0c add $0xc,%eax +c01018ef: 89 45 dc mov %eax,-0x24(%ebp) +c01018f2: 8b 45 e4 mov -0x1c(%ebp),%eax +c01018f5: 83 c0 36 add $0x36,%eax +c01018f8: 89 45 d8 mov %eax,-0x28(%ebp) + unsigned int i, length = 40; +c01018fb: c7 45 d4 28 00 00 00 movl $0x28,-0x2c(%ebp) + for (i = 0; i < length; i += 2) { +c0101902: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) +c0101909: eb 34 jmp c010193f + model[i] = data[i + 1], model[i + 1] = data[i]; +c010190b: 8b 45 ec mov -0x14(%ebp),%eax +c010190e: 8d 50 01 lea 0x1(%eax),%edx +c0101911: 8b 45 d8 mov -0x28(%ebp),%eax +c0101914: 01 c2 add %eax,%edx +c0101916: 8b 4d dc mov -0x24(%ebp),%ecx +c0101919: 8b 45 ec mov -0x14(%ebp),%eax +c010191c: 01 c8 add %ecx,%eax +c010191e: 0f b6 12 movzbl (%edx),%edx +c0101921: 88 10 mov %dl,(%eax) +c0101923: 8b 55 d8 mov -0x28(%ebp),%edx +c0101926: 8b 45 ec mov -0x14(%ebp),%eax +c0101929: 01 c2 add %eax,%edx +c010192b: 8b 45 ec mov -0x14(%ebp),%eax +c010192e: 8d 48 01 lea 0x1(%eax),%ecx +c0101931: 8b 45 dc mov -0x24(%ebp),%eax +c0101934: 01 c8 add %ecx,%eax +c0101936: 0f b6 12 movzbl (%edx),%edx +c0101939: 88 10 mov %dl,(%eax) + for (i = 0; i < length; i += 2) { +c010193b: 83 45 ec 02 addl $0x2,-0x14(%ebp) +c010193f: 8b 45 ec mov -0x14(%ebp),%eax +c0101942: 3b 45 d4 cmp -0x2c(%ebp),%eax +c0101945: 72 c4 jb c010190b + } + do { + model[i] = '\0'; +c0101947: 8b 55 dc mov -0x24(%ebp),%edx +c010194a: 8b 45 ec mov -0x14(%ebp),%eax +c010194d: 01 d0 add %edx,%eax +c010194f: c6 00 00 movb $0x0,(%eax) + } while (i -- > 0 && model[i] == ' '); +c0101952: 8b 45 ec mov -0x14(%ebp),%eax +c0101955: 8d 50 ff lea -0x1(%eax),%edx +c0101958: 89 55 ec mov %edx,-0x14(%ebp) +c010195b: 85 c0 test %eax,%eax +c010195d: 74 0f je c010196e +c010195f: 8b 55 dc mov -0x24(%ebp),%edx +c0101962: 8b 45 ec mov -0x14(%ebp),%eax +c0101965: 01 d0 add %edx,%eax +c0101967: 0f b6 00 movzbl (%eax),%eax +c010196a: 3c 20 cmp $0x20,%al +c010196c: 74 d9 je c0101947 + + cprintf("ide %d: %10u(sectors), '%s'.\n", ideno, ide_devices[ideno].size, ide_devices[ideno].model); +c010196e: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101972: 89 d0 mov %edx,%eax +c0101974: c1 e0 03 shl $0x3,%eax +c0101977: 29 d0 sub %edx,%eax +c0101979: c1 e0 03 shl $0x3,%eax +c010197c: 05 80 56 12 c0 add $0xc0125680,%eax +c0101981: 8d 48 0c lea 0xc(%eax),%ecx +c0101984: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101988: 89 d0 mov %edx,%eax +c010198a: c1 e0 03 shl $0x3,%eax +c010198d: 29 d0 sub %edx,%eax +c010198f: c1 e0 03 shl $0x3,%eax +c0101992: 05 88 56 12 c0 add $0xc0125688,%eax +c0101997: 8b 10 mov (%eax),%edx +c0101999: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010199d: 89 4c 24 0c mov %ecx,0xc(%esp) +c01019a1: 89 54 24 08 mov %edx,0x8(%esp) +c01019a5: 89 44 24 04 mov %eax,0x4(%esp) +c01019a9: c7 04 24 06 91 10 c0 movl $0xc0109106,(%esp) +c01019b0: e8 c0 e9 ff ff call c0100375 +c01019b5: eb 01 jmp c01019b8 + continue ; +c01019b7: 90 nop + for (ideno = 0; ideno < MAX_IDE; ideno ++) { +c01019b8: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c01019bc: 40 inc %eax +c01019bd: 66 89 45 f6 mov %ax,-0xa(%ebp) +c01019c1: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c01019c5: 83 f8 03 cmp $0x3,%eax +c01019c8: 0f 86 36 fd ff ff jbe c0101704 + } + + // enable ide interrupt + pic_enable(IRQ_IDE1); +c01019ce: c7 04 24 0e 00 00 00 movl $0xe,(%esp) +c01019d5: e8 83 05 00 00 call c0101f5d + pic_enable(IRQ_IDE2); +c01019da: c7 04 24 0f 00 00 00 movl $0xf,(%esp) +c01019e1: e8 77 05 00 00 call c0101f5d +} +c01019e6: 90 nop +c01019e7: 81 c4 50 02 00 00 add $0x250,%esp +c01019ed: 5b pop %ebx +c01019ee: 5f pop %edi +c01019ef: 5d pop %ebp +c01019f0: c3 ret + +c01019f1 : + +bool +ide_device_valid(unsigned short ideno) { +c01019f1: 55 push %ebp +c01019f2: 89 e5 mov %esp,%ebp +c01019f4: 83 ec 04 sub $0x4,%esp +c01019f7: 8b 45 08 mov 0x8(%ebp),%eax +c01019fa: 66 89 45 fc mov %ax,-0x4(%ebp) + return VALID_IDE(ideno); +c01019fe: 0f b7 45 fc movzwl -0x4(%ebp),%eax +c0101a02: 83 f8 03 cmp $0x3,%eax +c0101a05: 77 21 ja c0101a28 +c0101a07: 0f b7 55 fc movzwl -0x4(%ebp),%edx +c0101a0b: 89 d0 mov %edx,%eax +c0101a0d: c1 e0 03 shl $0x3,%eax +c0101a10: 29 d0 sub %edx,%eax +c0101a12: c1 e0 03 shl $0x3,%eax +c0101a15: 05 80 56 12 c0 add $0xc0125680,%eax +c0101a1a: 0f b6 00 movzbl (%eax),%eax +c0101a1d: 84 c0 test %al,%al +c0101a1f: 74 07 je c0101a28 +c0101a21: b8 01 00 00 00 mov $0x1,%eax +c0101a26: eb 05 jmp c0101a2d +c0101a28: b8 00 00 00 00 mov $0x0,%eax +} +c0101a2d: 89 ec mov %ebp,%esp +c0101a2f: 5d pop %ebp +c0101a30: c3 ret + +c0101a31 : + +size_t +ide_device_size(unsigned short ideno) { +c0101a31: 55 push %ebp +c0101a32: 89 e5 mov %esp,%ebp +c0101a34: 83 ec 08 sub $0x8,%esp +c0101a37: 8b 45 08 mov 0x8(%ebp),%eax +c0101a3a: 66 89 45 fc mov %ax,-0x4(%ebp) + if (ide_device_valid(ideno)) { +c0101a3e: 0f b7 45 fc movzwl -0x4(%ebp),%eax +c0101a42: 89 04 24 mov %eax,(%esp) +c0101a45: e8 a7 ff ff ff call c01019f1 +c0101a4a: 85 c0 test %eax,%eax +c0101a4c: 74 17 je c0101a65 + return ide_devices[ideno].size; +c0101a4e: 0f b7 55 fc movzwl -0x4(%ebp),%edx +c0101a52: 89 d0 mov %edx,%eax +c0101a54: c1 e0 03 shl $0x3,%eax +c0101a57: 29 d0 sub %edx,%eax +c0101a59: c1 e0 03 shl $0x3,%eax +c0101a5c: 05 88 56 12 c0 add $0xc0125688,%eax +c0101a61: 8b 00 mov (%eax),%eax +c0101a63: eb 05 jmp c0101a6a + } + return 0; +c0101a65: b8 00 00 00 00 mov $0x0,%eax +} +c0101a6a: 89 ec mov %ebp,%esp +c0101a6c: 5d pop %ebp +c0101a6d: c3 ret + +c0101a6e : + +int +ide_read_secs(unsigned short ideno, uint32_t secno, void *dst, size_t nsecs) { +c0101a6e: 55 push %ebp +c0101a6f: 89 e5 mov %esp,%ebp +c0101a71: 57 push %edi +c0101a72: 53 push %ebx +c0101a73: 83 ec 50 sub $0x50,%esp +c0101a76: 8b 45 08 mov 0x8(%ebp),%eax +c0101a79: 66 89 45 c4 mov %ax,-0x3c(%ebp) + assert(nsecs <= MAX_NSECS && VALID_IDE(ideno)); +c0101a7d: 81 7d 14 80 00 00 00 cmpl $0x80,0x14(%ebp) +c0101a84: 77 23 ja c0101aa9 +c0101a86: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101a8a: 83 f8 03 cmp $0x3,%eax +c0101a8d: 77 1a ja c0101aa9 +c0101a8f: 0f b7 55 c4 movzwl -0x3c(%ebp),%edx +c0101a93: 89 d0 mov %edx,%eax +c0101a95: c1 e0 03 shl $0x3,%eax +c0101a98: 29 d0 sub %edx,%eax +c0101a9a: c1 e0 03 shl $0x3,%eax +c0101a9d: 05 80 56 12 c0 add $0xc0125680,%eax +c0101aa2: 0f b6 00 movzbl (%eax),%eax +c0101aa5: 84 c0 test %al,%al +c0101aa7: 75 24 jne c0101acd +c0101aa9: c7 44 24 0c 24 91 10 movl $0xc0109124,0xc(%esp) +c0101ab0: c0 +c0101ab1: c7 44 24 08 df 90 10 movl $0xc01090df,0x8(%esp) +c0101ab8: c0 +c0101ab9: c7 44 24 04 9f 00 00 movl $0x9f,0x4(%esp) +c0101ac0: 00 +c0101ac1: c7 04 24 f4 90 10 c0 movl $0xc01090f4,(%esp) +c0101ac8: e8 75 f1 ff ff call c0100c42 <__panic> + assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS); +c0101acd: 81 7d 0c ff ff ff 0f cmpl $0xfffffff,0xc(%ebp) +c0101ad4: 77 0f ja c0101ae5 +c0101ad6: 8b 55 0c mov 0xc(%ebp),%edx +c0101ad9: 8b 45 14 mov 0x14(%ebp),%eax +c0101adc: 01 d0 add %edx,%eax +c0101ade: 3d 00 00 00 10 cmp $0x10000000,%eax +c0101ae3: 76 24 jbe c0101b09 +c0101ae5: c7 44 24 0c 4c 91 10 movl $0xc010914c,0xc(%esp) +c0101aec: c0 +c0101aed: c7 44 24 08 df 90 10 movl $0xc01090df,0x8(%esp) +c0101af4: c0 +c0101af5: c7 44 24 04 a0 00 00 movl $0xa0,0x4(%esp) +c0101afc: 00 +c0101afd: c7 04 24 f4 90 10 c0 movl $0xc01090f4,(%esp) +c0101b04: e8 39 f1 ff ff call c0100c42 <__panic> + unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno); +c0101b09: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101b0d: d1 e8 shr %eax +c0101b0f: 0f b7 c0 movzwl %ax,%eax +c0101b12: 8b 04 85 94 90 10 c0 mov -0x3fef6f6c(,%eax,4),%eax +c0101b19: 66 89 45 f2 mov %ax,-0xe(%ebp) +c0101b1d: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101b21: d1 e8 shr %eax +c0101b23: 0f b7 c0 movzwl %ax,%eax +c0101b26: 0f b7 04 85 96 90 10 movzwl -0x3fef6f6a(,%eax,4),%eax +c0101b2d: c0 +c0101b2e: 66 89 45 f0 mov %ax,-0x10(%ebp) + + ide_wait_ready(iobase, 0); +c0101b32: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101b36: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0101b3d: 00 +c0101b3e: 89 04 24 mov %eax,(%esp) +c0101b41: e8 4d fb ff ff call c0101693 + + // generate interrupt + outb(ioctrl + ISA_CTRL, 0); +c0101b46: 8b 45 f0 mov -0x10(%ebp),%eax +c0101b49: 83 c0 02 add $0x2,%eax +c0101b4c: 0f b7 c0 movzwl %ax,%eax +c0101b4f: 66 89 45 d6 mov %ax,-0x2a(%ebp) +c0101b53: c6 45 d5 00 movb $0x0,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101b57: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101b5b: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101b5f: ee out %al,(%dx) +} +c0101b60: 90 nop + outb(iobase + ISA_SECCNT, nsecs); +c0101b61: 8b 45 14 mov 0x14(%ebp),%eax +c0101b64: 0f b6 c0 movzbl %al,%eax +c0101b67: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101b6b: 83 c2 02 add $0x2,%edx +c0101b6e: 0f b7 d2 movzwl %dx,%edx +c0101b71: 66 89 55 da mov %dx,-0x26(%ebp) +c0101b75: 88 45 d9 mov %al,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101b78: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0101b7c: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0101b80: ee out %al,(%dx) +} +c0101b81: 90 nop + outb(iobase + ISA_SECTOR, secno & 0xFF); +c0101b82: 8b 45 0c mov 0xc(%ebp),%eax +c0101b85: 0f b6 c0 movzbl %al,%eax +c0101b88: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101b8c: 83 c2 03 add $0x3,%edx +c0101b8f: 0f b7 d2 movzwl %dx,%edx +c0101b92: 66 89 55 de mov %dx,-0x22(%ebp) +c0101b96: 88 45 dd mov %al,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101b99: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0101b9d: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0101ba1: ee out %al,(%dx) +} +c0101ba2: 90 nop + outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF); +c0101ba3: 8b 45 0c mov 0xc(%ebp),%eax +c0101ba6: c1 e8 08 shr $0x8,%eax +c0101ba9: 0f b6 c0 movzbl %al,%eax +c0101bac: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101bb0: 83 c2 04 add $0x4,%edx +c0101bb3: 0f b7 d2 movzwl %dx,%edx +c0101bb6: 66 89 55 e2 mov %dx,-0x1e(%ebp) +c0101bba: 88 45 e1 mov %al,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101bbd: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0101bc1: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0101bc5: ee out %al,(%dx) +} +c0101bc6: 90 nop + outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF); +c0101bc7: 8b 45 0c mov 0xc(%ebp),%eax +c0101bca: c1 e8 10 shr $0x10,%eax +c0101bcd: 0f b6 c0 movzbl %al,%eax +c0101bd0: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101bd4: 83 c2 05 add $0x5,%edx +c0101bd7: 0f b7 d2 movzwl %dx,%edx +c0101bda: 66 89 55 e6 mov %dx,-0x1a(%ebp) +c0101bde: 88 45 e5 mov %al,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101be1: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0101be5: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101be9: ee out %al,(%dx) +} +c0101bea: 90 nop + outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF)); +c0101beb: 8b 45 c4 mov -0x3c(%ebp),%eax +c0101bee: c0 e0 04 shl $0x4,%al +c0101bf1: 24 10 and $0x10,%al +c0101bf3: 88 c2 mov %al,%dl +c0101bf5: 8b 45 0c mov 0xc(%ebp),%eax +c0101bf8: c1 e8 18 shr $0x18,%eax +c0101bfb: 24 0f and $0xf,%al +c0101bfd: 08 d0 or %dl,%al +c0101bff: 0c e0 or $0xe0,%al +c0101c01: 0f b6 c0 movzbl %al,%eax +c0101c04: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101c08: 83 c2 06 add $0x6,%edx +c0101c0b: 0f b7 d2 movzwl %dx,%edx +c0101c0e: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101c12: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101c15: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101c19: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0101c1d: ee out %al,(%dx) +} +c0101c1e: 90 nop + outb(iobase + ISA_COMMAND, IDE_CMD_READ); +c0101c1f: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101c23: 83 c0 07 add $0x7,%eax +c0101c26: 0f b7 c0 movzwl %ax,%eax +c0101c29: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101c2d: c6 45 ed 20 movb $0x20,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101c31: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101c35: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101c39: ee out %al,(%dx) +} +c0101c3a: 90 nop + + int ret = 0; +c0101c3b: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + for (; nsecs > 0; nsecs --, dst += SECTSIZE) { +c0101c42: eb 58 jmp c0101c9c + if ((ret = ide_wait_ready(iobase, 1)) != 0) { +c0101c44: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101c48: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0101c4f: 00 +c0101c50: 89 04 24 mov %eax,(%esp) +c0101c53: e8 3b fa ff ff call c0101693 +c0101c58: 89 45 f4 mov %eax,-0xc(%ebp) +c0101c5b: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0101c5f: 75 43 jne c0101ca4 + goto out; + } + insl(iobase, dst, SECTSIZE / sizeof(uint32_t)); +c0101c61: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101c65: 89 45 d0 mov %eax,-0x30(%ebp) +c0101c68: 8b 45 10 mov 0x10(%ebp),%eax +c0101c6b: 89 45 cc mov %eax,-0x34(%ebp) +c0101c6e: c7 45 c8 80 00 00 00 movl $0x80,-0x38(%ebp) + asm volatile ( +c0101c75: 8b 55 d0 mov -0x30(%ebp),%edx +c0101c78: 8b 4d cc mov -0x34(%ebp),%ecx +c0101c7b: 8b 45 c8 mov -0x38(%ebp),%eax +c0101c7e: 89 cb mov %ecx,%ebx +c0101c80: 89 df mov %ebx,%edi +c0101c82: 89 c1 mov %eax,%ecx +c0101c84: fc cld +c0101c85: f2 6d repnz insl (%dx),%es:(%edi) +c0101c87: 89 c8 mov %ecx,%eax +c0101c89: 89 fb mov %edi,%ebx +c0101c8b: 89 5d cc mov %ebx,-0x34(%ebp) +c0101c8e: 89 45 c8 mov %eax,-0x38(%ebp) +} +c0101c91: 90 nop + for (; nsecs > 0; nsecs --, dst += SECTSIZE) { +c0101c92: ff 4d 14 decl 0x14(%ebp) +c0101c95: 81 45 10 00 02 00 00 addl $0x200,0x10(%ebp) +c0101c9c: 83 7d 14 00 cmpl $0x0,0x14(%ebp) +c0101ca0: 75 a2 jne c0101c44 + } + +out: +c0101ca2: eb 01 jmp c0101ca5 + goto out; +c0101ca4: 90 nop + return ret; +c0101ca5: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101ca8: 83 c4 50 add $0x50,%esp +c0101cab: 5b pop %ebx +c0101cac: 5f pop %edi +c0101cad: 5d pop %ebp +c0101cae: c3 ret + +c0101caf : + +int +ide_write_secs(unsigned short ideno, uint32_t secno, const void *src, size_t nsecs) { +c0101caf: 55 push %ebp +c0101cb0: 89 e5 mov %esp,%ebp +c0101cb2: 56 push %esi +c0101cb3: 53 push %ebx +c0101cb4: 83 ec 50 sub $0x50,%esp +c0101cb7: 8b 45 08 mov 0x8(%ebp),%eax +c0101cba: 66 89 45 c4 mov %ax,-0x3c(%ebp) + assert(nsecs <= MAX_NSECS && VALID_IDE(ideno)); +c0101cbe: 81 7d 14 80 00 00 00 cmpl $0x80,0x14(%ebp) +c0101cc5: 77 23 ja c0101cea +c0101cc7: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101ccb: 83 f8 03 cmp $0x3,%eax +c0101cce: 77 1a ja c0101cea +c0101cd0: 0f b7 55 c4 movzwl -0x3c(%ebp),%edx +c0101cd4: 89 d0 mov %edx,%eax +c0101cd6: c1 e0 03 shl $0x3,%eax +c0101cd9: 29 d0 sub %edx,%eax +c0101cdb: c1 e0 03 shl $0x3,%eax +c0101cde: 05 80 56 12 c0 add $0xc0125680,%eax +c0101ce3: 0f b6 00 movzbl (%eax),%eax +c0101ce6: 84 c0 test %al,%al +c0101ce8: 75 24 jne c0101d0e +c0101cea: c7 44 24 0c 24 91 10 movl $0xc0109124,0xc(%esp) +c0101cf1: c0 +c0101cf2: c7 44 24 08 df 90 10 movl $0xc01090df,0x8(%esp) +c0101cf9: c0 +c0101cfa: c7 44 24 04 bc 00 00 movl $0xbc,0x4(%esp) +c0101d01: 00 +c0101d02: c7 04 24 f4 90 10 c0 movl $0xc01090f4,(%esp) +c0101d09: e8 34 ef ff ff call c0100c42 <__panic> + assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS); +c0101d0e: 81 7d 0c ff ff ff 0f cmpl $0xfffffff,0xc(%ebp) +c0101d15: 77 0f ja c0101d26 +c0101d17: 8b 55 0c mov 0xc(%ebp),%edx +c0101d1a: 8b 45 14 mov 0x14(%ebp),%eax +c0101d1d: 01 d0 add %edx,%eax +c0101d1f: 3d 00 00 00 10 cmp $0x10000000,%eax +c0101d24: 76 24 jbe c0101d4a +c0101d26: c7 44 24 0c 4c 91 10 movl $0xc010914c,0xc(%esp) +c0101d2d: c0 +c0101d2e: c7 44 24 08 df 90 10 movl $0xc01090df,0x8(%esp) +c0101d35: c0 +c0101d36: c7 44 24 04 bd 00 00 movl $0xbd,0x4(%esp) +c0101d3d: 00 +c0101d3e: c7 04 24 f4 90 10 c0 movl $0xc01090f4,(%esp) +c0101d45: e8 f8 ee ff ff call c0100c42 <__panic> + unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno); +c0101d4a: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101d4e: d1 e8 shr %eax +c0101d50: 0f b7 c0 movzwl %ax,%eax +c0101d53: 8b 04 85 94 90 10 c0 mov -0x3fef6f6c(,%eax,4),%eax +c0101d5a: 66 89 45 f2 mov %ax,-0xe(%ebp) +c0101d5e: 0f b7 45 c4 movzwl -0x3c(%ebp),%eax +c0101d62: d1 e8 shr %eax +c0101d64: 0f b7 c0 movzwl %ax,%eax +c0101d67: 0f b7 04 85 96 90 10 movzwl -0x3fef6f6a(,%eax,4),%eax +c0101d6e: c0 +c0101d6f: 66 89 45 f0 mov %ax,-0x10(%ebp) + + ide_wait_ready(iobase, 0); +c0101d73: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101d77: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0101d7e: 00 +c0101d7f: 89 04 24 mov %eax,(%esp) +c0101d82: e8 0c f9 ff ff call c0101693 + + // generate interrupt + outb(ioctrl + ISA_CTRL, 0); +c0101d87: 8b 45 f0 mov -0x10(%ebp),%eax +c0101d8a: 83 c0 02 add $0x2,%eax +c0101d8d: 0f b7 c0 movzwl %ax,%eax +c0101d90: 66 89 45 d6 mov %ax,-0x2a(%ebp) +c0101d94: c6 45 d5 00 movb $0x0,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101d98: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101d9c: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101da0: ee out %al,(%dx) +} +c0101da1: 90 nop + outb(iobase + ISA_SECCNT, nsecs); +c0101da2: 8b 45 14 mov 0x14(%ebp),%eax +c0101da5: 0f b6 c0 movzbl %al,%eax +c0101da8: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101dac: 83 c2 02 add $0x2,%edx +c0101daf: 0f b7 d2 movzwl %dx,%edx +c0101db2: 66 89 55 da mov %dx,-0x26(%ebp) +c0101db6: 88 45 d9 mov %al,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101db9: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0101dbd: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0101dc1: ee out %al,(%dx) +} +c0101dc2: 90 nop + outb(iobase + ISA_SECTOR, secno & 0xFF); +c0101dc3: 8b 45 0c mov 0xc(%ebp),%eax +c0101dc6: 0f b6 c0 movzbl %al,%eax +c0101dc9: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101dcd: 83 c2 03 add $0x3,%edx +c0101dd0: 0f b7 d2 movzwl %dx,%edx +c0101dd3: 66 89 55 de mov %dx,-0x22(%ebp) +c0101dd7: 88 45 dd mov %al,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101dda: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0101dde: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0101de2: ee out %al,(%dx) +} +c0101de3: 90 nop + outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF); +c0101de4: 8b 45 0c mov 0xc(%ebp),%eax +c0101de7: c1 e8 08 shr $0x8,%eax +c0101dea: 0f b6 c0 movzbl %al,%eax +c0101ded: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101df1: 83 c2 04 add $0x4,%edx +c0101df4: 0f b7 d2 movzwl %dx,%edx +c0101df7: 66 89 55 e2 mov %dx,-0x1e(%ebp) +c0101dfb: 88 45 e1 mov %al,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101dfe: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0101e02: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0101e06: ee out %al,(%dx) +} +c0101e07: 90 nop + outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF); +c0101e08: 8b 45 0c mov 0xc(%ebp),%eax +c0101e0b: c1 e8 10 shr $0x10,%eax +c0101e0e: 0f b6 c0 movzbl %al,%eax +c0101e11: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101e15: 83 c2 05 add $0x5,%edx +c0101e18: 0f b7 d2 movzwl %dx,%edx +c0101e1b: 66 89 55 e6 mov %dx,-0x1a(%ebp) +c0101e1f: 88 45 e5 mov %al,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101e22: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0101e26: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101e2a: ee out %al,(%dx) +} +c0101e2b: 90 nop + outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF)); +c0101e2c: 8b 45 c4 mov -0x3c(%ebp),%eax +c0101e2f: c0 e0 04 shl $0x4,%al +c0101e32: 24 10 and $0x10,%al +c0101e34: 88 c2 mov %al,%dl +c0101e36: 8b 45 0c mov 0xc(%ebp),%eax +c0101e39: c1 e8 18 shr $0x18,%eax +c0101e3c: 24 0f and $0xf,%al +c0101e3e: 08 d0 or %dl,%al +c0101e40: 0c e0 or $0xe0,%al +c0101e42: 0f b6 c0 movzbl %al,%eax +c0101e45: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101e49: 83 c2 06 add $0x6,%edx +c0101e4c: 0f b7 d2 movzwl %dx,%edx +c0101e4f: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101e53: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101e56: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101e5a: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0101e5e: ee out %al,(%dx) +} +c0101e5f: 90 nop + outb(iobase + ISA_COMMAND, IDE_CMD_WRITE); +c0101e60: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101e64: 83 c0 07 add $0x7,%eax +c0101e67: 0f b7 c0 movzwl %ax,%eax +c0101e6a: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101e6e: c6 45 ed 30 movb $0x30,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101e72: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101e76: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101e7a: ee out %al,(%dx) +} +c0101e7b: 90 nop + + int ret = 0; +c0101e7c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + for (; nsecs > 0; nsecs --, src += SECTSIZE) { +c0101e83: eb 58 jmp c0101edd + if ((ret = ide_wait_ready(iobase, 1)) != 0) { +c0101e85: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101e89: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0101e90: 00 +c0101e91: 89 04 24 mov %eax,(%esp) +c0101e94: e8 fa f7 ff ff call c0101693 +c0101e99: 89 45 f4 mov %eax,-0xc(%ebp) +c0101e9c: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0101ea0: 75 43 jne c0101ee5 + goto out; + } + outsl(iobase, src, SECTSIZE / sizeof(uint32_t)); +c0101ea2: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0101ea6: 89 45 d0 mov %eax,-0x30(%ebp) +c0101ea9: 8b 45 10 mov 0x10(%ebp),%eax +c0101eac: 89 45 cc mov %eax,-0x34(%ebp) +c0101eaf: c7 45 c8 80 00 00 00 movl $0x80,-0x38(%ebp) + asm volatile ( +c0101eb6: 8b 55 d0 mov -0x30(%ebp),%edx +c0101eb9: 8b 4d cc mov -0x34(%ebp),%ecx +c0101ebc: 8b 45 c8 mov -0x38(%ebp),%eax +c0101ebf: 89 cb mov %ecx,%ebx +c0101ec1: 89 de mov %ebx,%esi +c0101ec3: 89 c1 mov %eax,%ecx +c0101ec5: fc cld +c0101ec6: f2 6f repnz outsl %ds:(%esi),(%dx) +c0101ec8: 89 c8 mov %ecx,%eax +c0101eca: 89 f3 mov %esi,%ebx +c0101ecc: 89 5d cc mov %ebx,-0x34(%ebp) +c0101ecf: 89 45 c8 mov %eax,-0x38(%ebp) +} +c0101ed2: 90 nop + for (; nsecs > 0; nsecs --, src += SECTSIZE) { +c0101ed3: ff 4d 14 decl 0x14(%ebp) +c0101ed6: 81 45 10 00 02 00 00 addl $0x200,0x10(%ebp) +c0101edd: 83 7d 14 00 cmpl $0x0,0x14(%ebp) +c0101ee1: 75 a2 jne c0101e85 + } + +out: +c0101ee3: eb 01 jmp c0101ee6 + goto out; +c0101ee5: 90 nop + return ret; +c0101ee6: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101ee9: 83 c4 50 add $0x50,%esp +c0101eec: 5b pop %ebx +c0101eed: 5e pop %esi +c0101eee: 5d pop %ebp +c0101eef: c3 ret + +c0101ef0 : +#include +#include + +/* intr_enable - enable irq interrupt */ +void +intr_enable(void) { +c0101ef0: 55 push %ebp +c0101ef1: 89 e5 mov %esp,%ebp + asm volatile ("sti"); +c0101ef3: fb sti +} +c0101ef4: 90 nop + sti(); +} +c0101ef5: 90 nop +c0101ef6: 5d pop %ebp +c0101ef7: c3 ret + +c0101ef8 : + +/* intr_disable - disable irq interrupt */ +void +intr_disable(void) { +c0101ef8: 55 push %ebp +c0101ef9: 89 e5 mov %esp,%ebp + asm volatile ("cli" ::: "memory"); +c0101efb: fa cli +} +c0101efc: 90 nop + cli(); +} +c0101efd: 90 nop +c0101efe: 5d pop %ebp +c0101eff: c3 ret + +c0101f00 : + * 此函数用于更新内部的IRQ掩码,并在设备初始化后,将掩码值写入到两个级联的可编程中断控制器(PIC)中 + * + * @param mask 一个16位的掩码值,用于配置IRQ线的掩码 + */ +static void +pic_setmask(uint16_t mask) { +c0101f00: 55 push %ebp +c0101f01: 89 e5 mov %esp,%ebp +c0101f03: 83 ec 14 sub $0x14,%esp +c0101f06: 8b 45 08 mov 0x8(%ebp),%eax +c0101f09: 66 89 45 ec mov %ax,-0x14(%ebp) + // 更新内部的IRQ掩码 + irq_mask = mask; +c0101f0d: 8b 45 ec mov -0x14(%ebp),%eax +c0101f10: 66 a3 50 25 12 c0 mov %ax,0xc0122550 + // 仅在设备已初始化的情况下执行后续操作 + if (did_init) { +c0101f16: a1 60 57 12 c0 mov 0xc0125760,%eax +c0101f1b: 85 c0 test %eax,%eax +c0101f1d: 74 39 je c0101f58 + // 向主PIC发送低8位的掩码 + outb(IO_PIC1 + 1, mask); +c0101f1f: 8b 45 ec mov -0x14(%ebp),%eax +c0101f22: 0f b6 c0 movzbl %al,%eax +c0101f25: 66 c7 45 fa 21 00 movw $0x21,-0x6(%ebp) +c0101f2b: 88 45 f9 mov %al,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101f2e: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0101f32: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c0101f36: ee out %al,(%dx) +} +c0101f37: 90 nop + // 向从PIC发送高8位的掩码 + outb(IO_PIC2 + 1, mask >> 8); +c0101f38: 0f b7 45 ec movzwl -0x14(%ebp),%eax +c0101f3c: c1 e8 08 shr $0x8,%eax +c0101f3f: 0f b7 c0 movzwl %ax,%eax +c0101f42: 0f b6 c0 movzbl %al,%eax +c0101f45: 66 c7 45 fe a1 00 movw $0xa1,-0x2(%ebp) +c0101f4b: 88 45 fd mov %al,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101f4e: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c0101f52: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c0101f56: ee out %al,(%dx) +} +c0101f57: 90 nop + } +} +c0101f58: 90 nop +c0101f59: 89 ec mov %ebp,%esp +c0101f5b: 5d pop %ebp +c0101f5c: c3 ret + +c0101f5d : + * 此函数通过更新中断掩码寄存器来启用特定的中断源 + * + * @param irq 要启用的中断源的编号 + */ +void +pic_enable(unsigned int irq) { +c0101f5d: 55 push %ebp +c0101f5e: 89 e5 mov %esp,%ebp +c0101f60: 83 ec 04 sub $0x4,%esp + // 更新中断掩码,清除对应IRQ的掩码位以启用中断 + pic_setmask(irq_mask & ~(1 << irq)); +c0101f63: 8b 45 08 mov 0x8(%ebp),%eax +c0101f66: ba 01 00 00 00 mov $0x1,%edx +c0101f6b: 88 c1 mov %al,%cl +c0101f6d: d3 e2 shl %cl,%edx +c0101f6f: 89 d0 mov %edx,%eax +c0101f71: 98 cwtl +c0101f72: f7 d0 not %eax +c0101f74: 0f bf d0 movswl %ax,%edx +c0101f77: 0f b7 05 50 25 12 c0 movzwl 0xc0122550,%eax +c0101f7e: 98 cwtl +c0101f7f: 21 d0 and %edx,%eax +c0101f81: 98 cwtl +c0101f82: 0f b7 c0 movzwl %ax,%eax +c0101f85: 89 04 24 mov %eax,(%esp) +c0101f88: e8 73 ff ff ff call c0101f00 +} +c0101f8d: 90 nop +c0101f8e: 89 ec mov %ebp,%esp +c0101f90: 5d pop %ebp +c0101f91: c3 ret + +c0101f92 : + +/* pic_init - initialize the 8259A interrupt controllers */ +// 初始化可编程中断控制器(PIC) +// 此函数配置 PIC 以准备处理系统中的中断 +void +pic_init(void) { +c0101f92: 55 push %ebp +c0101f93: 89 e5 mov %esp,%ebp +c0101f95: 83 ec 44 sub $0x44,%esp + // 标记 PIC 初始化完成 + did_init = 1; +c0101f98: c7 05 60 57 12 c0 01 movl $0x1,0xc0125760 +c0101f9f: 00 00 00 +c0101fa2: 66 c7 45 ca 21 00 movw $0x21,-0x36(%ebp) +c0101fa8: c6 45 c9 ff movb $0xff,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101fac: 0f b6 45 c9 movzbl -0x37(%ebp),%eax +c0101fb0: 0f b7 55 ca movzwl -0x36(%ebp),%edx +c0101fb4: ee out %al,(%dx) +} +c0101fb5: 90 nop +c0101fb6: 66 c7 45 ce a1 00 movw $0xa1,-0x32(%ebp) +c0101fbc: c6 45 cd ff movb $0xff,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101fc0: 0f b6 45 cd movzbl -0x33(%ebp),%eax +c0101fc4: 0f b7 55 ce movzwl -0x32(%ebp),%edx +c0101fc8: ee out %al,(%dx) +} +c0101fc9: 90 nop +c0101fca: 66 c7 45 d2 20 00 movw $0x20,-0x2e(%ebp) +c0101fd0: c6 45 d1 11 movb $0x11,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101fd4: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c0101fd8: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c0101fdc: ee out %al,(%dx) +} +c0101fdd: 90 nop +c0101fde: 66 c7 45 d6 21 00 movw $0x21,-0x2a(%ebp) +c0101fe4: c6 45 d5 20 movb $0x20,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101fe8: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101fec: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101ff0: ee out %al,(%dx) +} +c0101ff1: 90 nop +c0101ff2: 66 c7 45 da 21 00 movw $0x21,-0x26(%ebp) +c0101ff8: c6 45 d9 04 movb $0x4,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101ffc: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0102000: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0102004: ee out %al,(%dx) +} +c0102005: 90 nop +c0102006: 66 c7 45 de 21 00 movw $0x21,-0x22(%ebp) +c010200c: c6 45 dd 03 movb $0x3,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102010: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0102014: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0102018: ee out %al,(%dx) +} +c0102019: 90 nop +c010201a: 66 c7 45 e2 a0 00 movw $0xa0,-0x1e(%ebp) +c0102020: c6 45 e1 11 movb $0x11,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102024: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0102028: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c010202c: ee out %al,(%dx) +} +c010202d: 90 nop +c010202e: 66 c7 45 e6 a1 00 movw $0xa1,-0x1a(%ebp) +c0102034: c6 45 e5 28 movb $0x28,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102038: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c010203c: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0102040: ee out %al,(%dx) +} +c0102041: 90 nop +c0102042: 66 c7 45 ea a1 00 movw $0xa1,-0x16(%ebp) +c0102048: c6 45 e9 02 movb $0x2,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010204c: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0102050: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0102054: ee out %al,(%dx) +} +c0102055: 90 nop +c0102056: 66 c7 45 ee a1 00 movw $0xa1,-0x12(%ebp) +c010205c: c6 45 ed 03 movb $0x3,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102060: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0102064: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0102068: ee out %al,(%dx) +} +c0102069: 90 nop +c010206a: 66 c7 45 f2 20 00 movw $0x20,-0xe(%ebp) +c0102070: c6 45 f1 68 movb $0x68,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102074: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0102078: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c010207c: ee out %al,(%dx) +} +c010207d: 90 nop +c010207e: 66 c7 45 f6 20 00 movw $0x20,-0xa(%ebp) +c0102084: c6 45 f5 0a movb $0xa,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0102088: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c010208c: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0102090: ee out %al,(%dx) +} +c0102091: 90 nop +c0102092: 66 c7 45 fa a0 00 movw $0xa0,-0x6(%ebp) +c0102098: c6 45 f9 68 movb $0x68,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010209c: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01020a0: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c01020a4: ee out %al,(%dx) +} +c01020a5: 90 nop +c01020a6: 66 c7 45 fe a0 00 movw $0xa0,-0x2(%ebp) +c01020ac: c6 45 fd 0a movb $0xa,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01020b0: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c01020b4: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c01020b8: ee out %al,(%dx) +} +c01020b9: 90 nop + + outb(IO_PIC2, 0x68); // OCW3 + outb(IO_PIC2, 0x0a); // OCW3 + + // 如果有自定义的中断掩码,则设置中断掩码 + if (irq_mask != 0xFFFF) { +c01020ba: 0f b7 05 50 25 12 c0 movzwl 0xc0122550,%eax +c01020c1: 3d ff ff 00 00 cmp $0xffff,%eax +c01020c6: 74 0f je c01020d7 + pic_setmask(irq_mask); +c01020c8: 0f b7 05 50 25 12 c0 movzwl 0xc0122550,%eax +c01020cf: 89 04 24 mov %eax,(%esp) +c01020d2: e8 29 fe ff ff call c0101f00 + } +} +c01020d7: 90 nop +c01020d8: 89 ec mov %ebp,%esp +c01020da: 5d pop %ebp +c01020db: c3 ret + +c01020dc : +#include +#include + +#define TICK_NUM 100 + +static void print_ticks() { +c01020dc: 55 push %ebp +c01020dd: 89 e5 mov %esp,%ebp +c01020df: 83 ec 18 sub $0x18,%esp + cprintf("%d ticks\n",TICK_NUM); +c01020e2: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) +c01020e9: 00 +c01020ea: c7 04 24 a0 91 10 c0 movl $0xc01091a0,(%esp) +c01020f1: e8 7f e2 ff ff call c0100375 +#ifdef DEBUG_GRADE + cprintf("End of Test.\n"); + panic("EOT: kernel seems ok.");//panic 是一个用于处理内核崩溃的函数,它会打印出错误信息并导致系统停止运行。 +#endif +} +c01020f6: 90 nop +c01020f7: 89 ec mov %ebp,%esp +c01020f9: 5d pop %ebp +c01020fa: c3 ret + +c01020fb : + sizeof(idt) - 1, (uintptr_t)idt +}; + +/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ +void +idt_init(void) { +c01020fb: 55 push %ebp +c01020fc: 89 e5 mov %esp,%ebp +c01020fe: 83 ec 10 sub $0x10,%esp + * Notice: the argument of lidt is idt_pd. try to find it! + */ + + extern uintptr_t __vectors[];//声明了一个外部数组 __vectors,该数组存储中断服务例程(ISR)的地址。 + int i; + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { +c0102101: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c0102108: e9 c4 00 00 00 jmp c01021d1 + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); +c010210d: 8b 45 fc mov -0x4(%ebp),%eax +c0102110: 8b 04 85 e0 25 12 c0 mov -0x3fedda20(,%eax,4),%eax +c0102117: 0f b7 d0 movzwl %ax,%edx +c010211a: 8b 45 fc mov -0x4(%ebp),%eax +c010211d: 66 89 14 c5 e0 57 12 mov %dx,-0x3feda820(,%eax,8) +c0102124: c0 +c0102125: 8b 45 fc mov -0x4(%ebp),%eax +c0102128: 66 c7 04 c5 e2 57 12 movw $0x8,-0x3feda81e(,%eax,8) +c010212f: c0 08 00 +c0102132: 8b 45 fc mov -0x4(%ebp),%eax +c0102135: 0f b6 14 c5 e4 57 12 movzbl -0x3feda81c(,%eax,8),%edx +c010213c: c0 +c010213d: 80 e2 e0 and $0xe0,%dl +c0102140: 88 14 c5 e4 57 12 c0 mov %dl,-0x3feda81c(,%eax,8) +c0102147: 8b 45 fc mov -0x4(%ebp),%eax +c010214a: 0f b6 14 c5 e4 57 12 movzbl -0x3feda81c(,%eax,8),%edx +c0102151: c0 +c0102152: 80 e2 1f and $0x1f,%dl +c0102155: 88 14 c5 e4 57 12 c0 mov %dl,-0x3feda81c(,%eax,8) +c010215c: 8b 45 fc mov -0x4(%ebp),%eax +c010215f: 0f b6 14 c5 e5 57 12 movzbl -0x3feda81b(,%eax,8),%edx +c0102166: c0 +c0102167: 80 e2 f0 and $0xf0,%dl +c010216a: 80 ca 0e or $0xe,%dl +c010216d: 88 14 c5 e5 57 12 c0 mov %dl,-0x3feda81b(,%eax,8) +c0102174: 8b 45 fc mov -0x4(%ebp),%eax +c0102177: 0f b6 14 c5 e5 57 12 movzbl -0x3feda81b(,%eax,8),%edx +c010217e: c0 +c010217f: 80 e2 ef and $0xef,%dl +c0102182: 88 14 c5 e5 57 12 c0 mov %dl,-0x3feda81b(,%eax,8) +c0102189: 8b 45 fc mov -0x4(%ebp),%eax +c010218c: 0f b6 14 c5 e5 57 12 movzbl -0x3feda81b(,%eax,8),%edx +c0102193: c0 +c0102194: 80 e2 9f and $0x9f,%dl +c0102197: 88 14 c5 e5 57 12 c0 mov %dl,-0x3feda81b(,%eax,8) +c010219e: 8b 45 fc mov -0x4(%ebp),%eax +c01021a1: 0f b6 14 c5 e5 57 12 movzbl -0x3feda81b(,%eax,8),%edx +c01021a8: c0 +c01021a9: 80 ca 80 or $0x80,%dl +c01021ac: 88 14 c5 e5 57 12 c0 mov %dl,-0x3feda81b(,%eax,8) +c01021b3: 8b 45 fc mov -0x4(%ebp),%eax +c01021b6: 8b 04 85 e0 25 12 c0 mov -0x3fedda20(,%eax,4),%eax +c01021bd: c1 e8 10 shr $0x10,%eax +c01021c0: 0f b7 d0 movzwl %ax,%edx +c01021c3: 8b 45 fc mov -0x4(%ebp),%eax +c01021c6: 66 89 14 c5 e6 57 12 mov %dx,-0x3feda81a(,%eax,8) +c01021cd: c0 + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { +c01021ce: ff 45 fc incl -0x4(%ebp) +c01021d1: 8b 45 fc mov -0x4(%ebp),%eax +c01021d4: 3d ff 00 00 00 cmp $0xff,%eax +c01021d9: 0f 86 2e ff ff ff jbe c010210d + //宏用于配置每个 IDT 条目.0 表示最高特权级(内核级)GD_KTEXT: 指向内核代码段的选择子,确保 ISR 在内核代码段中执行。 + //__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级,表示该中断只能由内核级代码触发。 + // set for switch from user to kernel + //SETGATE 这行代码特别设置了 T_SWITCH_TOK(一个特定的中断向量,用于用户态到内核态的切换)的 IDT 条目。 + //DPL_USER 表示该中断可以由用户态代码触发 + SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); +c01021df: a1 c4 27 12 c0 mov 0xc01227c4,%eax +c01021e4: 0f b7 c0 movzwl %ax,%eax +c01021e7: 66 a3 a8 5b 12 c0 mov %ax,0xc0125ba8 +c01021ed: 66 c7 05 aa 5b 12 c0 movw $0x8,0xc0125baa +c01021f4: 08 00 +c01021f6: 0f b6 05 ac 5b 12 c0 movzbl 0xc0125bac,%eax +c01021fd: 24 e0 and $0xe0,%al +c01021ff: a2 ac 5b 12 c0 mov %al,0xc0125bac +c0102204: 0f b6 05 ac 5b 12 c0 movzbl 0xc0125bac,%eax +c010220b: 24 1f and $0x1f,%al +c010220d: a2 ac 5b 12 c0 mov %al,0xc0125bac +c0102212: 0f b6 05 ad 5b 12 c0 movzbl 0xc0125bad,%eax +c0102219: 24 f0 and $0xf0,%al +c010221b: 0c 0e or $0xe,%al +c010221d: a2 ad 5b 12 c0 mov %al,0xc0125bad +c0102222: 0f b6 05 ad 5b 12 c0 movzbl 0xc0125bad,%eax +c0102229: 24 ef and $0xef,%al +c010222b: a2 ad 5b 12 c0 mov %al,0xc0125bad +c0102230: 0f b6 05 ad 5b 12 c0 movzbl 0xc0125bad,%eax +c0102237: 0c 60 or $0x60,%al +c0102239: a2 ad 5b 12 c0 mov %al,0xc0125bad +c010223e: 0f b6 05 ad 5b 12 c0 movzbl 0xc0125bad,%eax +c0102245: 0c 80 or $0x80,%al +c0102247: a2 ad 5b 12 c0 mov %al,0xc0125bad +c010224c: a1 c4 27 12 c0 mov 0xc01227c4,%eax +c0102251: c1 e8 10 shr $0x10,%eax +c0102254: 0f b7 c0 movzwl %ax,%eax +c0102257: 66 a3 ae 5b 12 c0 mov %ax,0xc0125bae +c010225d: c7 45 f8 60 25 12 c0 movl $0xc0122560,-0x8(%ebp) + asm volatile ("lidt (%0)" :: "r" (pd) : "memory"); +c0102264: 8b 45 f8 mov -0x8(%ebp),%eax +c0102267: 0f 01 18 lidtl (%eax) +} +c010226a: 90 nop + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); +} +c010226b: 90 nop +c010226c: 89 ec mov %ebp,%esp +c010226e: 5d pop %ebp +c010226f: c3 ret + +c0102270 : + +static const char * +trapname(int trapno) { +c0102270: 55 push %ebp +c0102271: 89 e5 mov %esp,%ebp + "Alignment Check", + "Machine-Check", + "SIMD Floating-Point Exception" + }; + //如果 trapno 小于数组长度,则返回对应的异常名称。 + if (trapno < sizeof(excnames)/sizeof(const char * const)) { +c0102273: 8b 45 08 mov 0x8(%ebp),%eax +c0102276: 83 f8 13 cmp $0x13,%eax +c0102279: 77 0c ja c0102287 + return excnames[trapno]; +c010227b: 8b 45 08 mov 0x8(%ebp),%eax +c010227e: 8b 04 85 00 96 10 c0 mov -0x3fef6a00(,%eax,4),%eax +c0102285: eb 18 jmp c010229f + } + //如果 trapno 在 IRQ_OFFSET 和 IRQ_OFFSET + 16 之间,表示它是一个硬件中断 + if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) { +c0102287: 83 7d 08 1f cmpl $0x1f,0x8(%ebp) +c010228b: 7e 0d jle c010229a +c010228d: 83 7d 08 2f cmpl $0x2f,0x8(%ebp) +c0102291: 7f 07 jg c010229a + return "Hardware Interrupt"; +c0102293: b8 aa 91 10 c0 mov $0xc01091aa,%eax +c0102298: eb 05 jmp c010229f + } + return "(unknown trap)"; +c010229a: b8 bd 91 10 c0 mov $0xc01091bd,%eax +} +c010229f: 5d pop %ebp +c01022a0: c3 ret + +c01022a1 : + +/* trap_in_kernel - test if trap happened in kernel */ +bool +trap_in_kernel(struct trapframe *tf) { +c01022a1: 55 push %ebp +c01022a2: 89 e5 mov %esp,%ebp + return (tf->tf_cs == (uint16_t)KERNEL_CS); +c01022a4: 8b 45 08 mov 0x8(%ebp),%eax +c01022a7: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c01022ab: 83 f8 08 cmp $0x8,%eax +c01022ae: 0f 94 c0 sete %al +c01022b1: 0f b6 c0 movzbl %al,%eax + //函数通过检查 tf 中的 tf_cs 字段来判断当前处于哪个特权级,tf_cs 存储了当前代码段选择子的值 + //当 tf->tf_cs 等于 KERNEL_CS 时,表示陷阱发生在内核模式下 +} +c01022b4: 5d pop %ebp +c01022b5: c3 ret + +c01022b6 : + "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL, + "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL, +}; +//struct trapframe *tf,一个指向 trapframe 结构的指针,包含有关陷阱发生时的 CPU 状态的信息。 +void +print_trapframe(struct trapframe *tf) { +c01022b6: 55 push %ebp +c01022b7: 89 e5 mov %esp,%ebp +c01022b9: 83 ec 28 sub $0x28,%esp + cprintf("trapframe at %p\n", tf); //打印陷阱框架地址 +c01022bc: 8b 45 08 mov 0x8(%ebp),%eax +c01022bf: 89 44 24 04 mov %eax,0x4(%esp) +c01022c3: c7 04 24 fe 91 10 c0 movl $0xc01091fe,(%esp) +c01022ca: e8 a6 e0 ff ff call c0100375 + print_regs(&tf->tf_regs); //打印寄存器状态 +c01022cf: 8b 45 08 mov 0x8(%ebp),%eax +c01022d2: 89 04 24 mov %eax,(%esp) +c01022d5: e8 8f 01 00 00 call c0102469 + //打印数据段(DS)、扩展段(ES)、文件段(FS)、通用段(GS)的值。 + cprintf(" ds 0x----%04x\n", tf->tf_ds); +c01022da: 8b 45 08 mov 0x8(%ebp),%eax +c01022dd: 0f b7 40 2c movzwl 0x2c(%eax),%eax +c01022e1: 89 44 24 04 mov %eax,0x4(%esp) +c01022e5: c7 04 24 0f 92 10 c0 movl $0xc010920f,(%esp) +c01022ec: e8 84 e0 ff ff call c0100375 + cprintf(" es 0x----%04x\n", tf->tf_es); +c01022f1: 8b 45 08 mov 0x8(%ebp),%eax +c01022f4: 0f b7 40 28 movzwl 0x28(%eax),%eax +c01022f8: 89 44 24 04 mov %eax,0x4(%esp) +c01022fc: c7 04 24 22 92 10 c0 movl $0xc0109222,(%esp) +c0102303: e8 6d e0 ff ff call c0100375 + cprintf(" fs 0x----%04x\n", tf->tf_fs); +c0102308: 8b 45 08 mov 0x8(%ebp),%eax +c010230b: 0f b7 40 24 movzwl 0x24(%eax),%eax +c010230f: 89 44 24 04 mov %eax,0x4(%esp) +c0102313: c7 04 24 35 92 10 c0 movl $0xc0109235,(%esp) +c010231a: e8 56 e0 ff ff call c0100375 + cprintf(" gs 0x----%04x\n", tf->tf_gs); +c010231f: 8b 45 08 mov 0x8(%ebp),%eax +c0102322: 0f b7 40 20 movzwl 0x20(%eax),%eax +c0102326: 89 44 24 04 mov %eax,0x4(%esp) +c010232a: c7 04 24 48 92 10 c0 movl $0xc0109248,(%esp) +c0102331: e8 3f e0 ff ff call c0100375 + // 打印陷阱号(trap number)及其对应的名称,通过调用 trapname 函数获取。 + cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno)); +c0102336: 8b 45 08 mov 0x8(%ebp),%eax +c0102339: 8b 40 30 mov 0x30(%eax),%eax +c010233c: 89 04 24 mov %eax,(%esp) +c010233f: e8 2c ff ff ff call c0102270 +c0102344: 8b 55 08 mov 0x8(%ebp),%edx +c0102347: 8b 52 30 mov 0x30(%edx),%edx +c010234a: 89 44 24 08 mov %eax,0x8(%esp) +c010234e: 89 54 24 04 mov %edx,0x4(%esp) +c0102352: c7 04 24 5b 92 10 c0 movl $0xc010925b,(%esp) +c0102359: e8 17 e0 ff ff call c0100375 + cprintf(" err 0x%08x\n", tf->tf_err);// 如果有错误代码,打印该字段的值。 +c010235e: 8b 45 08 mov 0x8(%ebp),%eax +c0102361: 8b 40 34 mov 0x34(%eax),%eax +c0102364: 89 44 24 04 mov %eax,0x4(%esp) +c0102368: c7 04 24 6d 92 10 c0 movl $0xc010926d,(%esp) +c010236f: e8 01 e0 ff ff call c0100375 + cprintf(" eip 0x%08x\n", tf->tf_eip);//打印当前执行的指令指针(EIP),指向出错或中断的指令。 +c0102374: 8b 45 08 mov 0x8(%ebp),%eax +c0102377: 8b 40 38 mov 0x38(%eax),%eax +c010237a: 89 44 24 04 mov %eax,0x4(%esp) +c010237e: c7 04 24 7c 92 10 c0 movl $0xc010927c,(%esp) +c0102385: e8 eb df ff ff call c0100375 + cprintf(" cs 0x----%04x\n", tf->tf_cs);//打印代码段寄存器(CS)的值。 +c010238a: 8b 45 08 mov 0x8(%ebp),%eax +c010238d: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0102391: 89 44 24 04 mov %eax,0x4(%esp) +c0102395: c7 04 24 8b 92 10 c0 movl $0xc010928b,(%esp) +c010239c: e8 d4 df ff ff call c0100375 + cprintf(" flag 0x%08x ", tf->tf_eflags);// 打印标志寄存器(EFLAGS)的值 +c01023a1: 8b 45 08 mov 0x8(%ebp),%eax +c01023a4: 8b 40 40 mov 0x40(%eax),%eax +c01023a7: 89 44 24 04 mov %eax,0x4(%esp) +c01023ab: c7 04 24 9e 92 10 c0 movl $0xc010929e,(%esp) +c01023b2: e8 be df ff ff call c0100375 + //使用循环遍历 IA32flags 数组,j 表示当前标志位的位掩码。 + int i, j; + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c01023b7: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c01023be: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) +c01023c5: eb 3d jmp c0102404 + if ((tf->tf_eflags & j) && IA32flags[i] != NULL) { +c01023c7: 8b 45 08 mov 0x8(%ebp),%eax +c01023ca: 8b 50 40 mov 0x40(%eax),%edx +c01023cd: 8b 45 f0 mov -0x10(%ebp),%eax +c01023d0: 21 d0 and %edx,%eax +c01023d2: 85 c0 test %eax,%eax +c01023d4: 74 28 je c01023fe +c01023d6: 8b 45 f4 mov -0xc(%ebp),%eax +c01023d9: 8b 04 85 80 25 12 c0 mov -0x3fedda80(,%eax,4),%eax +c01023e0: 85 c0 test %eax,%eax +c01023e2: 74 1a je c01023fe + cprintf("%s,", IA32flags[i]); +c01023e4: 8b 45 f4 mov -0xc(%ebp),%eax +c01023e7: 8b 04 85 80 25 12 c0 mov -0x3fedda80(,%eax,4),%eax +c01023ee: 89 44 24 04 mov %eax,0x4(%esp) +c01023f2: c7 04 24 ad 92 10 c0 movl $0xc01092ad,(%esp) +c01023f9: e8 77 df ff ff call c0100375 + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c01023fe: ff 45 f4 incl -0xc(%ebp) +c0102401: d1 65 f0 shll -0x10(%ebp) +c0102404: 8b 45 f4 mov -0xc(%ebp),%eax +c0102407: 83 f8 17 cmp $0x17,%eax +c010240a: 76 bb jbe c01023c7 + } + } + //通过位掩码 FL_IOPL_MASK 获取和打印当前的 I/O 特权级别。 + cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12); +c010240c: 8b 45 08 mov 0x8(%ebp),%eax +c010240f: 8b 40 40 mov 0x40(%eax),%eax +c0102412: c1 e8 0c shr $0xc,%eax +c0102415: 83 e0 03 and $0x3,%eax +c0102418: 89 44 24 04 mov %eax,0x4(%esp) +c010241c: c7 04 24 b1 92 10 c0 movl $0xc01092b1,(%esp) +c0102423: e8 4d df ff ff call c0100375 + //如果陷阱不是在内核中发生的(通过 trap_in_kernel 判断), + //则打印栈指针(ESP)和栈段(SS)寄存器的值。 + if (!trap_in_kernel(tf)) { +c0102428: 8b 45 08 mov 0x8(%ebp),%eax +c010242b: 89 04 24 mov %eax,(%esp) +c010242e: e8 6e fe ff ff call c01022a1 +c0102433: 85 c0 test %eax,%eax +c0102435: 75 2d jne c0102464 + cprintf(" esp 0x%08x\n", tf->tf_esp); +c0102437: 8b 45 08 mov 0x8(%ebp),%eax +c010243a: 8b 40 44 mov 0x44(%eax),%eax +c010243d: 89 44 24 04 mov %eax,0x4(%esp) +c0102441: c7 04 24 ba 92 10 c0 movl $0xc01092ba,(%esp) +c0102448: e8 28 df ff ff call c0100375 + cprintf(" ss 0x----%04x\n", tf->tf_ss); +c010244d: 8b 45 08 mov 0x8(%ebp),%eax +c0102450: 0f b7 40 48 movzwl 0x48(%eax),%eax +c0102454: 89 44 24 04 mov %eax,0x4(%esp) +c0102458: c7 04 24 c9 92 10 c0 movl $0xc01092c9,(%esp) +c010245f: e8 11 df ff ff call c0100375 + } +} +c0102464: 90 nop +c0102465: 89 ec mov %ebp,%esp +c0102467: 5d pop %ebp +c0102468: c3 ret + +c0102469 : +//定义了一个名为 print_regs 的函数, +//打印出存储在 struct pushregs 结构体中的寄存器值。 +void +print_regs(struct pushregs *regs) { +c0102469: 55 push %ebp +c010246a: 89 e5 mov %esp,%ebp +c010246c: 83 ec 18 sub $0x18,%esp + cprintf(" edi 0x%08x\n", regs->reg_edi); +c010246f: 8b 45 08 mov 0x8(%ebp),%eax +c0102472: 8b 00 mov (%eax),%eax +c0102474: 89 44 24 04 mov %eax,0x4(%esp) +c0102478: c7 04 24 dc 92 10 c0 movl $0xc01092dc,(%esp) +c010247f: e8 f1 de ff ff call c0100375 + cprintf(" esi 0x%08x\n", regs->reg_esi); +c0102484: 8b 45 08 mov 0x8(%ebp),%eax +c0102487: 8b 40 04 mov 0x4(%eax),%eax +c010248a: 89 44 24 04 mov %eax,0x4(%esp) +c010248e: c7 04 24 eb 92 10 c0 movl $0xc01092eb,(%esp) +c0102495: e8 db de ff ff call c0100375 + cprintf(" ebp 0x%08x\n", regs->reg_ebp); +c010249a: 8b 45 08 mov 0x8(%ebp),%eax +c010249d: 8b 40 08 mov 0x8(%eax),%eax +c01024a0: 89 44 24 04 mov %eax,0x4(%esp) +c01024a4: c7 04 24 fa 92 10 c0 movl $0xc01092fa,(%esp) +c01024ab: e8 c5 de ff ff call c0100375 + cprintf(" oesp 0x%08x\n", regs->reg_oesp);//打印旧的栈指针(OESP),这个寄存器通常在陷阱或中断发生时用于记录上一个栈指针。 +c01024b0: 8b 45 08 mov 0x8(%ebp),%eax +c01024b3: 8b 40 0c mov 0xc(%eax),%eax +c01024b6: 89 44 24 04 mov %eax,0x4(%esp) +c01024ba: c7 04 24 09 93 10 c0 movl $0xc0109309,(%esp) +c01024c1: e8 af de ff ff call c0100375 + cprintf(" ebx 0x%08x\n", regs->reg_ebx); +c01024c6: 8b 45 08 mov 0x8(%ebp),%eax +c01024c9: 8b 40 10 mov 0x10(%eax),%eax +c01024cc: 89 44 24 04 mov %eax,0x4(%esp) +c01024d0: c7 04 24 18 93 10 c0 movl $0xc0109318,(%esp) +c01024d7: e8 99 de ff ff call c0100375 + cprintf(" edx 0x%08x\n", regs->reg_edx); +c01024dc: 8b 45 08 mov 0x8(%ebp),%eax +c01024df: 8b 40 14 mov 0x14(%eax),%eax +c01024e2: 89 44 24 04 mov %eax,0x4(%esp) +c01024e6: c7 04 24 27 93 10 c0 movl $0xc0109327,(%esp) +c01024ed: e8 83 de ff ff call c0100375 + cprintf(" ecx 0x%08x\n", regs->reg_ecx); +c01024f2: 8b 45 08 mov 0x8(%ebp),%eax +c01024f5: 8b 40 18 mov 0x18(%eax),%eax +c01024f8: 89 44 24 04 mov %eax,0x4(%esp) +c01024fc: c7 04 24 36 93 10 c0 movl $0xc0109336,(%esp) +c0102503: e8 6d de ff ff call c0100375 + cprintf(" eax 0x%08x\n", regs->reg_eax); +c0102508: 8b 45 08 mov 0x8(%ebp),%eax +c010250b: 8b 40 1c mov 0x1c(%eax),%eax +c010250e: 89 44 24 04 mov %eax,0x4(%esp) +c0102512: c7 04 24 45 93 10 c0 movl $0xc0109345,(%esp) +c0102519: e8 57 de ff ff call c0100375 +} +c010251e: 90 nop +c010251f: 89 ec mov %ebp,%esp +c0102521: 5d pop %ebp +c0102522: c3 ret + +c0102523 : + * 此函数用于输出页面故障的详细信息,包括故障地址、访问类型(读/写)、访问模式(用户/内核)以及故障类型(未找到页面/保护故障)。 + * + * @param tf 指向 trapframe 结构的指针,包含故障发生时的寄存器状态和错误代码。 + */ +static inline void +print_pgfault(struct trapframe *tf) { +c0102523: 55 push %ebp +c0102524: 89 e5 mov %esp,%ebp +c0102526: 83 ec 38 sub $0x38,%esp +c0102529: 89 5d fc mov %ebx,-0x4(%ebp) + * bit 2 == 0 表示内核模式,1 表示用户模式 + * */ + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), + (tf->tf_err & 4) ? 'U' : 'K', + (tf->tf_err & 2) ? 'W' : 'R', + (tf->tf_err & 1) ? "protection fault" : "no page found"); +c010252c: 8b 45 08 mov 0x8(%ebp),%eax +c010252f: 8b 40 34 mov 0x34(%eax),%eax +c0102532: 83 e0 01 and $0x1,%eax + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), +c0102535: 85 c0 test %eax,%eax +c0102537: 74 07 je c0102540 +c0102539: bb 54 93 10 c0 mov $0xc0109354,%ebx +c010253e: eb 05 jmp c0102545 +c0102540: bb 65 93 10 c0 mov $0xc0109365,%ebx + (tf->tf_err & 2) ? 'W' : 'R', +c0102545: 8b 45 08 mov 0x8(%ebp),%eax +c0102548: 8b 40 34 mov 0x34(%eax),%eax +c010254b: 83 e0 02 and $0x2,%eax + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), +c010254e: 85 c0 test %eax,%eax +c0102550: 74 07 je c0102559 +c0102552: b9 57 00 00 00 mov $0x57,%ecx +c0102557: eb 05 jmp c010255e +c0102559: b9 52 00 00 00 mov $0x52,%ecx + (tf->tf_err & 4) ? 'U' : 'K', +c010255e: 8b 45 08 mov 0x8(%ebp),%eax +c0102561: 8b 40 34 mov 0x34(%eax),%eax +c0102564: 83 e0 04 and $0x4,%eax + cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(), +c0102567: 85 c0 test %eax,%eax +c0102569: 74 07 je c0102572 +c010256b: ba 55 00 00 00 mov $0x55,%edx +c0102570: eb 05 jmp c0102577 +c0102572: ba 4b 00 00 00 mov $0x4b,%edx +} + +static inline uintptr_t +rcr2(void) { + uintptr_t cr2; + asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory"); +c0102577: 0f 20 d0 mov %cr2,%eax +c010257a: 89 45 f4 mov %eax,-0xc(%ebp) + return cr2; +c010257d: 8b 45 f4 mov -0xc(%ebp),%eax +c0102580: 89 5c 24 10 mov %ebx,0x10(%esp) +c0102584: 89 4c 24 0c mov %ecx,0xc(%esp) +c0102588: 89 54 24 08 mov %edx,0x8(%esp) +c010258c: 89 44 24 04 mov %eax,0x4(%esp) +c0102590: c7 04 24 74 93 10 c0 movl $0xc0109374,(%esp) +c0102597: e8 d9 dd ff ff call c0100375 +} +c010259c: 90 nop +c010259d: 8b 5d fc mov -0x4(%ebp),%ebx +c01025a0: 89 ec mov %ebp,%esp +c01025a2: 5d pop %ebp +c01025a3: c3 ret + +c01025a4 : + * + * @param tf 指向陷阱帧的指针,包含故障发生时的CPU状态信息 + * @return 返回页面故障处理的结果,或者在无法处理时引发系统崩溃 + */ +static int +pgfault_handler(struct trapframe *tf) { +c01025a4: 55 push %ebp +c01025a5: 89 e5 mov %esp,%ebp +c01025a7: 83 ec 28 sub $0x28,%esp + // 声明一个外部变量,用于检查内存管理结构 + extern struct mm_struct *check_mm_struct; + // 打印页面故障信息 + print_pgfault(tf); +c01025aa: 8b 45 08 mov 0x8(%ebp),%eax +c01025ad: 89 04 24 mov %eax,(%esp) +c01025b0: e8 6e ff ff ff call c0102523 + // 检查是否存在有效的内存管理结构 + if (check_mm_struct != NULL) { +c01025b5: a1 6c 61 12 c0 mov 0xc012616c,%eax +c01025ba: 85 c0 test %eax,%eax +c01025bc: 74 26 je c01025e4 + asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory"); +c01025be: 0f 20 d0 mov %cr2,%eax +c01025c1: 89 45 f4 mov %eax,-0xc(%ebp) + return cr2; +c01025c4: 8b 4d f4 mov -0xc(%ebp),%ecx + // 如果存在,调用页面故障处理函数 + return do_pgfault(check_mm_struct, tf->tf_err, rcr2()); +c01025c7: 8b 45 08 mov 0x8(%ebp),%eax +c01025ca: 8b 50 34 mov 0x34(%eax),%edx +c01025cd: a1 6c 61 12 c0 mov 0xc012616c,%eax +c01025d2: 89 4c 24 08 mov %ecx,0x8(%esp) +c01025d6: 89 54 24 04 mov %edx,0x4(%esp) +c01025da: 89 04 24 mov %eax,(%esp) +c01025dd: e8 ab 57 00 00 call c0107d8d +c01025e2: eb 1c jmp c0102600 + } + // 如果没有有效的内存管理结构,引发系统崩溃 + panic("unhandled page fault.\n"); +c01025e4: c7 44 24 08 97 93 10 movl $0xc0109397,0x8(%esp) +c01025eb: c0 +c01025ec: c7 44 24 04 d3 00 00 movl $0xd3,0x4(%esp) +c01025f3: 00 +c01025f4: c7 04 24 ae 93 10 c0 movl $0xc01093ae,(%esp) +c01025fb: e8 42 e6 ff ff call c0100c42 <__panic> +} +c0102600: 89 ec mov %ebp,%esp +c0102602: 5d pop %ebp +c0102603: c3 ret + +c0102604 : + +struct trapframe switchk2u, *switchu2k; +//定义了一个名为 trap_dispatch 的静态函数,根据发生的陷阱类型进行相应的处理。 +// 参数 tf 是指向陷阱帧的指针,包含了关于陷阱发生时的CPU状态信息。 +static void +trap_dispatch(struct trapframe *tf) { +c0102604: 55 push %ebp +c0102605: 89 e5 mov %esp,%ebp +c0102607: 83 ec 28 sub $0x28,%esp +c010260a: 89 5d fc mov %ebx,-0x4(%ebp) + char c; + + int ret; + //通过 switch 语句根据 tf->tf_trapno 的值来分发不同的陷阱处理逻辑。 + switch (tf->tf_trapno) { +c010260d: 8b 45 08 mov 0x8(%ebp),%eax +c0102610: 8b 40 30 mov 0x30(%eax),%eax +c0102613: 83 f8 79 cmp $0x79,%eax +c0102616: 0f 84 a2 01 00 00 je c01027be +c010261c: 83 f8 79 cmp $0x79,%eax +c010261f: 0f 87 16 02 00 00 ja c010283b +c0102625: 83 f8 2f cmp $0x2f,%eax +c0102628: 77 1e ja c0102648 +c010262a: 83 f8 0e cmp $0xe,%eax +c010262d: 0f 82 08 02 00 00 jb c010283b +c0102633: 83 e8 0e sub $0xe,%eax +c0102636: 83 f8 21 cmp $0x21,%eax +c0102639: 0f 87 fc 01 00 00 ja c010283b +c010263f: 8b 04 85 18 94 10 c0 mov -0x3fef6be8(,%eax,4),%eax +c0102646: ff e0 jmp *%eax +c0102648: 83 f8 78 cmp $0x78,%eax +c010264b: 0f 84 e3 00 00 00 je c0102734 +c0102651: e9 e5 01 00 00 jmp c010283b + case T_PGFLT: //page fault + // 处理页故障中断 + if ((ret = pgfault_handler(tf)) != 0) { +c0102656: 8b 45 08 mov 0x8(%ebp),%eax +c0102659: 89 04 24 mov %eax,(%esp) +c010265c: e8 43 ff ff ff call c01025a4 +c0102661: 89 45 f0 mov %eax,-0x10(%ebp) +c0102664: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0102668: 0f 84 05 02 00 00 je c0102873 + print_trapframe(tf); +c010266e: 8b 45 08 mov 0x8(%ebp),%eax +c0102671: 89 04 24 mov %eax,(%esp) +c0102674: e8 3d fc ff ff call c01022b6 + panic("handle pgfault failed. %e\n", ret); +c0102679: 8b 45 f0 mov -0x10(%ebp),%eax +c010267c: 89 44 24 0c mov %eax,0xc(%esp) +c0102680: c7 44 24 08 bf 93 10 movl $0xc01093bf,0x8(%esp) +c0102687: c0 +c0102688: c7 44 24 04 e7 00 00 movl $0xe7,0x4(%esp) +c010268f: 00 +c0102690: c7 04 24 ae 93 10 c0 movl $0xc01093ae,(%esp) +c0102697: e8 a6 e5 ff ff call c0100c42 <__panic> + /* handle the timer interrupt */ + /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c + * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). + * (3) Too Simple? Yes, I think so! + */ + ticks ++; //记录中断事件 +c010269c: a1 24 54 12 c0 mov 0xc0125424,%eax +c01026a1: 40 inc %eax +c01026a2: a3 24 54 12 c0 mov %eax,0xc0125424 + if (ticks % TICK_NUM == 0) +c01026a7: 8b 0d 24 54 12 c0 mov 0xc0125424,%ecx +c01026ad: ba 1f 85 eb 51 mov $0x51eb851f,%edx +c01026b2: 89 c8 mov %ecx,%eax +c01026b4: f7 e2 mul %edx +c01026b6: c1 ea 05 shr $0x5,%edx +c01026b9: 89 d0 mov %edx,%eax +c01026bb: c1 e0 02 shl $0x2,%eax +c01026be: 01 d0 add %edx,%eax +c01026c0: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c01026c7: 01 d0 add %edx,%eax +c01026c9: c1 e0 02 shl $0x2,%eax +c01026cc: 29 c1 sub %eax,%ecx +c01026ce: 89 ca mov %ecx,%edx +c01026d0: 85 d2 test %edx,%edx +c01026d2: 0f 85 9e 01 00 00 jne c0102876 + { + print_ticks(); +c01026d8: e8 ff f9 ff ff call c01020dc + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息。 + break; +c01026dd: e9 94 01 00 00 jmp c0102876 + //处理串口中断,调用 cons_getc() 从串口读取字符并打印。 + case IRQ_OFFSET + IRQ_COM1: + c = cons_getc(); +c01026e2: e8 3b ef ff ff call c0101622 +c01026e7: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("serial [%03d] %c\n", c, c); +c01026ea: 0f be 55 f7 movsbl -0x9(%ebp),%edx +c01026ee: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c01026f2: 89 54 24 08 mov %edx,0x8(%esp) +c01026f6: 89 44 24 04 mov %eax,0x4(%esp) +c01026fa: c7 04 24 da 93 10 c0 movl $0xc01093da,(%esp) +c0102701: e8 6f dc ff ff call c0100375 + break; +c0102706: e9 72 01 00 00 jmp c010287d + //处理键盘中断,调用 cons_getc() 读取键盘输入并打印。 + case IRQ_OFFSET + IRQ_KBD: + c = cons_getc(); +c010270b: e8 12 ef ff ff call c0101622 +c0102710: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("kbd [%03d] %c\n", c, c); +c0102713: 0f be 55 f7 movsbl -0x9(%ebp),%edx +c0102717: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c010271b: 89 54 24 08 mov %edx,0x8(%esp) +c010271f: 89 44 24 04 mov %eax,0x4(%esp) +c0102723: c7 04 24 ec 93 10 c0 movl $0xc01093ec,(%esp) +c010272a: e8 46 dc ff ff call c0100375 + break; +c010272f: e9 49 01 00 00 jmp c010287d + //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. + case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。 + if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下 +c0102734: 8b 45 08 mov 0x8(%ebp),%eax +c0102737: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c010273b: 83 f8 1b cmp $0x1b,%eax +c010273e: 0f 84 35 01 00 00 je c0102879 + switchk2u = *tf; //保存当前陷阱框架 +c0102744: 8b 4d 08 mov 0x8(%ebp),%ecx +c0102747: b8 4c 00 00 00 mov $0x4c,%eax +c010274c: 83 e0 fc and $0xfffffffc,%eax +c010274f: 89 c3 mov %eax,%ebx +c0102751: b8 00 00 00 00 mov $0x0,%eax +c0102756: 8b 14 01 mov (%ecx,%eax,1),%edx +c0102759: 89 90 80 57 12 c0 mov %edx,-0x3feda880(%eax) +c010275f: 83 c0 04 add $0x4,%eax +c0102762: 39 d8 cmp %ebx,%eax +c0102764: 72 f0 jb c0102756 + switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器 +c0102766: 66 c7 05 bc 57 12 c0 movw $0x1b,0xc01257bc +c010276d: 1b 00 + //将数据段和栈段寄存器 都设置为 USER_DS(用户数据段) + switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS; +c010276f: 66 c7 05 c8 57 12 c0 movw $0x23,0xc01257c8 +c0102776: 23 00 +c0102778: 0f b7 05 c8 57 12 c0 movzwl 0xc01257c8,%eax +c010277f: 66 a3 a8 57 12 c0 mov %ax,0xc01257a8 +c0102785: 0f b7 05 a8 57 12 c0 movzwl 0xc01257a8,%eax +c010278c: 66 a3 ac 57 12 c0 mov %ax,0xc01257ac + switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8; +c0102792: 8b 45 08 mov 0x8(%ebp),%eax +c0102795: 83 c0 44 add $0x44,%eax +c0102798: a3 c4 57 12 c0 mov %eax,0xc01257c4 + + // set eflags, make sure ucore can use io under user mode. + // if CPL > IOPL, then cpu will generate a general protection. + switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作 +c010279d: a1 c0 57 12 c0 mov 0xc01257c0,%eax +c01027a2: 0d 00 30 00 00 or $0x3000,%eax +c01027a7: a3 c0 57 12 c0 mov %eax,0xc01257c0 + + // set temporary stack + // then iret will jump to the right stack + *((uint32_t *)tf - 1) = (uint32_t)&switchk2u; +c01027ac: 8b 45 08 mov 0x8(%ebp),%eax +c01027af: 83 e8 04 sub $0x4,%eax +c01027b2: ba 80 57 12 c0 mov $0xc0125780,%edx +c01027b7: 89 10 mov %edx,(%eax) + } + break; +c01027b9: e9 bb 00 00 00 jmp c0102879 + case T_SWITCH_TOK://T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。 + if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下 +c01027be: 8b 45 08 mov 0x8(%ebp),%eax +c01027c1: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c01027c5: 83 f8 08 cmp $0x8,%eax +c01027c8: 0f 84 ae 00 00 00 je c010287c + tf->tf_cs = KERNEL_CS; +c01027ce: 8b 45 08 mov 0x8(%ebp),%eax +c01027d1: 66 c7 40 3c 08 00 movw $0x8,0x3c(%eax) + tf->tf_ds = tf->tf_es = KERNEL_DS; +c01027d7: 8b 45 08 mov 0x8(%ebp),%eax +c01027da: 66 c7 40 28 10 00 movw $0x10,0x28(%eax) +c01027e0: 8b 45 08 mov 0x8(%ebp),%eax +c01027e3: 0f b7 50 28 movzwl 0x28(%eax),%edx +c01027e7: 8b 45 08 mov 0x8(%ebp),%eax +c01027ea: 66 89 50 2c mov %dx,0x2c(%eax) + //设置内核模式的段寄存器 + tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志 +c01027ee: 8b 45 08 mov 0x8(%ebp),%eax +c01027f1: 8b 40 40 mov 0x40(%eax),%eax +c01027f4: 25 ff cf ff ff and $0xffffcfff,%eax +c01027f9: 89 c2 mov %eax,%edx +c01027fb: 8b 45 08 mov 0x8(%ebp),%eax +c01027fe: 89 50 40 mov %edx,0x40(%eax) + switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8)); +c0102801: 8b 45 08 mov 0x8(%ebp),%eax +c0102804: 8b 40 44 mov 0x44(%eax),%eax +c0102807: 83 e8 44 sub $0x44,%eax +c010280a: a3 cc 57 12 c0 mov %eax,0xc01257cc + //使用 memmove 将当前的陷阱框架(除了最后8个字节)复制到新的陷阱框架位置 switchu2k + memmove(switchu2k, tf, sizeof(struct trapframe) - 8); +c010280f: a1 cc 57 12 c0 mov 0xc01257cc,%eax +c0102814: c7 44 24 08 44 00 00 movl $0x44,0x8(%esp) +c010281b: 00 +c010281c: 8b 55 08 mov 0x8(%ebp),%edx +c010281f: 89 54 24 04 mov %edx,0x4(%esp) +c0102823: 89 04 24 mov %eax,(%esp) +c0102826: e8 e5 63 00 00 call c0108c10 + //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置 + *((uint32_t *)tf - 1) = (uint32_t)switchu2k; +c010282b: 8b 15 cc 57 12 c0 mov 0xc01257cc,%edx +c0102831: 8b 45 08 mov 0x8(%ebp),%eax +c0102834: 83 e8 04 sub $0x4,%eax +c0102837: 89 10 mov %edx,(%eax) + } + break; +c0102839: eb 41 jmp c010287c + break; + default: + // in kernel, it must be a mistake + //检查当前陷阱框架的代码段寄存器 tf->tf_cs 的特权级 + //(tf->tf_cs & 3) == 0 检查是否在内核模式中 + if ((tf->tf_cs & 3) == 0) { +c010283b: 8b 45 08 mov 0x8(%ebp),%eax +c010283e: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0102842: 83 e0 03 and $0x3,%eax +c0102845: 85 c0 test %eax,%eax +c0102847: 75 34 jne c010287d + print_trapframe(tf); +c0102849: 8b 45 08 mov 0x8(%ebp),%eax +c010284c: 89 04 24 mov %eax,(%esp) +c010284f: e8 62 fa ff ff call c01022b6 + panic("unexpected trap in kernel.\n"); +c0102854: c7 44 24 08 fb 93 10 movl $0xc01093fb,0x8(%esp) +c010285b: c0 +c010285c: c7 44 24 04 2f 01 00 movl $0x12f,0x4(%esp) +c0102863: 00 +c0102864: c7 04 24 ae 93 10 c0 movl $0xc01093ae,(%esp) +c010286b: e8 d2 e3 ff ff call c0100c42 <__panic> + break; +c0102870: 90 nop +c0102871: eb 0a jmp c010287d + break; +c0102873: 90 nop +c0102874: eb 07 jmp c010287d + break; +c0102876: 90 nop +c0102877: eb 04 jmp c010287d + break; +c0102879: 90 nop +c010287a: eb 01 jmp c010287d + break; +c010287c: 90 nop + } + } +} +c010287d: 90 nop +c010287e: 8b 5d fc mov -0x4(%ebp),%ebx +c0102881: 89 ec mov %ebp,%esp +c0102883: 5d pop %ebp +c0102884: c3 ret + +c0102885 : + * trap - handles or dispatches an exception/interrupt. if and when trap() returns, + * the code in kern/trap/trapentry.S restores the old CPU state saved in the + * trapframe and then uses the iret instruction to return from the exception. + * */ +void +trap(struct trapframe *tf) { +c0102885: 55 push %ebp +c0102886: 89 e5 mov %esp,%ebp +c0102888: 83 ec 18 sub $0x18,%esp + // dispatch based on what type of trap occurred + //该行代码调用 trap_dispatch 函数,将陷阱帧传递给它。 + trap_dispatch(tf); +c010288b: 8b 45 08 mov 0x8(%ebp),%eax +c010288e: 89 04 24 mov %eax,(%esp) +c0102891: e8 6e fd ff ff call c0102604 +} +c0102896: 90 nop +c0102897: 89 ec mov %ebp,%esp +c0102899: 5d pop %ebp +c010289a: c3 ret + +c010289b <__alltraps>: +.globl __alltraps +__alltraps: + # push registers to build a trap frame + # therefore make the stack look like a struct trapframe + # 通过 push 指令,将数据段寄存器和所有通用寄存器(使用 pushal)的值压入栈中,以保存当前状态。 + pushl %ds +c010289b: 1e push %ds + pushl %es +c010289c: 06 push %es + pushl %fs +c010289d: 0f a0 push %fs + pushl %gs +c010289f: 0f a8 push %gs + pushal +c01028a1: 60 pusha + + # load GD_KDATA into %ds and %es to set up data segments for kernel + # 将常量 GD_KDATA 加载到 %eax 中,然后将其值复制到 %ds 和 %es 中,设置内核的数据段。 + movl $GD_KDATA, %eax +c01028a2: b8 10 00 00 00 mov $0x10,%eax + movw %ax, %ds +c01028a7: 8e d8 mov %eax,%ds + movw %ax, %es +c01028a9: 8e c0 mov %eax,%es + + # push %esp to pass a pointer to the trapframe as an argument to trap() + # 将 %esp 压栈,以将指向 trapframe 的指针作为参数传递给 trap() + pushl %esp +c01028ab: 54 push %esp + + # call trap(tf), where tf=%esp + # 调用 trap(tf),其中 tf=%esp + call trap +c01028ac: e8 d4 ff ff ff call c0102885 + + # pop the pushed stack pointer弹出之前压入的栈指针 + popl %esp +c01028b1: 5c pop %esp + +c01028b2 <__trapret>: + # 返回后继续执行到 trapret... +.globl __trapret +__trapret: + # restore registers from stack + # 定义了返回的入口点 __trapret。 + popal +c01028b2: 61 popa + + # restore %ds, %es, %fs and %gs + # 这里会恢复之前保存的寄存器 + popl %gs +c01028b3: 0f a9 pop %gs + popl %fs +c01028b5: 0f a1 pop %fs + popl %es +c01028b7: 07 pop %es + popl %ds +c01028b8: 1f pop %ds + + # get rid of the trap number and error code + # 通过 iret 指令返回中断处理 + addl $0x8, %esp +c01028b9: 83 c4 08 add $0x8,%esp + iret +c01028bc: cf iret + +c01028bd : +# handler +.text +.globl __alltraps +.globl vector0 +vector0: + pushl $0 +c01028bd: 6a 00 push $0x0 + pushl $0 +c01028bf: 6a 00 push $0x0 + jmp __alltraps +c01028c1: e9 d5 ff ff ff jmp c010289b <__alltraps> + +c01028c6 : +.globl vector1 +vector1: + pushl $0 +c01028c6: 6a 00 push $0x0 + pushl $1 +c01028c8: 6a 01 push $0x1 + jmp __alltraps +c01028ca: e9 cc ff ff ff jmp c010289b <__alltraps> + +c01028cf : +.globl vector2 +vector2: + pushl $0 +c01028cf: 6a 00 push $0x0 + pushl $2 +c01028d1: 6a 02 push $0x2 + jmp __alltraps +c01028d3: e9 c3 ff ff ff jmp c010289b <__alltraps> + +c01028d8 : +.globl vector3 +vector3: + pushl $0 +c01028d8: 6a 00 push $0x0 + pushl $3 +c01028da: 6a 03 push $0x3 + jmp __alltraps +c01028dc: e9 ba ff ff ff jmp c010289b <__alltraps> + +c01028e1 : +.globl vector4 +vector4: + pushl $0 +c01028e1: 6a 00 push $0x0 + pushl $4 +c01028e3: 6a 04 push $0x4 + jmp __alltraps +c01028e5: e9 b1 ff ff ff jmp c010289b <__alltraps> + +c01028ea : +.globl vector5 +vector5: + pushl $0 +c01028ea: 6a 00 push $0x0 + pushl $5 +c01028ec: 6a 05 push $0x5 + jmp __alltraps +c01028ee: e9 a8 ff ff ff jmp c010289b <__alltraps> + +c01028f3 : +.globl vector6 +vector6: + pushl $0 +c01028f3: 6a 00 push $0x0 + pushl $6 +c01028f5: 6a 06 push $0x6 + jmp __alltraps +c01028f7: e9 9f ff ff ff jmp c010289b <__alltraps> + +c01028fc : +.globl vector7 +vector7: + pushl $0 +c01028fc: 6a 00 push $0x0 + pushl $7 +c01028fe: 6a 07 push $0x7 + jmp __alltraps +c0102900: e9 96 ff ff ff jmp c010289b <__alltraps> + +c0102905 : +.globl vector8 +vector8: + pushl $8 +c0102905: 6a 08 push $0x8 + jmp __alltraps +c0102907: e9 8f ff ff ff jmp c010289b <__alltraps> + +c010290c : +.globl vector9 +vector9: + pushl $0 +c010290c: 6a 00 push $0x0 + pushl $9 +c010290e: 6a 09 push $0x9 + jmp __alltraps +c0102910: e9 86 ff ff ff jmp c010289b <__alltraps> + +c0102915 : +.globl vector10 +vector10: + pushl $10 +c0102915: 6a 0a push $0xa + jmp __alltraps +c0102917: e9 7f ff ff ff jmp c010289b <__alltraps> + +c010291c : +.globl vector11 +vector11: + pushl $11 +c010291c: 6a 0b push $0xb + jmp __alltraps +c010291e: e9 78 ff ff ff jmp c010289b <__alltraps> + +c0102923 : +.globl vector12 +vector12: + pushl $12 +c0102923: 6a 0c push $0xc + jmp __alltraps +c0102925: e9 71 ff ff ff jmp c010289b <__alltraps> + +c010292a : +.globl vector13 +vector13: + pushl $13 +c010292a: 6a 0d push $0xd + jmp __alltraps +c010292c: e9 6a ff ff ff jmp c010289b <__alltraps> + +c0102931 : +.globl vector14 +vector14: + pushl $14 +c0102931: 6a 0e push $0xe + jmp __alltraps +c0102933: e9 63 ff ff ff jmp c010289b <__alltraps> + +c0102938 : +.globl vector15 +vector15: + pushl $0 +c0102938: 6a 00 push $0x0 + pushl $15 +c010293a: 6a 0f push $0xf + jmp __alltraps +c010293c: e9 5a ff ff ff jmp c010289b <__alltraps> + +c0102941 : +.globl vector16 +vector16: + pushl $0 +c0102941: 6a 00 push $0x0 + pushl $16 +c0102943: 6a 10 push $0x10 + jmp __alltraps +c0102945: e9 51 ff ff ff jmp c010289b <__alltraps> + +c010294a : +.globl vector17 +vector17: + pushl $17 +c010294a: 6a 11 push $0x11 + jmp __alltraps +c010294c: e9 4a ff ff ff jmp c010289b <__alltraps> + +c0102951 : +.globl vector18 +vector18: + pushl $0 +c0102951: 6a 00 push $0x0 + pushl $18 +c0102953: 6a 12 push $0x12 + jmp __alltraps +c0102955: e9 41 ff ff ff jmp c010289b <__alltraps> + +c010295a : +.globl vector19 +vector19: + pushl $0 +c010295a: 6a 00 push $0x0 + pushl $19 +c010295c: 6a 13 push $0x13 + jmp __alltraps +c010295e: e9 38 ff ff ff jmp c010289b <__alltraps> + +c0102963 : +.globl vector20 +vector20: + pushl $0 +c0102963: 6a 00 push $0x0 + pushl $20 +c0102965: 6a 14 push $0x14 + jmp __alltraps +c0102967: e9 2f ff ff ff jmp c010289b <__alltraps> + +c010296c : +.globl vector21 +vector21: + pushl $0 +c010296c: 6a 00 push $0x0 + pushl $21 +c010296e: 6a 15 push $0x15 + jmp __alltraps +c0102970: e9 26 ff ff ff jmp c010289b <__alltraps> + +c0102975 : +.globl vector22 +vector22: + pushl $0 +c0102975: 6a 00 push $0x0 + pushl $22 +c0102977: 6a 16 push $0x16 + jmp __alltraps +c0102979: e9 1d ff ff ff jmp c010289b <__alltraps> + +c010297e : +.globl vector23 +vector23: + pushl $0 +c010297e: 6a 00 push $0x0 + pushl $23 +c0102980: 6a 17 push $0x17 + jmp __alltraps +c0102982: e9 14 ff ff ff jmp c010289b <__alltraps> + +c0102987 : +.globl vector24 +vector24: + pushl $0 +c0102987: 6a 00 push $0x0 + pushl $24 +c0102989: 6a 18 push $0x18 + jmp __alltraps +c010298b: e9 0b ff ff ff jmp c010289b <__alltraps> + +c0102990 : +.globl vector25 +vector25: + pushl $0 +c0102990: 6a 00 push $0x0 + pushl $25 +c0102992: 6a 19 push $0x19 + jmp __alltraps +c0102994: e9 02 ff ff ff jmp c010289b <__alltraps> + +c0102999 : +.globl vector26 +vector26: + pushl $0 +c0102999: 6a 00 push $0x0 + pushl $26 +c010299b: 6a 1a push $0x1a + jmp __alltraps +c010299d: e9 f9 fe ff ff jmp c010289b <__alltraps> + +c01029a2 : +.globl vector27 +vector27: + pushl $0 +c01029a2: 6a 00 push $0x0 + pushl $27 +c01029a4: 6a 1b push $0x1b + jmp __alltraps +c01029a6: e9 f0 fe ff ff jmp c010289b <__alltraps> + +c01029ab : +.globl vector28 +vector28: + pushl $0 +c01029ab: 6a 00 push $0x0 + pushl $28 +c01029ad: 6a 1c push $0x1c + jmp __alltraps +c01029af: e9 e7 fe ff ff jmp c010289b <__alltraps> + +c01029b4 : +.globl vector29 +vector29: + pushl $0 +c01029b4: 6a 00 push $0x0 + pushl $29 +c01029b6: 6a 1d push $0x1d + jmp __alltraps +c01029b8: e9 de fe ff ff jmp c010289b <__alltraps> + +c01029bd : +.globl vector30 +vector30: + pushl $0 +c01029bd: 6a 00 push $0x0 + pushl $30 +c01029bf: 6a 1e push $0x1e + jmp __alltraps +c01029c1: e9 d5 fe ff ff jmp c010289b <__alltraps> + +c01029c6 : +.globl vector31 +vector31: + pushl $0 +c01029c6: 6a 00 push $0x0 + pushl $31 +c01029c8: 6a 1f push $0x1f + jmp __alltraps +c01029ca: e9 cc fe ff ff jmp c010289b <__alltraps> + +c01029cf : +.globl vector32 +vector32: + pushl $0 +c01029cf: 6a 00 push $0x0 + pushl $32 +c01029d1: 6a 20 push $0x20 + jmp __alltraps +c01029d3: e9 c3 fe ff ff jmp c010289b <__alltraps> + +c01029d8 : +.globl vector33 +vector33: + pushl $0 +c01029d8: 6a 00 push $0x0 + pushl $33 +c01029da: 6a 21 push $0x21 + jmp __alltraps +c01029dc: e9 ba fe ff ff jmp c010289b <__alltraps> + +c01029e1 : +.globl vector34 +vector34: + pushl $0 +c01029e1: 6a 00 push $0x0 + pushl $34 +c01029e3: 6a 22 push $0x22 + jmp __alltraps +c01029e5: e9 b1 fe ff ff jmp c010289b <__alltraps> + +c01029ea : +.globl vector35 +vector35: + pushl $0 +c01029ea: 6a 00 push $0x0 + pushl $35 +c01029ec: 6a 23 push $0x23 + jmp __alltraps +c01029ee: e9 a8 fe ff ff jmp c010289b <__alltraps> + +c01029f3 : +.globl vector36 +vector36: + pushl $0 +c01029f3: 6a 00 push $0x0 + pushl $36 +c01029f5: 6a 24 push $0x24 + jmp __alltraps +c01029f7: e9 9f fe ff ff jmp c010289b <__alltraps> + +c01029fc : +.globl vector37 +vector37: + pushl $0 +c01029fc: 6a 00 push $0x0 + pushl $37 +c01029fe: 6a 25 push $0x25 + jmp __alltraps +c0102a00: e9 96 fe ff ff jmp c010289b <__alltraps> + +c0102a05 : +.globl vector38 +vector38: + pushl $0 +c0102a05: 6a 00 push $0x0 + pushl $38 +c0102a07: 6a 26 push $0x26 + jmp __alltraps +c0102a09: e9 8d fe ff ff jmp c010289b <__alltraps> + +c0102a0e : +.globl vector39 +vector39: + pushl $0 +c0102a0e: 6a 00 push $0x0 + pushl $39 +c0102a10: 6a 27 push $0x27 + jmp __alltraps +c0102a12: e9 84 fe ff ff jmp c010289b <__alltraps> + +c0102a17 : +.globl vector40 +vector40: + pushl $0 +c0102a17: 6a 00 push $0x0 + pushl $40 +c0102a19: 6a 28 push $0x28 + jmp __alltraps +c0102a1b: e9 7b fe ff ff jmp c010289b <__alltraps> + +c0102a20 : +.globl vector41 +vector41: + pushl $0 +c0102a20: 6a 00 push $0x0 + pushl $41 +c0102a22: 6a 29 push $0x29 + jmp __alltraps +c0102a24: e9 72 fe ff ff jmp c010289b <__alltraps> + +c0102a29 : +.globl vector42 +vector42: + pushl $0 +c0102a29: 6a 00 push $0x0 + pushl $42 +c0102a2b: 6a 2a push $0x2a + jmp __alltraps +c0102a2d: e9 69 fe ff ff jmp c010289b <__alltraps> + +c0102a32 : +.globl vector43 +vector43: + pushl $0 +c0102a32: 6a 00 push $0x0 + pushl $43 +c0102a34: 6a 2b push $0x2b + jmp __alltraps +c0102a36: e9 60 fe ff ff jmp c010289b <__alltraps> + +c0102a3b : +.globl vector44 +vector44: + pushl $0 +c0102a3b: 6a 00 push $0x0 + pushl $44 +c0102a3d: 6a 2c push $0x2c + jmp __alltraps +c0102a3f: e9 57 fe ff ff jmp c010289b <__alltraps> + +c0102a44 : +.globl vector45 +vector45: + pushl $0 +c0102a44: 6a 00 push $0x0 + pushl $45 +c0102a46: 6a 2d push $0x2d + jmp __alltraps +c0102a48: e9 4e fe ff ff jmp c010289b <__alltraps> + +c0102a4d : +.globl vector46 +vector46: + pushl $0 +c0102a4d: 6a 00 push $0x0 + pushl $46 +c0102a4f: 6a 2e push $0x2e + jmp __alltraps +c0102a51: e9 45 fe ff ff jmp c010289b <__alltraps> + +c0102a56 : +.globl vector47 +vector47: + pushl $0 +c0102a56: 6a 00 push $0x0 + pushl $47 +c0102a58: 6a 2f push $0x2f + jmp __alltraps +c0102a5a: e9 3c fe ff ff jmp c010289b <__alltraps> + +c0102a5f : +.globl vector48 +vector48: + pushl $0 +c0102a5f: 6a 00 push $0x0 + pushl $48 +c0102a61: 6a 30 push $0x30 + jmp __alltraps +c0102a63: e9 33 fe ff ff jmp c010289b <__alltraps> + +c0102a68 : +.globl vector49 +vector49: + pushl $0 +c0102a68: 6a 00 push $0x0 + pushl $49 +c0102a6a: 6a 31 push $0x31 + jmp __alltraps +c0102a6c: e9 2a fe ff ff jmp c010289b <__alltraps> + +c0102a71 : +.globl vector50 +vector50: + pushl $0 +c0102a71: 6a 00 push $0x0 + pushl $50 +c0102a73: 6a 32 push $0x32 + jmp __alltraps +c0102a75: e9 21 fe ff ff jmp c010289b <__alltraps> + +c0102a7a : +.globl vector51 +vector51: + pushl $0 +c0102a7a: 6a 00 push $0x0 + pushl $51 +c0102a7c: 6a 33 push $0x33 + jmp __alltraps +c0102a7e: e9 18 fe ff ff jmp c010289b <__alltraps> + +c0102a83 : +.globl vector52 +vector52: + pushl $0 +c0102a83: 6a 00 push $0x0 + pushl $52 +c0102a85: 6a 34 push $0x34 + jmp __alltraps +c0102a87: e9 0f fe ff ff jmp c010289b <__alltraps> + +c0102a8c : +.globl vector53 +vector53: + pushl $0 +c0102a8c: 6a 00 push $0x0 + pushl $53 +c0102a8e: 6a 35 push $0x35 + jmp __alltraps +c0102a90: e9 06 fe ff ff jmp c010289b <__alltraps> + +c0102a95 : +.globl vector54 +vector54: + pushl $0 +c0102a95: 6a 00 push $0x0 + pushl $54 +c0102a97: 6a 36 push $0x36 + jmp __alltraps +c0102a99: e9 fd fd ff ff jmp c010289b <__alltraps> + +c0102a9e : +.globl vector55 +vector55: + pushl $0 +c0102a9e: 6a 00 push $0x0 + pushl $55 +c0102aa0: 6a 37 push $0x37 + jmp __alltraps +c0102aa2: e9 f4 fd ff ff jmp c010289b <__alltraps> + +c0102aa7 : +.globl vector56 +vector56: + pushl $0 +c0102aa7: 6a 00 push $0x0 + pushl $56 +c0102aa9: 6a 38 push $0x38 + jmp __alltraps +c0102aab: e9 eb fd ff ff jmp c010289b <__alltraps> + +c0102ab0 : +.globl vector57 +vector57: + pushl $0 +c0102ab0: 6a 00 push $0x0 + pushl $57 +c0102ab2: 6a 39 push $0x39 + jmp __alltraps +c0102ab4: e9 e2 fd ff ff jmp c010289b <__alltraps> + +c0102ab9 : +.globl vector58 +vector58: + pushl $0 +c0102ab9: 6a 00 push $0x0 + pushl $58 +c0102abb: 6a 3a push $0x3a + jmp __alltraps +c0102abd: e9 d9 fd ff ff jmp c010289b <__alltraps> + +c0102ac2 : +.globl vector59 +vector59: + pushl $0 +c0102ac2: 6a 00 push $0x0 + pushl $59 +c0102ac4: 6a 3b push $0x3b + jmp __alltraps +c0102ac6: e9 d0 fd ff ff jmp c010289b <__alltraps> + +c0102acb : +.globl vector60 +vector60: + pushl $0 +c0102acb: 6a 00 push $0x0 + pushl $60 +c0102acd: 6a 3c push $0x3c + jmp __alltraps +c0102acf: e9 c7 fd ff ff jmp c010289b <__alltraps> + +c0102ad4 : +.globl vector61 +vector61: + pushl $0 +c0102ad4: 6a 00 push $0x0 + pushl $61 +c0102ad6: 6a 3d push $0x3d + jmp __alltraps +c0102ad8: e9 be fd ff ff jmp c010289b <__alltraps> + +c0102add : +.globl vector62 +vector62: + pushl $0 +c0102add: 6a 00 push $0x0 + pushl $62 +c0102adf: 6a 3e push $0x3e + jmp __alltraps +c0102ae1: e9 b5 fd ff ff jmp c010289b <__alltraps> + +c0102ae6 : +.globl vector63 +vector63: + pushl $0 +c0102ae6: 6a 00 push $0x0 + pushl $63 +c0102ae8: 6a 3f push $0x3f + jmp __alltraps +c0102aea: e9 ac fd ff ff jmp c010289b <__alltraps> + +c0102aef : +.globl vector64 +vector64: + pushl $0 +c0102aef: 6a 00 push $0x0 + pushl $64 +c0102af1: 6a 40 push $0x40 + jmp __alltraps +c0102af3: e9 a3 fd ff ff jmp c010289b <__alltraps> + +c0102af8 : +.globl vector65 +vector65: + pushl $0 +c0102af8: 6a 00 push $0x0 + pushl $65 +c0102afa: 6a 41 push $0x41 + jmp __alltraps +c0102afc: e9 9a fd ff ff jmp c010289b <__alltraps> + +c0102b01 : +.globl vector66 +vector66: + pushl $0 +c0102b01: 6a 00 push $0x0 + pushl $66 +c0102b03: 6a 42 push $0x42 + jmp __alltraps +c0102b05: e9 91 fd ff ff jmp c010289b <__alltraps> + +c0102b0a : +.globl vector67 +vector67: + pushl $0 +c0102b0a: 6a 00 push $0x0 + pushl $67 +c0102b0c: 6a 43 push $0x43 + jmp __alltraps +c0102b0e: e9 88 fd ff ff jmp c010289b <__alltraps> + +c0102b13 : +.globl vector68 +vector68: + pushl $0 +c0102b13: 6a 00 push $0x0 + pushl $68 +c0102b15: 6a 44 push $0x44 + jmp __alltraps +c0102b17: e9 7f fd ff ff jmp c010289b <__alltraps> + +c0102b1c : +.globl vector69 +vector69: + pushl $0 +c0102b1c: 6a 00 push $0x0 + pushl $69 +c0102b1e: 6a 45 push $0x45 + jmp __alltraps +c0102b20: e9 76 fd ff ff jmp c010289b <__alltraps> + +c0102b25 : +.globl vector70 +vector70: + pushl $0 +c0102b25: 6a 00 push $0x0 + pushl $70 +c0102b27: 6a 46 push $0x46 + jmp __alltraps +c0102b29: e9 6d fd ff ff jmp c010289b <__alltraps> + +c0102b2e : +.globl vector71 +vector71: + pushl $0 +c0102b2e: 6a 00 push $0x0 + pushl $71 +c0102b30: 6a 47 push $0x47 + jmp __alltraps +c0102b32: e9 64 fd ff ff jmp c010289b <__alltraps> + +c0102b37 : +.globl vector72 +vector72: + pushl $0 +c0102b37: 6a 00 push $0x0 + pushl $72 +c0102b39: 6a 48 push $0x48 + jmp __alltraps +c0102b3b: e9 5b fd ff ff jmp c010289b <__alltraps> + +c0102b40 : +.globl vector73 +vector73: + pushl $0 +c0102b40: 6a 00 push $0x0 + pushl $73 +c0102b42: 6a 49 push $0x49 + jmp __alltraps +c0102b44: e9 52 fd ff ff jmp c010289b <__alltraps> + +c0102b49 : +.globl vector74 +vector74: + pushl $0 +c0102b49: 6a 00 push $0x0 + pushl $74 +c0102b4b: 6a 4a push $0x4a + jmp __alltraps +c0102b4d: e9 49 fd ff ff jmp c010289b <__alltraps> + +c0102b52 : +.globl vector75 +vector75: + pushl $0 +c0102b52: 6a 00 push $0x0 + pushl $75 +c0102b54: 6a 4b push $0x4b + jmp __alltraps +c0102b56: e9 40 fd ff ff jmp c010289b <__alltraps> + +c0102b5b : +.globl vector76 +vector76: + pushl $0 +c0102b5b: 6a 00 push $0x0 + pushl $76 +c0102b5d: 6a 4c push $0x4c + jmp __alltraps +c0102b5f: e9 37 fd ff ff jmp c010289b <__alltraps> + +c0102b64 : +.globl vector77 +vector77: + pushl $0 +c0102b64: 6a 00 push $0x0 + pushl $77 +c0102b66: 6a 4d push $0x4d + jmp __alltraps +c0102b68: e9 2e fd ff ff jmp c010289b <__alltraps> + +c0102b6d : +.globl vector78 +vector78: + pushl $0 +c0102b6d: 6a 00 push $0x0 + pushl $78 +c0102b6f: 6a 4e push $0x4e + jmp __alltraps +c0102b71: e9 25 fd ff ff jmp c010289b <__alltraps> + +c0102b76 : +.globl vector79 +vector79: + pushl $0 +c0102b76: 6a 00 push $0x0 + pushl $79 +c0102b78: 6a 4f push $0x4f + jmp __alltraps +c0102b7a: e9 1c fd ff ff jmp c010289b <__alltraps> + +c0102b7f : +.globl vector80 +vector80: + pushl $0 +c0102b7f: 6a 00 push $0x0 + pushl $80 +c0102b81: 6a 50 push $0x50 + jmp __alltraps +c0102b83: e9 13 fd ff ff jmp c010289b <__alltraps> + +c0102b88 : +.globl vector81 +vector81: + pushl $0 +c0102b88: 6a 00 push $0x0 + pushl $81 +c0102b8a: 6a 51 push $0x51 + jmp __alltraps +c0102b8c: e9 0a fd ff ff jmp c010289b <__alltraps> + +c0102b91 : +.globl vector82 +vector82: + pushl $0 +c0102b91: 6a 00 push $0x0 + pushl $82 +c0102b93: 6a 52 push $0x52 + jmp __alltraps +c0102b95: e9 01 fd ff ff jmp c010289b <__alltraps> + +c0102b9a : +.globl vector83 +vector83: + pushl $0 +c0102b9a: 6a 00 push $0x0 + pushl $83 +c0102b9c: 6a 53 push $0x53 + jmp __alltraps +c0102b9e: e9 f8 fc ff ff jmp c010289b <__alltraps> + +c0102ba3 : +.globl vector84 +vector84: + pushl $0 +c0102ba3: 6a 00 push $0x0 + pushl $84 +c0102ba5: 6a 54 push $0x54 + jmp __alltraps +c0102ba7: e9 ef fc ff ff jmp c010289b <__alltraps> + +c0102bac : +.globl vector85 +vector85: + pushl $0 +c0102bac: 6a 00 push $0x0 + pushl $85 +c0102bae: 6a 55 push $0x55 + jmp __alltraps +c0102bb0: e9 e6 fc ff ff jmp c010289b <__alltraps> + +c0102bb5 : +.globl vector86 +vector86: + pushl $0 +c0102bb5: 6a 00 push $0x0 + pushl $86 +c0102bb7: 6a 56 push $0x56 + jmp __alltraps +c0102bb9: e9 dd fc ff ff jmp c010289b <__alltraps> + +c0102bbe : +.globl vector87 +vector87: + pushl $0 +c0102bbe: 6a 00 push $0x0 + pushl $87 +c0102bc0: 6a 57 push $0x57 + jmp __alltraps +c0102bc2: e9 d4 fc ff ff jmp c010289b <__alltraps> + +c0102bc7 : +.globl vector88 +vector88: + pushl $0 +c0102bc7: 6a 00 push $0x0 + pushl $88 +c0102bc9: 6a 58 push $0x58 + jmp __alltraps +c0102bcb: e9 cb fc ff ff jmp c010289b <__alltraps> + +c0102bd0 : +.globl vector89 +vector89: + pushl $0 +c0102bd0: 6a 00 push $0x0 + pushl $89 +c0102bd2: 6a 59 push $0x59 + jmp __alltraps +c0102bd4: e9 c2 fc ff ff jmp c010289b <__alltraps> + +c0102bd9 : +.globl vector90 +vector90: + pushl $0 +c0102bd9: 6a 00 push $0x0 + pushl $90 +c0102bdb: 6a 5a push $0x5a + jmp __alltraps +c0102bdd: e9 b9 fc ff ff jmp c010289b <__alltraps> + +c0102be2 : +.globl vector91 +vector91: + pushl $0 +c0102be2: 6a 00 push $0x0 + pushl $91 +c0102be4: 6a 5b push $0x5b + jmp __alltraps +c0102be6: e9 b0 fc ff ff jmp c010289b <__alltraps> + +c0102beb : +.globl vector92 +vector92: + pushl $0 +c0102beb: 6a 00 push $0x0 + pushl $92 +c0102bed: 6a 5c push $0x5c + jmp __alltraps +c0102bef: e9 a7 fc ff ff jmp c010289b <__alltraps> + +c0102bf4 : +.globl vector93 +vector93: + pushl $0 +c0102bf4: 6a 00 push $0x0 + pushl $93 +c0102bf6: 6a 5d push $0x5d + jmp __alltraps +c0102bf8: e9 9e fc ff ff jmp c010289b <__alltraps> + +c0102bfd : +.globl vector94 +vector94: + pushl $0 +c0102bfd: 6a 00 push $0x0 + pushl $94 +c0102bff: 6a 5e push $0x5e + jmp __alltraps +c0102c01: e9 95 fc ff ff jmp c010289b <__alltraps> + +c0102c06 : +.globl vector95 +vector95: + pushl $0 +c0102c06: 6a 00 push $0x0 + pushl $95 +c0102c08: 6a 5f push $0x5f + jmp __alltraps +c0102c0a: e9 8c fc ff ff jmp c010289b <__alltraps> + +c0102c0f : +.globl vector96 +vector96: + pushl $0 +c0102c0f: 6a 00 push $0x0 + pushl $96 +c0102c11: 6a 60 push $0x60 + jmp __alltraps +c0102c13: e9 83 fc ff ff jmp c010289b <__alltraps> + +c0102c18 : +.globl vector97 +vector97: + pushl $0 +c0102c18: 6a 00 push $0x0 + pushl $97 +c0102c1a: 6a 61 push $0x61 + jmp __alltraps +c0102c1c: e9 7a fc ff ff jmp c010289b <__alltraps> + +c0102c21 : +.globl vector98 +vector98: + pushl $0 +c0102c21: 6a 00 push $0x0 + pushl $98 +c0102c23: 6a 62 push $0x62 + jmp __alltraps +c0102c25: e9 71 fc ff ff jmp c010289b <__alltraps> + +c0102c2a : +.globl vector99 +vector99: + pushl $0 +c0102c2a: 6a 00 push $0x0 + pushl $99 +c0102c2c: 6a 63 push $0x63 + jmp __alltraps +c0102c2e: e9 68 fc ff ff jmp c010289b <__alltraps> + +c0102c33 : +.globl vector100 +vector100: + pushl $0 +c0102c33: 6a 00 push $0x0 + pushl $100 +c0102c35: 6a 64 push $0x64 + jmp __alltraps +c0102c37: e9 5f fc ff ff jmp c010289b <__alltraps> + +c0102c3c : +.globl vector101 +vector101: + pushl $0 +c0102c3c: 6a 00 push $0x0 + pushl $101 +c0102c3e: 6a 65 push $0x65 + jmp __alltraps +c0102c40: e9 56 fc ff ff jmp c010289b <__alltraps> + +c0102c45 : +.globl vector102 +vector102: + pushl $0 +c0102c45: 6a 00 push $0x0 + pushl $102 +c0102c47: 6a 66 push $0x66 + jmp __alltraps +c0102c49: e9 4d fc ff ff jmp c010289b <__alltraps> + +c0102c4e : +.globl vector103 +vector103: + pushl $0 +c0102c4e: 6a 00 push $0x0 + pushl $103 +c0102c50: 6a 67 push $0x67 + jmp __alltraps +c0102c52: e9 44 fc ff ff jmp c010289b <__alltraps> + +c0102c57 : +.globl vector104 +vector104: + pushl $0 +c0102c57: 6a 00 push $0x0 + pushl $104 +c0102c59: 6a 68 push $0x68 + jmp __alltraps +c0102c5b: e9 3b fc ff ff jmp c010289b <__alltraps> + +c0102c60 : +.globl vector105 +vector105: + pushl $0 +c0102c60: 6a 00 push $0x0 + pushl $105 +c0102c62: 6a 69 push $0x69 + jmp __alltraps +c0102c64: e9 32 fc ff ff jmp c010289b <__alltraps> + +c0102c69 : +.globl vector106 +vector106: + pushl $0 +c0102c69: 6a 00 push $0x0 + pushl $106 +c0102c6b: 6a 6a push $0x6a + jmp __alltraps +c0102c6d: e9 29 fc ff ff jmp c010289b <__alltraps> + +c0102c72 : +.globl vector107 +vector107: + pushl $0 +c0102c72: 6a 00 push $0x0 + pushl $107 +c0102c74: 6a 6b push $0x6b + jmp __alltraps +c0102c76: e9 20 fc ff ff jmp c010289b <__alltraps> + +c0102c7b : +.globl vector108 +vector108: + pushl $0 +c0102c7b: 6a 00 push $0x0 + pushl $108 +c0102c7d: 6a 6c push $0x6c + jmp __alltraps +c0102c7f: e9 17 fc ff ff jmp c010289b <__alltraps> + +c0102c84 : +.globl vector109 +vector109: + pushl $0 +c0102c84: 6a 00 push $0x0 + pushl $109 +c0102c86: 6a 6d push $0x6d + jmp __alltraps +c0102c88: e9 0e fc ff ff jmp c010289b <__alltraps> + +c0102c8d : +.globl vector110 +vector110: + pushl $0 +c0102c8d: 6a 00 push $0x0 + pushl $110 +c0102c8f: 6a 6e push $0x6e + jmp __alltraps +c0102c91: e9 05 fc ff ff jmp c010289b <__alltraps> + +c0102c96 : +.globl vector111 +vector111: + pushl $0 +c0102c96: 6a 00 push $0x0 + pushl $111 +c0102c98: 6a 6f push $0x6f + jmp __alltraps +c0102c9a: e9 fc fb ff ff jmp c010289b <__alltraps> + +c0102c9f : +.globl vector112 +vector112: + pushl $0 +c0102c9f: 6a 00 push $0x0 + pushl $112 +c0102ca1: 6a 70 push $0x70 + jmp __alltraps +c0102ca3: e9 f3 fb ff ff jmp c010289b <__alltraps> + +c0102ca8 : +.globl vector113 +vector113: + pushl $0 +c0102ca8: 6a 00 push $0x0 + pushl $113 +c0102caa: 6a 71 push $0x71 + jmp __alltraps +c0102cac: e9 ea fb ff ff jmp c010289b <__alltraps> + +c0102cb1 : +.globl vector114 +vector114: + pushl $0 +c0102cb1: 6a 00 push $0x0 + pushl $114 +c0102cb3: 6a 72 push $0x72 + jmp __alltraps +c0102cb5: e9 e1 fb ff ff jmp c010289b <__alltraps> + +c0102cba : +.globl vector115 +vector115: + pushl $0 +c0102cba: 6a 00 push $0x0 + pushl $115 +c0102cbc: 6a 73 push $0x73 + jmp __alltraps +c0102cbe: e9 d8 fb ff ff jmp c010289b <__alltraps> + +c0102cc3 : +.globl vector116 +vector116: + pushl $0 +c0102cc3: 6a 00 push $0x0 + pushl $116 +c0102cc5: 6a 74 push $0x74 + jmp __alltraps +c0102cc7: e9 cf fb ff ff jmp c010289b <__alltraps> + +c0102ccc : +.globl vector117 +vector117: + pushl $0 +c0102ccc: 6a 00 push $0x0 + pushl $117 +c0102cce: 6a 75 push $0x75 + jmp __alltraps +c0102cd0: e9 c6 fb ff ff jmp c010289b <__alltraps> + +c0102cd5 : +.globl vector118 +vector118: + pushl $0 +c0102cd5: 6a 00 push $0x0 + pushl $118 +c0102cd7: 6a 76 push $0x76 + jmp __alltraps +c0102cd9: e9 bd fb ff ff jmp c010289b <__alltraps> + +c0102cde : +.globl vector119 +vector119: + pushl $0 +c0102cde: 6a 00 push $0x0 + pushl $119 +c0102ce0: 6a 77 push $0x77 + jmp __alltraps +c0102ce2: e9 b4 fb ff ff jmp c010289b <__alltraps> + +c0102ce7 : +.globl vector120 +vector120: + pushl $0 +c0102ce7: 6a 00 push $0x0 + pushl $120 +c0102ce9: 6a 78 push $0x78 + jmp __alltraps +c0102ceb: e9 ab fb ff ff jmp c010289b <__alltraps> + +c0102cf0 : +.globl vector121 +vector121: + pushl $0 +c0102cf0: 6a 00 push $0x0 + pushl $121 +c0102cf2: 6a 79 push $0x79 + jmp __alltraps +c0102cf4: e9 a2 fb ff ff jmp c010289b <__alltraps> + +c0102cf9 : +.globl vector122 +vector122: + pushl $0 +c0102cf9: 6a 00 push $0x0 + pushl $122 +c0102cfb: 6a 7a push $0x7a + jmp __alltraps +c0102cfd: e9 99 fb ff ff jmp c010289b <__alltraps> + +c0102d02 : +.globl vector123 +vector123: + pushl $0 +c0102d02: 6a 00 push $0x0 + pushl $123 +c0102d04: 6a 7b push $0x7b + jmp __alltraps +c0102d06: e9 90 fb ff ff jmp c010289b <__alltraps> + +c0102d0b : +.globl vector124 +vector124: + pushl $0 +c0102d0b: 6a 00 push $0x0 + pushl $124 +c0102d0d: 6a 7c push $0x7c + jmp __alltraps +c0102d0f: e9 87 fb ff ff jmp c010289b <__alltraps> + +c0102d14 : +.globl vector125 +vector125: + pushl $0 +c0102d14: 6a 00 push $0x0 + pushl $125 +c0102d16: 6a 7d push $0x7d + jmp __alltraps +c0102d18: e9 7e fb ff ff jmp c010289b <__alltraps> + +c0102d1d : +.globl vector126 +vector126: + pushl $0 +c0102d1d: 6a 00 push $0x0 + pushl $126 +c0102d1f: 6a 7e push $0x7e + jmp __alltraps +c0102d21: e9 75 fb ff ff jmp c010289b <__alltraps> + +c0102d26 : +.globl vector127 +vector127: + pushl $0 +c0102d26: 6a 00 push $0x0 + pushl $127 +c0102d28: 6a 7f push $0x7f + jmp __alltraps +c0102d2a: e9 6c fb ff ff jmp c010289b <__alltraps> + +c0102d2f : +.globl vector128 +vector128: + pushl $0 +c0102d2f: 6a 00 push $0x0 + pushl $128 +c0102d31: 68 80 00 00 00 push $0x80 + jmp __alltraps +c0102d36: e9 60 fb ff ff jmp c010289b <__alltraps> + +c0102d3b : +.globl vector129 +vector129: + pushl $0 +c0102d3b: 6a 00 push $0x0 + pushl $129 +c0102d3d: 68 81 00 00 00 push $0x81 + jmp __alltraps +c0102d42: e9 54 fb ff ff jmp c010289b <__alltraps> + +c0102d47 : +.globl vector130 +vector130: + pushl $0 +c0102d47: 6a 00 push $0x0 + pushl $130 +c0102d49: 68 82 00 00 00 push $0x82 + jmp __alltraps +c0102d4e: e9 48 fb ff ff jmp c010289b <__alltraps> + +c0102d53 : +.globl vector131 +vector131: + pushl $0 +c0102d53: 6a 00 push $0x0 + pushl $131 +c0102d55: 68 83 00 00 00 push $0x83 + jmp __alltraps +c0102d5a: e9 3c fb ff ff jmp c010289b <__alltraps> + +c0102d5f : +.globl vector132 +vector132: + pushl $0 +c0102d5f: 6a 00 push $0x0 + pushl $132 +c0102d61: 68 84 00 00 00 push $0x84 + jmp __alltraps +c0102d66: e9 30 fb ff ff jmp c010289b <__alltraps> + +c0102d6b : +.globl vector133 +vector133: + pushl $0 +c0102d6b: 6a 00 push $0x0 + pushl $133 +c0102d6d: 68 85 00 00 00 push $0x85 + jmp __alltraps +c0102d72: e9 24 fb ff ff jmp c010289b <__alltraps> + +c0102d77 : +.globl vector134 +vector134: + pushl $0 +c0102d77: 6a 00 push $0x0 + pushl $134 +c0102d79: 68 86 00 00 00 push $0x86 + jmp __alltraps +c0102d7e: e9 18 fb ff ff jmp c010289b <__alltraps> + +c0102d83 : +.globl vector135 +vector135: + pushl $0 +c0102d83: 6a 00 push $0x0 + pushl $135 +c0102d85: 68 87 00 00 00 push $0x87 + jmp __alltraps +c0102d8a: e9 0c fb ff ff jmp c010289b <__alltraps> + +c0102d8f : +.globl vector136 +vector136: + pushl $0 +c0102d8f: 6a 00 push $0x0 + pushl $136 +c0102d91: 68 88 00 00 00 push $0x88 + jmp __alltraps +c0102d96: e9 00 fb ff ff jmp c010289b <__alltraps> + +c0102d9b : +.globl vector137 +vector137: + pushl $0 +c0102d9b: 6a 00 push $0x0 + pushl $137 +c0102d9d: 68 89 00 00 00 push $0x89 + jmp __alltraps +c0102da2: e9 f4 fa ff ff jmp c010289b <__alltraps> + +c0102da7 : +.globl vector138 +vector138: + pushl $0 +c0102da7: 6a 00 push $0x0 + pushl $138 +c0102da9: 68 8a 00 00 00 push $0x8a + jmp __alltraps +c0102dae: e9 e8 fa ff ff jmp c010289b <__alltraps> + +c0102db3 : +.globl vector139 +vector139: + pushl $0 +c0102db3: 6a 00 push $0x0 + pushl $139 +c0102db5: 68 8b 00 00 00 push $0x8b + jmp __alltraps +c0102dba: e9 dc fa ff ff jmp c010289b <__alltraps> + +c0102dbf : +.globl vector140 +vector140: + pushl $0 +c0102dbf: 6a 00 push $0x0 + pushl $140 +c0102dc1: 68 8c 00 00 00 push $0x8c + jmp __alltraps +c0102dc6: e9 d0 fa ff ff jmp c010289b <__alltraps> + +c0102dcb : +.globl vector141 +vector141: + pushl $0 +c0102dcb: 6a 00 push $0x0 + pushl $141 +c0102dcd: 68 8d 00 00 00 push $0x8d + jmp __alltraps +c0102dd2: e9 c4 fa ff ff jmp c010289b <__alltraps> + +c0102dd7 : +.globl vector142 +vector142: + pushl $0 +c0102dd7: 6a 00 push $0x0 + pushl $142 +c0102dd9: 68 8e 00 00 00 push $0x8e + jmp __alltraps +c0102dde: e9 b8 fa ff ff jmp c010289b <__alltraps> + +c0102de3 : +.globl vector143 +vector143: + pushl $0 +c0102de3: 6a 00 push $0x0 + pushl $143 +c0102de5: 68 8f 00 00 00 push $0x8f + jmp __alltraps +c0102dea: e9 ac fa ff ff jmp c010289b <__alltraps> + +c0102def : +.globl vector144 +vector144: + pushl $0 +c0102def: 6a 00 push $0x0 + pushl $144 +c0102df1: 68 90 00 00 00 push $0x90 + jmp __alltraps +c0102df6: e9 a0 fa ff ff jmp c010289b <__alltraps> + +c0102dfb : +.globl vector145 +vector145: + pushl $0 +c0102dfb: 6a 00 push $0x0 + pushl $145 +c0102dfd: 68 91 00 00 00 push $0x91 + jmp __alltraps +c0102e02: e9 94 fa ff ff jmp c010289b <__alltraps> + +c0102e07 : +.globl vector146 +vector146: + pushl $0 +c0102e07: 6a 00 push $0x0 + pushl $146 +c0102e09: 68 92 00 00 00 push $0x92 + jmp __alltraps +c0102e0e: e9 88 fa ff ff jmp c010289b <__alltraps> + +c0102e13 : +.globl vector147 +vector147: + pushl $0 +c0102e13: 6a 00 push $0x0 + pushl $147 +c0102e15: 68 93 00 00 00 push $0x93 + jmp __alltraps +c0102e1a: e9 7c fa ff ff jmp c010289b <__alltraps> + +c0102e1f : +.globl vector148 +vector148: + pushl $0 +c0102e1f: 6a 00 push $0x0 + pushl $148 +c0102e21: 68 94 00 00 00 push $0x94 + jmp __alltraps +c0102e26: e9 70 fa ff ff jmp c010289b <__alltraps> + +c0102e2b : +.globl vector149 +vector149: + pushl $0 +c0102e2b: 6a 00 push $0x0 + pushl $149 +c0102e2d: 68 95 00 00 00 push $0x95 + jmp __alltraps +c0102e32: e9 64 fa ff ff jmp c010289b <__alltraps> + +c0102e37 : +.globl vector150 +vector150: + pushl $0 +c0102e37: 6a 00 push $0x0 + pushl $150 +c0102e39: 68 96 00 00 00 push $0x96 + jmp __alltraps +c0102e3e: e9 58 fa ff ff jmp c010289b <__alltraps> + +c0102e43 : +.globl vector151 +vector151: + pushl $0 +c0102e43: 6a 00 push $0x0 + pushl $151 +c0102e45: 68 97 00 00 00 push $0x97 + jmp __alltraps +c0102e4a: e9 4c fa ff ff jmp c010289b <__alltraps> + +c0102e4f : +.globl vector152 +vector152: + pushl $0 +c0102e4f: 6a 00 push $0x0 + pushl $152 +c0102e51: 68 98 00 00 00 push $0x98 + jmp __alltraps +c0102e56: e9 40 fa ff ff jmp c010289b <__alltraps> + +c0102e5b : +.globl vector153 +vector153: + pushl $0 +c0102e5b: 6a 00 push $0x0 + pushl $153 +c0102e5d: 68 99 00 00 00 push $0x99 + jmp __alltraps +c0102e62: e9 34 fa ff ff jmp c010289b <__alltraps> + +c0102e67 : +.globl vector154 +vector154: + pushl $0 +c0102e67: 6a 00 push $0x0 + pushl $154 +c0102e69: 68 9a 00 00 00 push $0x9a + jmp __alltraps +c0102e6e: e9 28 fa ff ff jmp c010289b <__alltraps> + +c0102e73 : +.globl vector155 +vector155: + pushl $0 +c0102e73: 6a 00 push $0x0 + pushl $155 +c0102e75: 68 9b 00 00 00 push $0x9b + jmp __alltraps +c0102e7a: e9 1c fa ff ff jmp c010289b <__alltraps> + +c0102e7f : +.globl vector156 +vector156: + pushl $0 +c0102e7f: 6a 00 push $0x0 + pushl $156 +c0102e81: 68 9c 00 00 00 push $0x9c + jmp __alltraps +c0102e86: e9 10 fa ff ff jmp c010289b <__alltraps> + +c0102e8b : +.globl vector157 +vector157: + pushl $0 +c0102e8b: 6a 00 push $0x0 + pushl $157 +c0102e8d: 68 9d 00 00 00 push $0x9d + jmp __alltraps +c0102e92: e9 04 fa ff ff jmp c010289b <__alltraps> + +c0102e97 : +.globl vector158 +vector158: + pushl $0 +c0102e97: 6a 00 push $0x0 + pushl $158 +c0102e99: 68 9e 00 00 00 push $0x9e + jmp __alltraps +c0102e9e: e9 f8 f9 ff ff jmp c010289b <__alltraps> + +c0102ea3 : +.globl vector159 +vector159: + pushl $0 +c0102ea3: 6a 00 push $0x0 + pushl $159 +c0102ea5: 68 9f 00 00 00 push $0x9f + jmp __alltraps +c0102eaa: e9 ec f9 ff ff jmp c010289b <__alltraps> + +c0102eaf : +.globl vector160 +vector160: + pushl $0 +c0102eaf: 6a 00 push $0x0 + pushl $160 +c0102eb1: 68 a0 00 00 00 push $0xa0 + jmp __alltraps +c0102eb6: e9 e0 f9 ff ff jmp c010289b <__alltraps> + +c0102ebb : +.globl vector161 +vector161: + pushl $0 +c0102ebb: 6a 00 push $0x0 + pushl $161 +c0102ebd: 68 a1 00 00 00 push $0xa1 + jmp __alltraps +c0102ec2: e9 d4 f9 ff ff jmp c010289b <__alltraps> + +c0102ec7 : +.globl vector162 +vector162: + pushl $0 +c0102ec7: 6a 00 push $0x0 + pushl $162 +c0102ec9: 68 a2 00 00 00 push $0xa2 + jmp __alltraps +c0102ece: e9 c8 f9 ff ff jmp c010289b <__alltraps> + +c0102ed3 : +.globl vector163 +vector163: + pushl $0 +c0102ed3: 6a 00 push $0x0 + pushl $163 +c0102ed5: 68 a3 00 00 00 push $0xa3 + jmp __alltraps +c0102eda: e9 bc f9 ff ff jmp c010289b <__alltraps> + +c0102edf : +.globl vector164 +vector164: + pushl $0 +c0102edf: 6a 00 push $0x0 + pushl $164 +c0102ee1: 68 a4 00 00 00 push $0xa4 + jmp __alltraps +c0102ee6: e9 b0 f9 ff ff jmp c010289b <__alltraps> + +c0102eeb : +.globl vector165 +vector165: + pushl $0 +c0102eeb: 6a 00 push $0x0 + pushl $165 +c0102eed: 68 a5 00 00 00 push $0xa5 + jmp __alltraps +c0102ef2: e9 a4 f9 ff ff jmp c010289b <__alltraps> + +c0102ef7 : +.globl vector166 +vector166: + pushl $0 +c0102ef7: 6a 00 push $0x0 + pushl $166 +c0102ef9: 68 a6 00 00 00 push $0xa6 + jmp __alltraps +c0102efe: e9 98 f9 ff ff jmp c010289b <__alltraps> + +c0102f03 : +.globl vector167 +vector167: + pushl $0 +c0102f03: 6a 00 push $0x0 + pushl $167 +c0102f05: 68 a7 00 00 00 push $0xa7 + jmp __alltraps +c0102f0a: e9 8c f9 ff ff jmp c010289b <__alltraps> + +c0102f0f : +.globl vector168 +vector168: + pushl $0 +c0102f0f: 6a 00 push $0x0 + pushl $168 +c0102f11: 68 a8 00 00 00 push $0xa8 + jmp __alltraps +c0102f16: e9 80 f9 ff ff jmp c010289b <__alltraps> + +c0102f1b : +.globl vector169 +vector169: + pushl $0 +c0102f1b: 6a 00 push $0x0 + pushl $169 +c0102f1d: 68 a9 00 00 00 push $0xa9 + jmp __alltraps +c0102f22: e9 74 f9 ff ff jmp c010289b <__alltraps> + +c0102f27 : +.globl vector170 +vector170: + pushl $0 +c0102f27: 6a 00 push $0x0 + pushl $170 +c0102f29: 68 aa 00 00 00 push $0xaa + jmp __alltraps +c0102f2e: e9 68 f9 ff ff jmp c010289b <__alltraps> + +c0102f33 : +.globl vector171 +vector171: + pushl $0 +c0102f33: 6a 00 push $0x0 + pushl $171 +c0102f35: 68 ab 00 00 00 push $0xab + jmp __alltraps +c0102f3a: e9 5c f9 ff ff jmp c010289b <__alltraps> + +c0102f3f : +.globl vector172 +vector172: + pushl $0 +c0102f3f: 6a 00 push $0x0 + pushl $172 +c0102f41: 68 ac 00 00 00 push $0xac + jmp __alltraps +c0102f46: e9 50 f9 ff ff jmp c010289b <__alltraps> + +c0102f4b : +.globl vector173 +vector173: + pushl $0 +c0102f4b: 6a 00 push $0x0 + pushl $173 +c0102f4d: 68 ad 00 00 00 push $0xad + jmp __alltraps +c0102f52: e9 44 f9 ff ff jmp c010289b <__alltraps> + +c0102f57 : +.globl vector174 +vector174: + pushl $0 +c0102f57: 6a 00 push $0x0 + pushl $174 +c0102f59: 68 ae 00 00 00 push $0xae + jmp __alltraps +c0102f5e: e9 38 f9 ff ff jmp c010289b <__alltraps> + +c0102f63 : +.globl vector175 +vector175: + pushl $0 +c0102f63: 6a 00 push $0x0 + pushl $175 +c0102f65: 68 af 00 00 00 push $0xaf + jmp __alltraps +c0102f6a: e9 2c f9 ff ff jmp c010289b <__alltraps> + +c0102f6f : +.globl vector176 +vector176: + pushl $0 +c0102f6f: 6a 00 push $0x0 + pushl $176 +c0102f71: 68 b0 00 00 00 push $0xb0 + jmp __alltraps +c0102f76: e9 20 f9 ff ff jmp c010289b <__alltraps> + +c0102f7b : +.globl vector177 +vector177: + pushl $0 +c0102f7b: 6a 00 push $0x0 + pushl $177 +c0102f7d: 68 b1 00 00 00 push $0xb1 + jmp __alltraps +c0102f82: e9 14 f9 ff ff jmp c010289b <__alltraps> + +c0102f87 : +.globl vector178 +vector178: + pushl $0 +c0102f87: 6a 00 push $0x0 + pushl $178 +c0102f89: 68 b2 00 00 00 push $0xb2 + jmp __alltraps +c0102f8e: e9 08 f9 ff ff jmp c010289b <__alltraps> + +c0102f93 : +.globl vector179 +vector179: + pushl $0 +c0102f93: 6a 00 push $0x0 + pushl $179 +c0102f95: 68 b3 00 00 00 push $0xb3 + jmp __alltraps +c0102f9a: e9 fc f8 ff ff jmp c010289b <__alltraps> + +c0102f9f : +.globl vector180 +vector180: + pushl $0 +c0102f9f: 6a 00 push $0x0 + pushl $180 +c0102fa1: 68 b4 00 00 00 push $0xb4 + jmp __alltraps +c0102fa6: e9 f0 f8 ff ff jmp c010289b <__alltraps> + +c0102fab : +.globl vector181 +vector181: + pushl $0 +c0102fab: 6a 00 push $0x0 + pushl $181 +c0102fad: 68 b5 00 00 00 push $0xb5 + jmp __alltraps +c0102fb2: e9 e4 f8 ff ff jmp c010289b <__alltraps> + +c0102fb7 : +.globl vector182 +vector182: + pushl $0 +c0102fb7: 6a 00 push $0x0 + pushl $182 +c0102fb9: 68 b6 00 00 00 push $0xb6 + jmp __alltraps +c0102fbe: e9 d8 f8 ff ff jmp c010289b <__alltraps> + +c0102fc3 : +.globl vector183 +vector183: + pushl $0 +c0102fc3: 6a 00 push $0x0 + pushl $183 +c0102fc5: 68 b7 00 00 00 push $0xb7 + jmp __alltraps +c0102fca: e9 cc f8 ff ff jmp c010289b <__alltraps> + +c0102fcf : +.globl vector184 +vector184: + pushl $0 +c0102fcf: 6a 00 push $0x0 + pushl $184 +c0102fd1: 68 b8 00 00 00 push $0xb8 + jmp __alltraps +c0102fd6: e9 c0 f8 ff ff jmp c010289b <__alltraps> + +c0102fdb : +.globl vector185 +vector185: + pushl $0 +c0102fdb: 6a 00 push $0x0 + pushl $185 +c0102fdd: 68 b9 00 00 00 push $0xb9 + jmp __alltraps +c0102fe2: e9 b4 f8 ff ff jmp c010289b <__alltraps> + +c0102fe7 : +.globl vector186 +vector186: + pushl $0 +c0102fe7: 6a 00 push $0x0 + pushl $186 +c0102fe9: 68 ba 00 00 00 push $0xba + jmp __alltraps +c0102fee: e9 a8 f8 ff ff jmp c010289b <__alltraps> + +c0102ff3 : +.globl vector187 +vector187: + pushl $0 +c0102ff3: 6a 00 push $0x0 + pushl $187 +c0102ff5: 68 bb 00 00 00 push $0xbb + jmp __alltraps +c0102ffa: e9 9c f8 ff ff jmp c010289b <__alltraps> + +c0102fff : +.globl vector188 +vector188: + pushl $0 +c0102fff: 6a 00 push $0x0 + pushl $188 +c0103001: 68 bc 00 00 00 push $0xbc + jmp __alltraps +c0103006: e9 90 f8 ff ff jmp c010289b <__alltraps> + +c010300b : +.globl vector189 +vector189: + pushl $0 +c010300b: 6a 00 push $0x0 + pushl $189 +c010300d: 68 bd 00 00 00 push $0xbd + jmp __alltraps +c0103012: e9 84 f8 ff ff jmp c010289b <__alltraps> + +c0103017 : +.globl vector190 +vector190: + pushl $0 +c0103017: 6a 00 push $0x0 + pushl $190 +c0103019: 68 be 00 00 00 push $0xbe + jmp __alltraps +c010301e: e9 78 f8 ff ff jmp c010289b <__alltraps> + +c0103023 : +.globl vector191 +vector191: + pushl $0 +c0103023: 6a 00 push $0x0 + pushl $191 +c0103025: 68 bf 00 00 00 push $0xbf + jmp __alltraps +c010302a: e9 6c f8 ff ff jmp c010289b <__alltraps> + +c010302f : +.globl vector192 +vector192: + pushl $0 +c010302f: 6a 00 push $0x0 + pushl $192 +c0103031: 68 c0 00 00 00 push $0xc0 + jmp __alltraps +c0103036: e9 60 f8 ff ff jmp c010289b <__alltraps> + +c010303b : +.globl vector193 +vector193: + pushl $0 +c010303b: 6a 00 push $0x0 + pushl $193 +c010303d: 68 c1 00 00 00 push $0xc1 + jmp __alltraps +c0103042: e9 54 f8 ff ff jmp c010289b <__alltraps> + +c0103047 : +.globl vector194 +vector194: + pushl $0 +c0103047: 6a 00 push $0x0 + pushl $194 +c0103049: 68 c2 00 00 00 push $0xc2 + jmp __alltraps +c010304e: e9 48 f8 ff ff jmp c010289b <__alltraps> + +c0103053 : +.globl vector195 +vector195: + pushl $0 +c0103053: 6a 00 push $0x0 + pushl $195 +c0103055: 68 c3 00 00 00 push $0xc3 + jmp __alltraps +c010305a: e9 3c f8 ff ff jmp c010289b <__alltraps> + +c010305f : +.globl vector196 +vector196: + pushl $0 +c010305f: 6a 00 push $0x0 + pushl $196 +c0103061: 68 c4 00 00 00 push $0xc4 + jmp __alltraps +c0103066: e9 30 f8 ff ff jmp c010289b <__alltraps> + +c010306b : +.globl vector197 +vector197: + pushl $0 +c010306b: 6a 00 push $0x0 + pushl $197 +c010306d: 68 c5 00 00 00 push $0xc5 + jmp __alltraps +c0103072: e9 24 f8 ff ff jmp c010289b <__alltraps> + +c0103077 : +.globl vector198 +vector198: + pushl $0 +c0103077: 6a 00 push $0x0 + pushl $198 +c0103079: 68 c6 00 00 00 push $0xc6 + jmp __alltraps +c010307e: e9 18 f8 ff ff jmp c010289b <__alltraps> + +c0103083 : +.globl vector199 +vector199: + pushl $0 +c0103083: 6a 00 push $0x0 + pushl $199 +c0103085: 68 c7 00 00 00 push $0xc7 + jmp __alltraps +c010308a: e9 0c f8 ff ff jmp c010289b <__alltraps> + +c010308f : +.globl vector200 +vector200: + pushl $0 +c010308f: 6a 00 push $0x0 + pushl $200 +c0103091: 68 c8 00 00 00 push $0xc8 + jmp __alltraps +c0103096: e9 00 f8 ff ff jmp c010289b <__alltraps> + +c010309b : +.globl vector201 +vector201: + pushl $0 +c010309b: 6a 00 push $0x0 + pushl $201 +c010309d: 68 c9 00 00 00 push $0xc9 + jmp __alltraps +c01030a2: e9 f4 f7 ff ff jmp c010289b <__alltraps> + +c01030a7 : +.globl vector202 +vector202: + pushl $0 +c01030a7: 6a 00 push $0x0 + pushl $202 +c01030a9: 68 ca 00 00 00 push $0xca + jmp __alltraps +c01030ae: e9 e8 f7 ff ff jmp c010289b <__alltraps> + +c01030b3 : +.globl vector203 +vector203: + pushl $0 +c01030b3: 6a 00 push $0x0 + pushl $203 +c01030b5: 68 cb 00 00 00 push $0xcb + jmp __alltraps +c01030ba: e9 dc f7 ff ff jmp c010289b <__alltraps> + +c01030bf : +.globl vector204 +vector204: + pushl $0 +c01030bf: 6a 00 push $0x0 + pushl $204 +c01030c1: 68 cc 00 00 00 push $0xcc + jmp __alltraps +c01030c6: e9 d0 f7 ff ff jmp c010289b <__alltraps> + +c01030cb : +.globl vector205 +vector205: + pushl $0 +c01030cb: 6a 00 push $0x0 + pushl $205 +c01030cd: 68 cd 00 00 00 push $0xcd + jmp __alltraps +c01030d2: e9 c4 f7 ff ff jmp c010289b <__alltraps> + +c01030d7 : +.globl vector206 +vector206: + pushl $0 +c01030d7: 6a 00 push $0x0 + pushl $206 +c01030d9: 68 ce 00 00 00 push $0xce + jmp __alltraps +c01030de: e9 b8 f7 ff ff jmp c010289b <__alltraps> + +c01030e3 : +.globl vector207 +vector207: + pushl $0 +c01030e3: 6a 00 push $0x0 + pushl $207 +c01030e5: 68 cf 00 00 00 push $0xcf + jmp __alltraps +c01030ea: e9 ac f7 ff ff jmp c010289b <__alltraps> + +c01030ef : +.globl vector208 +vector208: + pushl $0 +c01030ef: 6a 00 push $0x0 + pushl $208 +c01030f1: 68 d0 00 00 00 push $0xd0 + jmp __alltraps +c01030f6: e9 a0 f7 ff ff jmp c010289b <__alltraps> + +c01030fb : +.globl vector209 +vector209: + pushl $0 +c01030fb: 6a 00 push $0x0 + pushl $209 +c01030fd: 68 d1 00 00 00 push $0xd1 + jmp __alltraps +c0103102: e9 94 f7 ff ff jmp c010289b <__alltraps> + +c0103107 : +.globl vector210 +vector210: + pushl $0 +c0103107: 6a 00 push $0x0 + pushl $210 +c0103109: 68 d2 00 00 00 push $0xd2 + jmp __alltraps +c010310e: e9 88 f7 ff ff jmp c010289b <__alltraps> + +c0103113 : +.globl vector211 +vector211: + pushl $0 +c0103113: 6a 00 push $0x0 + pushl $211 +c0103115: 68 d3 00 00 00 push $0xd3 + jmp __alltraps +c010311a: e9 7c f7 ff ff jmp c010289b <__alltraps> + +c010311f : +.globl vector212 +vector212: + pushl $0 +c010311f: 6a 00 push $0x0 + pushl $212 +c0103121: 68 d4 00 00 00 push $0xd4 + jmp __alltraps +c0103126: e9 70 f7 ff ff jmp c010289b <__alltraps> + +c010312b : +.globl vector213 +vector213: + pushl $0 +c010312b: 6a 00 push $0x0 + pushl $213 +c010312d: 68 d5 00 00 00 push $0xd5 + jmp __alltraps +c0103132: e9 64 f7 ff ff jmp c010289b <__alltraps> + +c0103137 : +.globl vector214 +vector214: + pushl $0 +c0103137: 6a 00 push $0x0 + pushl $214 +c0103139: 68 d6 00 00 00 push $0xd6 + jmp __alltraps +c010313e: e9 58 f7 ff ff jmp c010289b <__alltraps> + +c0103143 : +.globl vector215 +vector215: + pushl $0 +c0103143: 6a 00 push $0x0 + pushl $215 +c0103145: 68 d7 00 00 00 push $0xd7 + jmp __alltraps +c010314a: e9 4c f7 ff ff jmp c010289b <__alltraps> + +c010314f : +.globl vector216 +vector216: + pushl $0 +c010314f: 6a 00 push $0x0 + pushl $216 +c0103151: 68 d8 00 00 00 push $0xd8 + jmp __alltraps +c0103156: e9 40 f7 ff ff jmp c010289b <__alltraps> + +c010315b : +.globl vector217 +vector217: + pushl $0 +c010315b: 6a 00 push $0x0 + pushl $217 +c010315d: 68 d9 00 00 00 push $0xd9 + jmp __alltraps +c0103162: e9 34 f7 ff ff jmp c010289b <__alltraps> + +c0103167 : +.globl vector218 +vector218: + pushl $0 +c0103167: 6a 00 push $0x0 + pushl $218 +c0103169: 68 da 00 00 00 push $0xda + jmp __alltraps +c010316e: e9 28 f7 ff ff jmp c010289b <__alltraps> + +c0103173 : +.globl vector219 +vector219: + pushl $0 +c0103173: 6a 00 push $0x0 + pushl $219 +c0103175: 68 db 00 00 00 push $0xdb + jmp __alltraps +c010317a: e9 1c f7 ff ff jmp c010289b <__alltraps> + +c010317f : +.globl vector220 +vector220: + pushl $0 +c010317f: 6a 00 push $0x0 + pushl $220 +c0103181: 68 dc 00 00 00 push $0xdc + jmp __alltraps +c0103186: e9 10 f7 ff ff jmp c010289b <__alltraps> + +c010318b : +.globl vector221 +vector221: + pushl $0 +c010318b: 6a 00 push $0x0 + pushl $221 +c010318d: 68 dd 00 00 00 push $0xdd + jmp __alltraps +c0103192: e9 04 f7 ff ff jmp c010289b <__alltraps> + +c0103197 : +.globl vector222 +vector222: + pushl $0 +c0103197: 6a 00 push $0x0 + pushl $222 +c0103199: 68 de 00 00 00 push $0xde + jmp __alltraps +c010319e: e9 f8 f6 ff ff jmp c010289b <__alltraps> + +c01031a3 : +.globl vector223 +vector223: + pushl $0 +c01031a3: 6a 00 push $0x0 + pushl $223 +c01031a5: 68 df 00 00 00 push $0xdf + jmp __alltraps +c01031aa: e9 ec f6 ff ff jmp c010289b <__alltraps> + +c01031af : +.globl vector224 +vector224: + pushl $0 +c01031af: 6a 00 push $0x0 + pushl $224 +c01031b1: 68 e0 00 00 00 push $0xe0 + jmp __alltraps +c01031b6: e9 e0 f6 ff ff jmp c010289b <__alltraps> + +c01031bb : +.globl vector225 +vector225: + pushl $0 +c01031bb: 6a 00 push $0x0 + pushl $225 +c01031bd: 68 e1 00 00 00 push $0xe1 + jmp __alltraps +c01031c2: e9 d4 f6 ff ff jmp c010289b <__alltraps> + +c01031c7 : +.globl vector226 +vector226: + pushl $0 +c01031c7: 6a 00 push $0x0 + pushl $226 +c01031c9: 68 e2 00 00 00 push $0xe2 + jmp __alltraps +c01031ce: e9 c8 f6 ff ff jmp c010289b <__alltraps> + +c01031d3 : +.globl vector227 +vector227: + pushl $0 +c01031d3: 6a 00 push $0x0 + pushl $227 +c01031d5: 68 e3 00 00 00 push $0xe3 + jmp __alltraps +c01031da: e9 bc f6 ff ff jmp c010289b <__alltraps> + +c01031df : +.globl vector228 +vector228: + pushl $0 +c01031df: 6a 00 push $0x0 + pushl $228 +c01031e1: 68 e4 00 00 00 push $0xe4 + jmp __alltraps +c01031e6: e9 b0 f6 ff ff jmp c010289b <__alltraps> + +c01031eb : +.globl vector229 +vector229: + pushl $0 +c01031eb: 6a 00 push $0x0 + pushl $229 +c01031ed: 68 e5 00 00 00 push $0xe5 + jmp __alltraps +c01031f2: e9 a4 f6 ff ff jmp c010289b <__alltraps> + +c01031f7 : +.globl vector230 +vector230: + pushl $0 +c01031f7: 6a 00 push $0x0 + pushl $230 +c01031f9: 68 e6 00 00 00 push $0xe6 + jmp __alltraps +c01031fe: e9 98 f6 ff ff jmp c010289b <__alltraps> + +c0103203 : +.globl vector231 +vector231: + pushl $0 +c0103203: 6a 00 push $0x0 + pushl $231 +c0103205: 68 e7 00 00 00 push $0xe7 + jmp __alltraps +c010320a: e9 8c f6 ff ff jmp c010289b <__alltraps> + +c010320f : +.globl vector232 +vector232: + pushl $0 +c010320f: 6a 00 push $0x0 + pushl $232 +c0103211: 68 e8 00 00 00 push $0xe8 + jmp __alltraps +c0103216: e9 80 f6 ff ff jmp c010289b <__alltraps> + +c010321b : +.globl vector233 +vector233: + pushl $0 +c010321b: 6a 00 push $0x0 + pushl $233 +c010321d: 68 e9 00 00 00 push $0xe9 + jmp __alltraps +c0103222: e9 74 f6 ff ff jmp c010289b <__alltraps> + +c0103227 : +.globl vector234 +vector234: + pushl $0 +c0103227: 6a 00 push $0x0 + pushl $234 +c0103229: 68 ea 00 00 00 push $0xea + jmp __alltraps +c010322e: e9 68 f6 ff ff jmp c010289b <__alltraps> + +c0103233 : +.globl vector235 +vector235: + pushl $0 +c0103233: 6a 00 push $0x0 + pushl $235 +c0103235: 68 eb 00 00 00 push $0xeb + jmp __alltraps +c010323a: e9 5c f6 ff ff jmp c010289b <__alltraps> + +c010323f : +.globl vector236 +vector236: + pushl $0 +c010323f: 6a 00 push $0x0 + pushl $236 +c0103241: 68 ec 00 00 00 push $0xec + jmp __alltraps +c0103246: e9 50 f6 ff ff jmp c010289b <__alltraps> + +c010324b : +.globl vector237 +vector237: + pushl $0 +c010324b: 6a 00 push $0x0 + pushl $237 +c010324d: 68 ed 00 00 00 push $0xed + jmp __alltraps +c0103252: e9 44 f6 ff ff jmp c010289b <__alltraps> + +c0103257 : +.globl vector238 +vector238: + pushl $0 +c0103257: 6a 00 push $0x0 + pushl $238 +c0103259: 68 ee 00 00 00 push $0xee + jmp __alltraps +c010325e: e9 38 f6 ff ff jmp c010289b <__alltraps> + +c0103263 : +.globl vector239 +vector239: + pushl $0 +c0103263: 6a 00 push $0x0 + pushl $239 +c0103265: 68 ef 00 00 00 push $0xef + jmp __alltraps +c010326a: e9 2c f6 ff ff jmp c010289b <__alltraps> + +c010326f : +.globl vector240 +vector240: + pushl $0 +c010326f: 6a 00 push $0x0 + pushl $240 +c0103271: 68 f0 00 00 00 push $0xf0 + jmp __alltraps +c0103276: e9 20 f6 ff ff jmp c010289b <__alltraps> + +c010327b : +.globl vector241 +vector241: + pushl $0 +c010327b: 6a 00 push $0x0 + pushl $241 +c010327d: 68 f1 00 00 00 push $0xf1 + jmp __alltraps +c0103282: e9 14 f6 ff ff jmp c010289b <__alltraps> + +c0103287 : +.globl vector242 +vector242: + pushl $0 +c0103287: 6a 00 push $0x0 + pushl $242 +c0103289: 68 f2 00 00 00 push $0xf2 + jmp __alltraps +c010328e: e9 08 f6 ff ff jmp c010289b <__alltraps> + +c0103293 : +.globl vector243 +vector243: + pushl $0 +c0103293: 6a 00 push $0x0 + pushl $243 +c0103295: 68 f3 00 00 00 push $0xf3 + jmp __alltraps +c010329a: e9 fc f5 ff ff jmp c010289b <__alltraps> + +c010329f : +.globl vector244 +vector244: + pushl $0 +c010329f: 6a 00 push $0x0 + pushl $244 +c01032a1: 68 f4 00 00 00 push $0xf4 + jmp __alltraps +c01032a6: e9 f0 f5 ff ff jmp c010289b <__alltraps> + +c01032ab : +.globl vector245 +vector245: + pushl $0 +c01032ab: 6a 00 push $0x0 + pushl $245 +c01032ad: 68 f5 00 00 00 push $0xf5 + jmp __alltraps +c01032b2: e9 e4 f5 ff ff jmp c010289b <__alltraps> + +c01032b7 : +.globl vector246 +vector246: + pushl $0 +c01032b7: 6a 00 push $0x0 + pushl $246 +c01032b9: 68 f6 00 00 00 push $0xf6 + jmp __alltraps +c01032be: e9 d8 f5 ff ff jmp c010289b <__alltraps> + +c01032c3 : +.globl vector247 +vector247: + pushl $0 +c01032c3: 6a 00 push $0x0 + pushl $247 +c01032c5: 68 f7 00 00 00 push $0xf7 + jmp __alltraps +c01032ca: e9 cc f5 ff ff jmp c010289b <__alltraps> + +c01032cf : +.globl vector248 +vector248: + pushl $0 +c01032cf: 6a 00 push $0x0 + pushl $248 +c01032d1: 68 f8 00 00 00 push $0xf8 + jmp __alltraps +c01032d6: e9 c0 f5 ff ff jmp c010289b <__alltraps> + +c01032db : +.globl vector249 +vector249: + pushl $0 +c01032db: 6a 00 push $0x0 + pushl $249 +c01032dd: 68 f9 00 00 00 push $0xf9 + jmp __alltraps +c01032e2: e9 b4 f5 ff ff jmp c010289b <__alltraps> + +c01032e7 : +.globl vector250 +vector250: + pushl $0 +c01032e7: 6a 00 push $0x0 + pushl $250 +c01032e9: 68 fa 00 00 00 push $0xfa + jmp __alltraps +c01032ee: e9 a8 f5 ff ff jmp c010289b <__alltraps> + +c01032f3 : +.globl vector251 +vector251: + pushl $0 +c01032f3: 6a 00 push $0x0 + pushl $251 +c01032f5: 68 fb 00 00 00 push $0xfb + jmp __alltraps +c01032fa: e9 9c f5 ff ff jmp c010289b <__alltraps> + +c01032ff : +.globl vector252 +vector252: + pushl $0 +c01032ff: 6a 00 push $0x0 + pushl $252 +c0103301: 68 fc 00 00 00 push $0xfc + jmp __alltraps +c0103306: e9 90 f5 ff ff jmp c010289b <__alltraps> + +c010330b : +.globl vector253 +vector253: + pushl $0 +c010330b: 6a 00 push $0x0 + pushl $253 +c010330d: 68 fd 00 00 00 push $0xfd + jmp __alltraps +c0103312: e9 84 f5 ff ff jmp c010289b <__alltraps> + +c0103317 : +.globl vector254 +vector254: + pushl $0 +c0103317: 6a 00 push $0x0 + pushl $254 +c0103319: 68 fe 00 00 00 push $0xfe + jmp __alltraps +c010331e: e9 78 f5 ff ff jmp c010289b <__alltraps> + +c0103323 : +.globl vector255 +vector255: + pushl $0 +c0103323: 6a 00 push $0x0 + pushl $255 +c0103325: 68 ff 00 00 00 push $0xff + jmp __alltraps +c010332a: e9 6c f5 ff ff jmp c010289b <__alltraps> + +c010332f : + +extern struct Page *pages; +extern size_t npage; + +static inline ppn_t +page2ppn(struct Page *page) { +c010332f: 55 push %ebp +c0103330: 89 e5 mov %esp,%ebp + return page - pages; +c0103332: 8b 15 00 60 12 c0 mov 0xc0126000,%edx +c0103338: 8b 45 08 mov 0x8(%ebp),%eax +c010333b: 29 d0 sub %edx,%eax +c010333d: c1 f8 05 sar $0x5,%eax +} +c0103340: 5d pop %ebp +c0103341: c3 ret + +c0103342 : + +static inline uintptr_t +page2pa(struct Page *page) { +c0103342: 55 push %ebp +c0103343: 89 e5 mov %esp,%ebp +c0103345: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0103348: 8b 45 08 mov 0x8(%ebp),%eax +c010334b: 89 04 24 mov %eax,(%esp) +c010334e: e8 dc ff ff ff call c010332f +c0103353: c1 e0 0c shl $0xc,%eax +} +c0103356: 89 ec mov %ebp,%esp +c0103358: 5d pop %ebp +c0103359: c3 ret + +c010335a : +pde2page(pde_t pde) { + return pa2page(PDE_ADDR(pde)); +} + +static inline int +page_ref(struct Page *page) { +c010335a: 55 push %ebp +c010335b: 89 e5 mov %esp,%ebp + return page->ref; +c010335d: 8b 45 08 mov 0x8(%ebp),%eax +c0103360: 8b 00 mov (%eax),%eax +} +c0103362: 5d pop %ebp +c0103363: c3 ret + +c0103364 : + +static inline void +set_page_ref(struct Page *page, int val) { +c0103364: 55 push %ebp +c0103365: 89 e5 mov %esp,%ebp + page->ref = val; +c0103367: 8b 45 08 mov 0x8(%ebp),%eax +c010336a: 8b 55 0c mov 0xc(%ebp),%edx +c010336d: 89 10 mov %edx,(%eax) +} +c010336f: 90 nop +c0103370: 5d pop %ebp +c0103371: c3 ret + +c0103372 : +#define nr_free (free_area.nr_free) + +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 +static void +default_init(void) { +c0103372: 55 push %ebp +c0103373: 89 e5 mov %esp,%ebp +c0103375: 83 ec 10 sub $0x10,%esp +c0103378: c7 45 fc e4 5f 12 c0 movl $0xc0125fe4,-0x4(%ebp) + * list_init - initialize a new entry + * @elm: new entry to be initialized + * */ +static inline void +list_init(list_entry_t *elm) { + elm->prev = elm->next = elm; +c010337f: 8b 45 fc mov -0x4(%ebp),%eax +c0103382: 8b 55 fc mov -0x4(%ebp),%edx +c0103385: 89 50 04 mov %edx,0x4(%eax) +c0103388: 8b 45 fc mov -0x4(%ebp),%eax +c010338b: 8b 50 04 mov 0x4(%eax),%edx +c010338e: 8b 45 fc mov -0x4(%ebp),%eax +c0103391: 89 10 mov %edx,(%eax) +} +c0103393: 90 nop + list_init(&free_list); + nr_free = 0; +c0103394: c7 05 ec 5f 12 c0 00 movl $0x0,0xc0125fec +c010339b: 00 00 00 +} +c010339e: 90 nop +c010339f: 89 ec mov %ebp,%esp +c01033a1: 5d pop %ebp +c01033a2: c3 ret + +c01033a3 : + +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 +static void +default_init_memmap(struct Page *base, size_t n) { +c01033a3: 55 push %ebp +c01033a4: 89 e5 mov %esp,%ebp +c01033a6: 83 ec 48 sub $0x48,%esp + assert(n > 0);// 确保请求的页数大于零 +c01033a9: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01033ad: 75 24 jne c01033d3 +c01033af: c7 44 24 0c 50 96 10 movl $0xc0109650,0xc(%esp) +c01033b6: c0 +c01033b7: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01033be: c0 +c01033bf: c7 44 24 04 9a 00 00 movl $0x9a,0x4(%esp) +c01033c6: 00 +c01033c7: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01033ce: e8 6f d8 ff ff call c0100c42 <__panic> + struct Page *p = base;// 指向当前初始化的页 +c01033d3: 8b 45 08 mov 0x8(%ebp),%eax +c01033d6: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历每一页,设置其状态 + for (; p != base + n; p ++) { +c01033d9: eb 7d jmp c0103458 + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 +c01033db: 8b 45 f4 mov -0xc(%ebp),%eax +c01033de: 83 c0 04 add $0x4,%eax +c01033e1: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) +c01033e8: 89 45 ec mov %eax,-0x14(%ebp) + * @addr: the address to count from + * */ +static inline bool +test_bit(int nr, volatile void *addr) { + int oldbit; + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01033eb: 8b 45 ec mov -0x14(%ebp),%eax +c01033ee: 8b 55 f0 mov -0x10(%ebp),%edx +c01033f1: 0f a3 10 bt %edx,(%eax) +c01033f4: 19 c0 sbb %eax,%eax +c01033f6: 89 45 e8 mov %eax,-0x18(%ebp) + return oldbit != 0; +c01033f9: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01033fd: 0f 95 c0 setne %al +c0103400: 0f b6 c0 movzbl %al,%eax +c0103403: 85 c0 test %eax,%eax +c0103405: 75 24 jne c010342b +c0103407: c7 44 24 0c 81 96 10 movl $0xc0109681,0xc(%esp) +c010340e: c0 +c010340f: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103416: c0 +c0103417: c7 44 24 04 9e 00 00 movl $0x9e,0x4(%esp) +c010341e: 00 +c010341f: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103426: e8 17 d8 ff ff call c0100c42 <__panic> + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 +c010342b: 8b 45 f4 mov -0xc(%ebp),%eax +c010342e: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) +c0103435: 8b 45 f4 mov -0xc(%ebp),%eax +c0103438: 8b 50 08 mov 0x8(%eax),%edx +c010343b: 8b 45 f4 mov -0xc(%ebp),%eax +c010343e: 89 50 04 mov %edx,0x4(%eax) + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 +c0103441: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0103448: 00 +c0103449: 8b 45 f4 mov -0xc(%ebp),%eax +c010344c: 89 04 24 mov %eax,(%esp) +c010344f: e8 10 ff ff ff call c0103364 + for (; p != base + n; p ++) { +c0103454: 83 45 f4 20 addl $0x20,-0xc(%ebp) +c0103458: 8b 45 0c mov 0xc(%ebp),%eax +c010345b: c1 e0 05 shl $0x5,%eax +c010345e: 89 c2 mov %eax,%edx +c0103460: 8b 45 08 mov 0x8(%ebp),%eax +c0103463: 01 d0 add %edx,%eax +c0103465: 39 45 f4 cmp %eax,-0xc(%ebp) +c0103468: 0f 85 6d ff ff ff jne c01033db + } + // 设置第一个页的 property 为块的总数 + base->property = n; +c010346e: 8b 45 08 mov 0x8(%ebp),%eax +c0103471: 8b 55 0c mov 0xc(%ebp),%edx +c0103474: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置当前页的有效标志 +c0103477: 8b 45 08 mov 0x8(%ebp),%eax +c010347a: 83 c0 04 add $0x4,%eax +c010347d: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c0103484: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0103487: 8b 45 cc mov -0x34(%ebp),%eax +c010348a: 8b 55 d0 mov -0x30(%ebp),%edx +c010348d: 0f ab 10 bts %edx,(%eax) +} +c0103490: 90 nop + nr_free += n;// 更新空闲页计数 +c0103491: 8b 15 ec 5f 12 c0 mov 0xc0125fec,%edx +c0103497: 8b 45 0c mov 0xc(%ebp),%eax +c010349a: 01 d0 add %edx,%eax +c010349c: a3 ec 5f 12 c0 mov %eax,0xc0125fec + list_add_before(&free_list, &(base->page_link));// 将该块添加到空闲列表中 +c01034a1: 8b 45 08 mov 0x8(%ebp),%eax +c01034a4: 83 c0 0c add $0xc,%eax +c01034a7: c7 45 e4 e4 5f 12 c0 movl $0xc0125fe4,-0x1c(%ebp) +c01034ae: 89 45 e0 mov %eax,-0x20(%ebp) + * Insert the new element @elm *before* the element @listelm which + * is already in the list. + * */ +static inline void +list_add_before(list_entry_t *listelm, list_entry_t *elm) { + __list_add(elm, listelm->prev, listelm); +c01034b1: 8b 45 e4 mov -0x1c(%ebp),%eax +c01034b4: 8b 00 mov (%eax),%eax +c01034b6: 8b 55 e0 mov -0x20(%ebp),%edx +c01034b9: 89 55 dc mov %edx,-0x24(%ebp) +c01034bc: 89 45 d8 mov %eax,-0x28(%ebp) +c01034bf: 8b 45 e4 mov -0x1c(%ebp),%eax +c01034c2: 89 45 d4 mov %eax,-0x2c(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) { + prev->next = next->prev = elm; +c01034c5: 8b 45 d4 mov -0x2c(%ebp),%eax +c01034c8: 8b 55 dc mov -0x24(%ebp),%edx +c01034cb: 89 10 mov %edx,(%eax) +c01034cd: 8b 45 d4 mov -0x2c(%ebp),%eax +c01034d0: 8b 10 mov (%eax),%edx +c01034d2: 8b 45 d8 mov -0x28(%ebp),%eax +c01034d5: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c01034d8: 8b 45 dc mov -0x24(%ebp),%eax +c01034db: 8b 55 d4 mov -0x2c(%ebp),%edx +c01034de: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c01034e1: 8b 45 dc mov -0x24(%ebp),%eax +c01034e4: 8b 55 d8 mov -0x28(%ebp),%edx +c01034e7: 89 10 mov %edx,(%eax) +} +c01034e9: 90 nop +} +c01034ea: 90 nop +} +c01034eb: 90 nop +c01034ec: 89 ec mov %ebp,%esp +c01034ee: 5d pop %ebp +c01034ef: c3 ret + +c01034f0 : + +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 +static struct Page * +default_alloc_pages(size_t n) { +c01034f0: 55 push %ebp +c01034f1: 89 e5 mov %esp,%ebp +c01034f3: 83 ec 68 sub $0x68,%esp + assert(n > 0);// 确保请求的页数大于零 +c01034f6: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c01034fa: 75 24 jne c0103520 +c01034fc: c7 44 24 0c 50 96 10 movl $0xc0109650,0xc(%esp) +c0103503: c0 +c0103504: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c010350b: c0 +c010350c: c7 44 24 04 ac 00 00 movl $0xac,0x4(%esp) +c0103513: 00 +c0103514: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c010351b: e8 22 d7 ff ff call c0100c42 <__panic> + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 +c0103520: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c0103525: 39 45 08 cmp %eax,0x8(%ebp) +c0103528: 76 0a jbe c0103534 + return NULL; +c010352a: b8 00 00 00 00 mov $0x0,%eax +c010352f: e9 3c 01 00 00 jmp c0103670 + } + struct Page *page = NULL;// 初始化分配的页指针 +c0103534: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + list_entry_t *le = &free_list;// 初始化链表迭代器 +c010353b: c7 45 f0 e4 5f 12 c0 movl $0xc0125fe4,-0x10(%ebp) + // 遍历空闲列表,寻找第一个满足条件的块 + while ((le = list_next(le)) != &free_list) { +c0103542: eb 1c jmp c0103560 + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 +c0103544: 8b 45 f0 mov -0x10(%ebp),%eax +c0103547: 83 e8 0c sub $0xc,%eax +c010354a: 89 45 ec mov %eax,-0x14(%ebp) + if (p->property >= n) {// 检查当前块的页数是否满足请求 +c010354d: 8b 45 ec mov -0x14(%ebp),%eax +c0103550: 8b 40 08 mov 0x8(%eax),%eax +c0103553: 39 45 08 cmp %eax,0x8(%ebp) +c0103556: 77 08 ja c0103560 + page = p;// 找到合适的块 +c0103558: 8b 45 ec mov -0x14(%ebp),%eax +c010355b: 89 45 f4 mov %eax,-0xc(%ebp) + break;// 退出循环 +c010355e: eb 18 jmp c0103578 +c0103560: 8b 45 f0 mov -0x10(%ebp),%eax +c0103563: 89 45 e4 mov %eax,-0x1c(%ebp) + return listelm->next; +c0103566: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103569: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c010356c: 89 45 f0 mov %eax,-0x10(%ebp) +c010356f: 81 7d f0 e4 5f 12 c0 cmpl $0xc0125fe4,-0x10(%ebp) +c0103576: 75 cc jne c0103544 + } + } + if (page != NULL) {// 如果找到合适的块 +c0103578: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010357c: 0f 84 eb 00 00 00 je c010366d + //list_del(&(page->page_link));// 从空闲列表中删除该块 + if (page->property > n) { +c0103582: 8b 45 f4 mov -0xc(%ebp),%eax +c0103585: 8b 40 08 mov 0x8(%eax),%eax +c0103588: 39 45 08 cmp %eax,0x8(%ebp) +c010358b: 0f 83 88 00 00 00 jae c0103619 + struct Page *p = page + n;// 指向剩余的页 +c0103591: 8b 45 08 mov 0x8(%ebp),%eax +c0103594: c1 e0 05 shl $0x5,%eax +c0103597: 89 c2 mov %eax,%edx +c0103599: 8b 45 f4 mov -0xc(%ebp),%eax +c010359c: 01 d0 add %edx,%eax +c010359e: 89 45 e8 mov %eax,-0x18(%ebp) + p->property = page->property - n;// 更新剩余块的页数 +c01035a1: 8b 45 f4 mov -0xc(%ebp),%eax +c01035a4: 8b 40 08 mov 0x8(%eax),%eax +c01035a7: 2b 45 08 sub 0x8(%ebp),%eax +c01035aa: 89 c2 mov %eax,%edx +c01035ac: 8b 45 e8 mov -0x18(%ebp),%eax +c01035af: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(p); +c01035b2: 8b 45 e8 mov -0x18(%ebp),%eax +c01035b5: 83 c0 04 add $0x4,%eax +c01035b8: c7 45 cc 01 00 00 00 movl $0x1,-0x34(%ebp) +c01035bf: 89 45 c8 mov %eax,-0x38(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c01035c2: 8b 45 c8 mov -0x38(%ebp),%eax +c01035c5: 8b 55 cc mov -0x34(%ebp),%edx +c01035c8: 0f ab 10 bts %edx,(%eax) +} +c01035cb: 90 nop + list_add_after(&(page->page_link), &(p->page_link));// 将剩余块添加回空闲列表 +c01035cc: 8b 45 e8 mov -0x18(%ebp),%eax +c01035cf: 83 c0 0c add $0xc,%eax +c01035d2: 8b 55 f4 mov -0xc(%ebp),%edx +c01035d5: 83 c2 0c add $0xc,%edx +c01035d8: 89 55 e0 mov %edx,-0x20(%ebp) +c01035db: 89 45 dc mov %eax,-0x24(%ebp) + __list_add(elm, listelm, listelm->next); +c01035de: 8b 45 e0 mov -0x20(%ebp),%eax +c01035e1: 8b 40 04 mov 0x4(%eax),%eax +c01035e4: 8b 55 dc mov -0x24(%ebp),%edx +c01035e7: 89 55 d8 mov %edx,-0x28(%ebp) +c01035ea: 8b 55 e0 mov -0x20(%ebp),%edx +c01035ed: 89 55 d4 mov %edx,-0x2c(%ebp) +c01035f0: 89 45 d0 mov %eax,-0x30(%ebp) + prev->next = next->prev = elm; +c01035f3: 8b 45 d0 mov -0x30(%ebp),%eax +c01035f6: 8b 55 d8 mov -0x28(%ebp),%edx +c01035f9: 89 10 mov %edx,(%eax) +c01035fb: 8b 45 d0 mov -0x30(%ebp),%eax +c01035fe: 8b 10 mov (%eax),%edx +c0103600: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103603: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0103606: 8b 45 d8 mov -0x28(%ebp),%eax +c0103609: 8b 55 d0 mov -0x30(%ebp),%edx +c010360c: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c010360f: 8b 45 d8 mov -0x28(%ebp),%eax +c0103612: 8b 55 d4 mov -0x2c(%ebp),%edx +c0103615: 89 10 mov %edx,(%eax) +} +c0103617: 90 nop +} +c0103618: 90 nop + } + list_del(&(page->page_link)); +c0103619: 8b 45 f4 mov -0xc(%ebp),%eax +c010361c: 83 c0 0c add $0xc,%eax +c010361f: 89 45 bc mov %eax,-0x44(%ebp) + __list_del(listelm->prev, listelm->next); +c0103622: 8b 45 bc mov -0x44(%ebp),%eax +c0103625: 8b 40 04 mov 0x4(%eax),%eax +c0103628: 8b 55 bc mov -0x44(%ebp),%edx +c010362b: 8b 12 mov (%edx),%edx +c010362d: 89 55 b8 mov %edx,-0x48(%ebp) +c0103630: 89 45 b4 mov %eax,-0x4c(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_del(list_entry_t *prev, list_entry_t *next) { + prev->next = next; +c0103633: 8b 45 b8 mov -0x48(%ebp),%eax +c0103636: 8b 55 b4 mov -0x4c(%ebp),%edx +c0103639: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c010363c: 8b 45 b4 mov -0x4c(%ebp),%eax +c010363f: 8b 55 b8 mov -0x48(%ebp),%edx +c0103642: 89 10 mov %edx,(%eax) +} +c0103644: 90 nop +} +c0103645: 90 nop + nr_free -= n;// 减少空闲页的计数 +c0103646: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c010364b: 2b 45 08 sub 0x8(%ebp),%eax +c010364e: a3 ec 5f 12 c0 mov %eax,0xc0125fec + ClearPageProperty(page);// 清除已分配页的属性 +c0103653: 8b 45 f4 mov -0xc(%ebp),%eax +c0103656: 83 c0 04 add $0x4,%eax +c0103659: c7 45 c4 01 00 00 00 movl $0x1,-0x3c(%ebp) +c0103660: 89 45 c0 mov %eax,-0x40(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0103663: 8b 45 c0 mov -0x40(%ebp),%eax +c0103666: 8b 55 c4 mov -0x3c(%ebp),%edx +c0103669: 0f b3 10 btr %edx,(%eax) +} +c010366c: 90 nop + } + return page;// 返回分配的页块 +c010366d: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0103670: 89 ec mov %ebp,%esp +c0103672: 5d pop %ebp +c0103673: c3 ret + +c0103674 : + +static void +default_free_pages(struct Page *base, size_t n) { +c0103674: 55 push %ebp +c0103675: 89 e5 mov %esp,%ebp +c0103677: 81 ec 98 00 00 00 sub $0x98,%esp + assert(n > 0);// 确保请求释放的页数大于零 +c010367d: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0103681: 75 24 jne c01036a7 +c0103683: c7 44 24 0c 50 96 10 movl $0xc0109650,0xc(%esp) +c010368a: c0 +c010368b: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103692: c0 +c0103693: c7 44 24 04 cb 00 00 movl $0xcb,0x4(%esp) +c010369a: 00 +c010369b: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01036a2: e8 9b d5 ff ff call c0100c42 <__panic> + struct Page *p = base; +c01036a7: 8b 45 08 mov 0x8(%ebp),%eax +c01036aa: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历释放的页,检查状态并重置 + for (; p != base + n; p ++) { +c01036ad: e9 9d 00 00 00 jmp c010374f + assert(!PageReserved(p) && !PageProperty(p));// 确保页没有被保留并且没有属性 +c01036b2: 8b 45 f4 mov -0xc(%ebp),%eax +c01036b5: 83 c0 04 add $0x4,%eax +c01036b8: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) +c01036bf: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01036c2: 8b 45 e8 mov -0x18(%ebp),%eax +c01036c5: 8b 55 ec mov -0x14(%ebp),%edx +c01036c8: 0f a3 10 bt %edx,(%eax) +c01036cb: 19 c0 sbb %eax,%eax +c01036cd: 89 45 e4 mov %eax,-0x1c(%ebp) + return oldbit != 0; +c01036d0: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c01036d4: 0f 95 c0 setne %al +c01036d7: 0f b6 c0 movzbl %al,%eax +c01036da: 85 c0 test %eax,%eax +c01036dc: 75 2c jne c010370a +c01036de: 8b 45 f4 mov -0xc(%ebp),%eax +c01036e1: 83 c0 04 add $0x4,%eax +c01036e4: c7 45 e0 01 00 00 00 movl $0x1,-0x20(%ebp) +c01036eb: 89 45 dc mov %eax,-0x24(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01036ee: 8b 45 dc mov -0x24(%ebp),%eax +c01036f1: 8b 55 e0 mov -0x20(%ebp),%edx +c01036f4: 0f a3 10 bt %edx,(%eax) +c01036f7: 19 c0 sbb %eax,%eax +c01036f9: 89 45 d8 mov %eax,-0x28(%ebp) + return oldbit != 0; +c01036fc: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c0103700: 0f 95 c0 setne %al +c0103703: 0f b6 c0 movzbl %al,%eax +c0103706: 85 c0 test %eax,%eax +c0103708: 74 24 je c010372e +c010370a: c7 44 24 0c 94 96 10 movl $0xc0109694,0xc(%esp) +c0103711: c0 +c0103712: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103719: c0 +c010371a: c7 44 24 04 cf 00 00 movl $0xcf,0x4(%esp) +c0103721: 00 +c0103722: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103729: e8 14 d5 ff ff call c0100c42 <__panic> + p->flags = 0;// 清除 flags 字段 +c010372e: 8b 45 f4 mov -0xc(%ebp),%eax +c0103731: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + set_page_ref(p, 0);// 清除引用计数 +c0103738: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010373f: 00 +c0103740: 8b 45 f4 mov -0xc(%ebp),%eax +c0103743: 89 04 24 mov %eax,(%esp) +c0103746: e8 19 fc ff ff call c0103364 + for (; p != base + n; p ++) { +c010374b: 83 45 f4 20 addl $0x20,-0xc(%ebp) +c010374f: 8b 45 0c mov 0xc(%ebp),%eax +c0103752: c1 e0 05 shl $0x5,%eax +c0103755: 89 c2 mov %eax,%edx +c0103757: 8b 45 08 mov 0x8(%ebp),%eax +c010375a: 01 d0 add %edx,%eax +c010375c: 39 45 f4 cmp %eax,-0xc(%ebp) +c010375f: 0f 85 4d ff ff ff jne c01036b2 + } + // 设置基页的属性为释放的页数 + base->property = n; +c0103765: 8b 45 08 mov 0x8(%ebp),%eax +c0103768: 8b 55 0c mov 0xc(%ebp),%edx +c010376b: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置页的有效标志 +c010376e: 8b 45 08 mov 0x8(%ebp),%eax +c0103771: 83 c0 04 add $0x4,%eax +c0103774: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c010377b: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c010377e: 8b 45 cc mov -0x34(%ebp),%eax +c0103781: 8b 55 d0 mov -0x30(%ebp),%edx +c0103784: 0f ab 10 bts %edx,(%eax) +} +c0103787: 90 nop +c0103788: c7 45 d4 e4 5f 12 c0 movl $0xc0125fe4,-0x2c(%ebp) + return listelm->next; +c010378f: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103792: 8b 40 04 mov 0x4(%eax),%eax + // 遍历空闲列表,检查是否需要合并 + list_entry_t *le = list_next(&free_list); +c0103795: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) { +c0103798: e9 00 01 00 00 jmp c010389d + p = le2page(le, page_link); +c010379d: 8b 45 f0 mov -0x10(%ebp),%eax +c01037a0: 83 e8 0c sub $0xc,%eax +c01037a3: 89 45 f4 mov %eax,-0xc(%ebp) +c01037a6: 8b 45 f0 mov -0x10(%ebp),%eax +c01037a9: 89 45 c8 mov %eax,-0x38(%ebp) +c01037ac: 8b 45 c8 mov -0x38(%ebp),%eax +c01037af: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le); +c01037b2: 89 45 f0 mov %eax,-0x10(%ebp) + // 如果当前页块与释放的页块相邻,合并 + if (base + base->property == p) { +c01037b5: 8b 45 08 mov 0x8(%ebp),%eax +c01037b8: 8b 40 08 mov 0x8(%eax),%eax +c01037bb: c1 e0 05 shl $0x5,%eax +c01037be: 89 c2 mov %eax,%edx +c01037c0: 8b 45 08 mov 0x8(%ebp),%eax +c01037c3: 01 d0 add %edx,%eax +c01037c5: 39 45 f4 cmp %eax,-0xc(%ebp) +c01037c8: 75 5d jne c0103827 + base->property += p->property;// 合并当前页块 +c01037ca: 8b 45 08 mov 0x8(%ebp),%eax +c01037cd: 8b 50 08 mov 0x8(%eax),%edx +c01037d0: 8b 45 f4 mov -0xc(%ebp),%eax +c01037d3: 8b 40 08 mov 0x8(%eax),%eax +c01037d6: 01 c2 add %eax,%edx +c01037d8: 8b 45 08 mov 0x8(%ebp),%eax +c01037db: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(p);// 清除合并页的属性 +c01037de: 8b 45 f4 mov -0xc(%ebp),%eax +c01037e1: 83 c0 04 add $0x4,%eax +c01037e4: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) +c01037eb: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c01037ee: 8b 45 b4 mov -0x4c(%ebp),%eax +c01037f1: 8b 55 b8 mov -0x48(%ebp),%edx +c01037f4: 0f b3 10 btr %edx,(%eax) +} +c01037f7: 90 nop + list_del(&(p->page_link));// 从空闲列表中删除合并页 +c01037f8: 8b 45 f4 mov -0xc(%ebp),%eax +c01037fb: 83 c0 0c add $0xc,%eax +c01037fe: 89 45 c4 mov %eax,-0x3c(%ebp) + __list_del(listelm->prev, listelm->next); +c0103801: 8b 45 c4 mov -0x3c(%ebp),%eax +c0103804: 8b 40 04 mov 0x4(%eax),%eax +c0103807: 8b 55 c4 mov -0x3c(%ebp),%edx +c010380a: 8b 12 mov (%edx),%edx +c010380c: 89 55 c0 mov %edx,-0x40(%ebp) +c010380f: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next; +c0103812: 8b 45 c0 mov -0x40(%ebp),%eax +c0103815: 8b 55 bc mov -0x44(%ebp),%edx +c0103818: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c010381b: 8b 45 bc mov -0x44(%ebp),%eax +c010381e: 8b 55 c0 mov -0x40(%ebp),%edx +c0103821: 89 10 mov %edx,(%eax) +} +c0103823: 90 nop +} +c0103824: 90 nop +c0103825: eb 76 jmp c010389d + } + else if (p + p->property == base) { +c0103827: 8b 45 f4 mov -0xc(%ebp),%eax +c010382a: 8b 40 08 mov 0x8(%eax),%eax +c010382d: c1 e0 05 shl $0x5,%eax +c0103830: 89 c2 mov %eax,%edx +c0103832: 8b 45 f4 mov -0xc(%ebp),%eax +c0103835: 01 d0 add %edx,%eax +c0103837: 39 45 08 cmp %eax,0x8(%ebp) +c010383a: 75 61 jne c010389d + p->property += base->property;// 合并前一个页块 +c010383c: 8b 45 f4 mov -0xc(%ebp),%eax +c010383f: 8b 50 08 mov 0x8(%eax),%edx +c0103842: 8b 45 08 mov 0x8(%ebp),%eax +c0103845: 8b 40 08 mov 0x8(%eax),%eax +c0103848: 01 c2 add %eax,%edx +c010384a: 8b 45 f4 mov -0xc(%ebp),%eax +c010384d: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(base);// 清除当前页的属性 +c0103850: 8b 45 08 mov 0x8(%ebp),%eax +c0103853: 83 c0 04 add $0x4,%eax +c0103856: c7 45 a4 01 00 00 00 movl $0x1,-0x5c(%ebp) +c010385d: 89 45 a0 mov %eax,-0x60(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0103860: 8b 45 a0 mov -0x60(%ebp),%eax +c0103863: 8b 55 a4 mov -0x5c(%ebp),%edx +c0103866: 0f b3 10 btr %edx,(%eax) +} +c0103869: 90 nop + base = p;// 更新 base 指针 +c010386a: 8b 45 f4 mov -0xc(%ebp),%eax +c010386d: 89 45 08 mov %eax,0x8(%ebp) + list_del(&(p->page_link));// 从空闲列表中删除当前页 +c0103870: 8b 45 f4 mov -0xc(%ebp),%eax +c0103873: 83 c0 0c add $0xc,%eax +c0103876: 89 45 b0 mov %eax,-0x50(%ebp) + __list_del(listelm->prev, listelm->next); +c0103879: 8b 45 b0 mov -0x50(%ebp),%eax +c010387c: 8b 40 04 mov 0x4(%eax),%eax +c010387f: 8b 55 b0 mov -0x50(%ebp),%edx +c0103882: 8b 12 mov (%edx),%edx +c0103884: 89 55 ac mov %edx,-0x54(%ebp) +c0103887: 89 45 a8 mov %eax,-0x58(%ebp) + prev->next = next; +c010388a: 8b 45 ac mov -0x54(%ebp),%eax +c010388d: 8b 55 a8 mov -0x58(%ebp),%edx +c0103890: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0103893: 8b 45 a8 mov -0x58(%ebp),%eax +c0103896: 8b 55 ac mov -0x54(%ebp),%edx +c0103899: 89 10 mov %edx,(%eax) +} +c010389b: 90 nop +} +c010389c: 90 nop + while (le != &free_list) { +c010389d: 81 7d f0 e4 5f 12 c0 cmpl $0xc0125fe4,-0x10(%ebp) +c01038a4: 0f 85 f3 fe ff ff jne c010379d + } + } + nr_free += n;// 更新空闲页的计数 +c01038aa: 8b 15 ec 5f 12 c0 mov 0xc0125fec,%edx +c01038b0: 8b 45 0c mov 0xc(%ebp),%eax +c01038b3: 01 d0 add %edx,%eax +c01038b5: a3 ec 5f 12 c0 mov %eax,0xc0125fec +c01038ba: c7 45 9c e4 5f 12 c0 movl $0xc0125fe4,-0x64(%ebp) + return listelm->next; +c01038c1: 8b 45 9c mov -0x64(%ebp),%eax +c01038c4: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(&free_list); +c01038c7: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) +c01038ca: eb 66 jmp c0103932 + { + p = le2page(le, page_link); +c01038cc: 8b 45 f0 mov -0x10(%ebp),%eax +c01038cf: 83 e8 0c sub $0xc,%eax +c01038d2: 89 45 f4 mov %eax,-0xc(%ebp) + if (base + base->property <= p) +c01038d5: 8b 45 08 mov 0x8(%ebp),%eax +c01038d8: 8b 40 08 mov 0x8(%eax),%eax +c01038db: c1 e0 05 shl $0x5,%eax +c01038de: 89 c2 mov %eax,%edx +c01038e0: 8b 45 08 mov 0x8(%ebp),%eax +c01038e3: 01 d0 add %edx,%eax +c01038e5: 39 45 f4 cmp %eax,-0xc(%ebp) +c01038e8: 72 39 jb c0103923 + { + assert(base + base->property != p); +c01038ea: 8b 45 08 mov 0x8(%ebp),%eax +c01038ed: 8b 40 08 mov 0x8(%eax),%eax +c01038f0: c1 e0 05 shl $0x5,%eax +c01038f3: 89 c2 mov %eax,%edx +c01038f5: 8b 45 08 mov 0x8(%ebp),%eax +c01038f8: 01 d0 add %edx,%eax +c01038fa: 39 45 f4 cmp %eax,-0xc(%ebp) +c01038fd: 75 3e jne c010393d +c01038ff: c7 44 24 0c b9 96 10 movl $0xc01096b9,0xc(%esp) +c0103906: c0 +c0103907: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c010390e: c0 +c010390f: c7 44 24 04 ef 00 00 movl $0xef,0x4(%esp) +c0103916: 00 +c0103917: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c010391e: e8 1f d3 ff ff call c0100c42 <__panic> +c0103923: 8b 45 f0 mov -0x10(%ebp),%eax +c0103926: 89 45 98 mov %eax,-0x68(%ebp) +c0103929: 8b 45 98 mov -0x68(%ebp),%eax +c010392c: 8b 40 04 mov 0x4(%eax),%eax + break; + } + le = list_next(le); +c010392f: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) +c0103932: 81 7d f0 e4 5f 12 c0 cmpl $0xc0125fe4,-0x10(%ebp) +c0103939: 75 91 jne c01038cc +c010393b: eb 01 jmp c010393e + break; +c010393d: 90 nop + } + + list_add_before(le, &(base->page_link));// 将释放的页块添加到空闲列表中 +c010393e: 8b 45 08 mov 0x8(%ebp),%eax +c0103941: 8d 50 0c lea 0xc(%eax),%edx +c0103944: 8b 45 f0 mov -0x10(%ebp),%eax +c0103947: 89 45 94 mov %eax,-0x6c(%ebp) +c010394a: 89 55 90 mov %edx,-0x70(%ebp) + __list_add(elm, listelm->prev, listelm); +c010394d: 8b 45 94 mov -0x6c(%ebp),%eax +c0103950: 8b 00 mov (%eax),%eax +c0103952: 8b 55 90 mov -0x70(%ebp),%edx +c0103955: 89 55 8c mov %edx,-0x74(%ebp) +c0103958: 89 45 88 mov %eax,-0x78(%ebp) +c010395b: 8b 45 94 mov -0x6c(%ebp),%eax +c010395e: 89 45 84 mov %eax,-0x7c(%ebp) + prev->next = next->prev = elm; +c0103961: 8b 45 84 mov -0x7c(%ebp),%eax +c0103964: 8b 55 8c mov -0x74(%ebp),%edx +c0103967: 89 10 mov %edx,(%eax) +c0103969: 8b 45 84 mov -0x7c(%ebp),%eax +c010396c: 8b 10 mov (%eax),%edx +c010396e: 8b 45 88 mov -0x78(%ebp),%eax +c0103971: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0103974: 8b 45 8c mov -0x74(%ebp),%eax +c0103977: 8b 55 84 mov -0x7c(%ebp),%edx +c010397a: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c010397d: 8b 45 8c mov -0x74(%ebp),%eax +c0103980: 8b 55 88 mov -0x78(%ebp),%edx +c0103983: 89 10 mov %edx,(%eax) +} +c0103985: 90 nop +} +c0103986: 90 nop +} +c0103987: 90 nop +c0103988: 89 ec mov %ebp,%esp +c010398a: 5d pop %ebp +c010398b: c3 ret + +c010398c : + +//用于返回当前系统中可用的空闲页的数量。 +static size_t +default_nr_free_pages(void) { +c010398c: 55 push %ebp +c010398d: 89 e5 mov %esp,%ebp + return nr_free;// 返回当前空闲页的数量 +c010398f: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +} +c0103994: 5d pop %ebp +c0103995: c3 ret + +c0103996 : + +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 +static void +basic_check(void) { +c0103996: 55 push %ebp +c0103997: 89 e5 mov %esp,%ebp +c0103999: 83 ec 48 sub $0x48,%esp + struct Page *p0, *p1, *p2; + p0 = p1 = p2 = NULL; +c010399c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c01039a3: 8b 45 f4 mov -0xc(%ebp),%eax +c01039a6: 89 45 f0 mov %eax,-0x10(%ebp) +c01039a9: 8b 45 f0 mov -0x10(%ebp),%eax +c01039ac: 89 45 ec mov %eax,-0x14(%ebp) + // 分配三个页面 + assert((p0 = alloc_page()) != NULL); +c01039af: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01039b6: e8 ec 0e 00 00 call c01048a7 +c01039bb: 89 45 ec mov %eax,-0x14(%ebp) +c01039be: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c01039c2: 75 24 jne c01039e8 +c01039c4: c7 44 24 0c d4 96 10 movl $0xc01096d4,0xc(%esp) +c01039cb: c0 +c01039cc: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01039d3: c0 +c01039d4: c7 44 24 04 05 01 00 movl $0x105,0x4(%esp) +c01039db: 00 +c01039dc: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01039e3: e8 5a d2 ff ff call c0100c42 <__panic> + assert((p1 = alloc_page()) != NULL); +c01039e8: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01039ef: e8 b3 0e 00 00 call c01048a7 +c01039f4: 89 45 f0 mov %eax,-0x10(%ebp) +c01039f7: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01039fb: 75 24 jne c0103a21 +c01039fd: c7 44 24 0c f0 96 10 movl $0xc01096f0,0xc(%esp) +c0103a04: c0 +c0103a05: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103a0c: c0 +c0103a0d: c7 44 24 04 06 01 00 movl $0x106,0x4(%esp) +c0103a14: 00 +c0103a15: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103a1c: e8 21 d2 ff ff call c0100c42 <__panic> + assert((p2 = alloc_page()) != NULL); +c0103a21: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103a28: e8 7a 0e 00 00 call c01048a7 +c0103a2d: 89 45 f4 mov %eax,-0xc(%ebp) +c0103a30: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103a34: 75 24 jne c0103a5a +c0103a36: c7 44 24 0c 0c 97 10 movl $0xc010970c,0xc(%esp) +c0103a3d: c0 +c0103a3e: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103a45: c0 +c0103a46: c7 44 24 04 07 01 00 movl $0x107,0x4(%esp) +c0103a4d: 00 +c0103a4e: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103a55: e8 e8 d1 ff ff call c0100c42 <__panic> + // 确保所有分配的页面是不同的 + assert(p0 != p1 && p0 != p2 && p1 != p2); +c0103a5a: 8b 45 ec mov -0x14(%ebp),%eax +c0103a5d: 3b 45 f0 cmp -0x10(%ebp),%eax +c0103a60: 74 10 je c0103a72 +c0103a62: 8b 45 ec mov -0x14(%ebp),%eax +c0103a65: 3b 45 f4 cmp -0xc(%ebp),%eax +c0103a68: 74 08 je c0103a72 +c0103a6a: 8b 45 f0 mov -0x10(%ebp),%eax +c0103a6d: 3b 45 f4 cmp -0xc(%ebp),%eax +c0103a70: 75 24 jne c0103a96 +c0103a72: c7 44 24 0c 28 97 10 movl $0xc0109728,0xc(%esp) +c0103a79: c0 +c0103a7a: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103a81: c0 +c0103a82: c7 44 24 04 09 01 00 movl $0x109,0x4(%esp) +c0103a89: 00 +c0103a8a: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103a91: e8 ac d1 ff ff call c0100c42 <__panic> + // 确保页面的引用计数为 0 + assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); +c0103a96: 8b 45 ec mov -0x14(%ebp),%eax +c0103a99: 89 04 24 mov %eax,(%esp) +c0103a9c: e8 b9 f8 ff ff call c010335a +c0103aa1: 85 c0 test %eax,%eax +c0103aa3: 75 1e jne c0103ac3 +c0103aa5: 8b 45 f0 mov -0x10(%ebp),%eax +c0103aa8: 89 04 24 mov %eax,(%esp) +c0103aab: e8 aa f8 ff ff call c010335a +c0103ab0: 85 c0 test %eax,%eax +c0103ab2: 75 0f jne c0103ac3 +c0103ab4: 8b 45 f4 mov -0xc(%ebp),%eax +c0103ab7: 89 04 24 mov %eax,(%esp) +c0103aba: e8 9b f8 ff ff call c010335a +c0103abf: 85 c0 test %eax,%eax +c0103ac1: 74 24 je c0103ae7 +c0103ac3: c7 44 24 0c 4c 97 10 movl $0xc010974c,0xc(%esp) +c0103aca: c0 +c0103acb: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103ad2: c0 +c0103ad3: c7 44 24 04 0b 01 00 movl $0x10b,0x4(%esp) +c0103ada: 00 +c0103adb: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103ae2: e8 5b d1 ff ff call c0100c42 <__panic> + // 确保页面地址在合法范围内 + assert(page2pa(p0) < npage * PGSIZE); +c0103ae7: 8b 45 ec mov -0x14(%ebp),%eax +c0103aea: 89 04 24 mov %eax,(%esp) +c0103aed: e8 50 f8 ff ff call c0103342 +c0103af2: 8b 15 04 60 12 c0 mov 0xc0126004,%edx +c0103af8: c1 e2 0c shl $0xc,%edx +c0103afb: 39 d0 cmp %edx,%eax +c0103afd: 72 24 jb c0103b23 +c0103aff: c7 44 24 0c 88 97 10 movl $0xc0109788,0xc(%esp) +c0103b06: c0 +c0103b07: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103b0e: c0 +c0103b0f: c7 44 24 04 0d 01 00 movl $0x10d,0x4(%esp) +c0103b16: 00 +c0103b17: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103b1e: e8 1f d1 ff ff call c0100c42 <__panic> + assert(page2pa(p1) < npage * PGSIZE); +c0103b23: 8b 45 f0 mov -0x10(%ebp),%eax +c0103b26: 89 04 24 mov %eax,(%esp) +c0103b29: e8 14 f8 ff ff call c0103342 +c0103b2e: 8b 15 04 60 12 c0 mov 0xc0126004,%edx +c0103b34: c1 e2 0c shl $0xc,%edx +c0103b37: 39 d0 cmp %edx,%eax +c0103b39: 72 24 jb c0103b5f +c0103b3b: c7 44 24 0c a5 97 10 movl $0xc01097a5,0xc(%esp) +c0103b42: c0 +c0103b43: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103b4a: c0 +c0103b4b: c7 44 24 04 0e 01 00 movl $0x10e,0x4(%esp) +c0103b52: 00 +c0103b53: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103b5a: e8 e3 d0 ff ff call c0100c42 <__panic> + assert(page2pa(p2) < npage * PGSIZE); +c0103b5f: 8b 45 f4 mov -0xc(%ebp),%eax +c0103b62: 89 04 24 mov %eax,(%esp) +c0103b65: e8 d8 f7 ff ff call c0103342 +c0103b6a: 8b 15 04 60 12 c0 mov 0xc0126004,%edx +c0103b70: c1 e2 0c shl $0xc,%edx +c0103b73: 39 d0 cmp %edx,%eax +c0103b75: 72 24 jb c0103b9b +c0103b77: c7 44 24 0c c2 97 10 movl $0xc01097c2,0xc(%esp) +c0103b7e: c0 +c0103b7f: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103b86: c0 +c0103b87: c7 44 24 04 0f 01 00 movl $0x10f,0x4(%esp) +c0103b8e: 00 +c0103b8f: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103b96: e8 a7 d0 ff ff call c0100c42 <__panic> + // 保存当前的空闲页面链表和数量 + list_entry_t free_list_store = free_list; +c0103b9b: a1 e4 5f 12 c0 mov 0xc0125fe4,%eax +c0103ba0: 8b 15 e8 5f 12 c0 mov 0xc0125fe8,%edx +c0103ba6: 89 45 d0 mov %eax,-0x30(%ebp) +c0103ba9: 89 55 d4 mov %edx,-0x2c(%ebp) +c0103bac: c7 45 dc e4 5f 12 c0 movl $0xc0125fe4,-0x24(%ebp) + elm->prev = elm->next = elm; +c0103bb3: 8b 45 dc mov -0x24(%ebp),%eax +c0103bb6: 8b 55 dc mov -0x24(%ebp),%edx +c0103bb9: 89 50 04 mov %edx,0x4(%eax) +c0103bbc: 8b 45 dc mov -0x24(%ebp),%eax +c0103bbf: 8b 50 04 mov 0x4(%eax),%edx +c0103bc2: 8b 45 dc mov -0x24(%ebp),%eax +c0103bc5: 89 10 mov %edx,(%eax) +} +c0103bc7: 90 nop +c0103bc8: c7 45 e0 e4 5f 12 c0 movl $0xc0125fe4,-0x20(%ebp) + return list->next == list; +c0103bcf: 8b 45 e0 mov -0x20(%ebp),%eax +c0103bd2: 8b 40 04 mov 0x4(%eax),%eax +c0103bd5: 39 45 e0 cmp %eax,-0x20(%ebp) +c0103bd8: 0f 94 c0 sete %al +c0103bdb: 0f b6 c0 movzbl %al,%eax + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 +c0103bde: 85 c0 test %eax,%eax +c0103be0: 75 24 jne c0103c06 +c0103be2: c7 44 24 0c df 97 10 movl $0xc01097df,0xc(%esp) +c0103be9: c0 +c0103bea: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103bf1: c0 +c0103bf2: c7 44 24 04 13 01 00 movl $0x113,0x4(%esp) +c0103bf9: 00 +c0103bfa: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103c01: e8 3c d0 ff ff call c0100c42 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 +c0103c06: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c0103c0b: 89 45 e8 mov %eax,-0x18(%ebp) + nr_free = 0;// 将空闲页数量设为 0 +c0103c0e: c7 05 ec 5f 12 c0 00 movl $0x0,0xc0125fec +c0103c15: 00 00 00 + // 请求分配页面,但当前没有空闲页面 + assert(alloc_page() == NULL); +c0103c18: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103c1f: e8 83 0c 00 00 call c01048a7 +c0103c24: 85 c0 test %eax,%eax +c0103c26: 74 24 je c0103c4c +c0103c28: c7 44 24 0c f6 97 10 movl $0xc01097f6,0xc(%esp) +c0103c2f: c0 +c0103c30: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103c37: c0 +c0103c38: c7 44 24 04 18 01 00 movl $0x118,0x4(%esp) +c0103c3f: 00 +c0103c40: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103c47: e8 f6 cf ff ff call c0100c42 <__panic> + // 释放之前分配的页面 + free_page(p0); +c0103c4c: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103c53: 00 +c0103c54: 8b 45 ec mov -0x14(%ebp),%eax +c0103c57: 89 04 24 mov %eax,(%esp) +c0103c5a: e8 b5 0c 00 00 call c0104914 + free_page(p1); +c0103c5f: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103c66: 00 +c0103c67: 8b 45 f0 mov -0x10(%ebp),%eax +c0103c6a: 89 04 24 mov %eax,(%esp) +c0103c6d: e8 a2 0c 00 00 call c0104914 + free_page(p2); +c0103c72: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103c79: 00 +c0103c7a: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c7d: 89 04 24 mov %eax,(%esp) +c0103c80: e8 8f 0c 00 00 call c0104914 + assert(nr_free == 3);// 确保释放后空闲页数量为 3 +c0103c85: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c0103c8a: 83 f8 03 cmp $0x3,%eax +c0103c8d: 74 24 je c0103cb3 +c0103c8f: c7 44 24 0c 0b 98 10 movl $0xc010980b,0xc(%esp) +c0103c96: c0 +c0103c97: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103c9e: c0 +c0103c9f: c7 44 24 04 1d 01 00 movl $0x11d,0x4(%esp) +c0103ca6: 00 +c0103ca7: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103cae: e8 8f cf ff ff call c0100c42 <__panic> + // 再次分配三个页面 + assert((p0 = alloc_page()) != NULL); +c0103cb3: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103cba: e8 e8 0b 00 00 call c01048a7 +c0103cbf: 89 45 ec mov %eax,-0x14(%ebp) +c0103cc2: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0103cc6: 75 24 jne c0103cec +c0103cc8: c7 44 24 0c d4 96 10 movl $0xc01096d4,0xc(%esp) +c0103ccf: c0 +c0103cd0: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103cd7: c0 +c0103cd8: c7 44 24 04 1f 01 00 movl $0x11f,0x4(%esp) +c0103cdf: 00 +c0103ce0: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103ce7: e8 56 cf ff ff call c0100c42 <__panic> + assert((p1 = alloc_page()) != NULL); +c0103cec: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103cf3: e8 af 0b 00 00 call c01048a7 +c0103cf8: 89 45 f0 mov %eax,-0x10(%ebp) +c0103cfb: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0103cff: 75 24 jne c0103d25 +c0103d01: c7 44 24 0c f0 96 10 movl $0xc01096f0,0xc(%esp) +c0103d08: c0 +c0103d09: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103d10: c0 +c0103d11: c7 44 24 04 20 01 00 movl $0x120,0x4(%esp) +c0103d18: 00 +c0103d19: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103d20: e8 1d cf ff ff call c0100c42 <__panic> + assert((p2 = alloc_page()) != NULL); +c0103d25: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103d2c: e8 76 0b 00 00 call c01048a7 +c0103d31: 89 45 f4 mov %eax,-0xc(%ebp) +c0103d34: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103d38: 75 24 jne c0103d5e +c0103d3a: c7 44 24 0c 0c 97 10 movl $0xc010970c,0xc(%esp) +c0103d41: c0 +c0103d42: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103d49: c0 +c0103d4a: c7 44 24 04 21 01 00 movl $0x121,0x4(%esp) +c0103d51: 00 +c0103d52: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103d59: e8 e4 ce ff ff call c0100c42 <__panic> + // 测试空闲页面是否不足 + assert(alloc_page() == NULL); +c0103d5e: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103d65: e8 3d 0b 00 00 call c01048a7 +c0103d6a: 85 c0 test %eax,%eax +c0103d6c: 74 24 je c0103d92 +c0103d6e: c7 44 24 0c f6 97 10 movl $0xc01097f6,0xc(%esp) +c0103d75: c0 +c0103d76: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103d7d: c0 +c0103d7e: c7 44 24 04 23 01 00 movl $0x123,0x4(%esp) +c0103d85: 00 +c0103d86: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103d8d: e8 b0 ce ff ff call c0100c42 <__panic> + // 释放 p0,并检查空闲列表 + free_page(p0); +c0103d92: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103d99: 00 +c0103d9a: 8b 45 ec mov -0x14(%ebp),%eax +c0103d9d: 89 04 24 mov %eax,(%esp) +c0103da0: e8 6f 0b 00 00 call c0104914 +c0103da5: c7 45 d8 e4 5f 12 c0 movl $0xc0125fe4,-0x28(%ebp) +c0103dac: 8b 45 d8 mov -0x28(%ebp),%eax +c0103daf: 8b 40 04 mov 0x4(%eax),%eax +c0103db2: 39 45 d8 cmp %eax,-0x28(%ebp) +c0103db5: 0f 94 c0 sete %al +c0103db8: 0f b6 c0 movzbl %al,%eax + assert(!list_empty(&free_list));// 确保空闲列表不为空 +c0103dbb: 85 c0 test %eax,%eax +c0103dbd: 74 24 je c0103de3 +c0103dbf: c7 44 24 0c 18 98 10 movl $0xc0109818,0xc(%esp) +c0103dc6: c0 +c0103dc7: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103dce: c0 +c0103dcf: c7 44 24 04 26 01 00 movl $0x126,0x4(%esp) +c0103dd6: 00 +c0103dd7: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103dde: e8 5f ce ff ff call c0100c42 <__panic> + + struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 + assert((p = alloc_page()) == p0); +c0103de3: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103dea: e8 b8 0a 00 00 call c01048a7 +c0103def: 89 45 e4 mov %eax,-0x1c(%ebp) +c0103df2: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103df5: 3b 45 ec cmp -0x14(%ebp),%eax +c0103df8: 74 24 je c0103e1e +c0103dfa: c7 44 24 0c 30 98 10 movl $0xc0109830,0xc(%esp) +c0103e01: c0 +c0103e02: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103e09: c0 +c0103e0a: c7 44 24 04 2a 01 00 movl $0x12a,0x4(%esp) +c0103e11: 00 +c0103e12: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103e19: e8 24 ce ff ff call c0100c42 <__panic> + assert(alloc_page() == NULL);// 确保没有更多的页面可分配 +c0103e1e: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103e25: e8 7d 0a 00 00 call c01048a7 +c0103e2a: 85 c0 test %eax,%eax +c0103e2c: 74 24 je c0103e52 +c0103e2e: c7 44 24 0c f6 97 10 movl $0xc01097f6,0xc(%esp) +c0103e35: c0 +c0103e36: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103e3d: c0 +c0103e3e: c7 44 24 04 2b 01 00 movl $0x12b,0x4(%esp) +c0103e45: 00 +c0103e46: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103e4d: e8 f0 cd ff ff call c0100c42 <__panic> + + assert(nr_free == 0);// 确保当前空闲页面数量为 0 +c0103e52: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c0103e57: 85 c0 test %eax,%eax +c0103e59: 74 24 je c0103e7f +c0103e5b: c7 44 24 0c 49 98 10 movl $0xc0109849,0xc(%esp) +c0103e62: c0 +c0103e63: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103e6a: c0 +c0103e6b: c7 44 24 04 2d 01 00 movl $0x12d,0x4(%esp) +c0103e72: 00 +c0103e73: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103e7a: e8 c3 cd ff ff call c0100c42 <__panic> + // 恢复之前的空闲页面链表和数量 + free_list = free_list_store; +c0103e7f: 8b 45 d0 mov -0x30(%ebp),%eax +c0103e82: 8b 55 d4 mov -0x2c(%ebp),%edx +c0103e85: a3 e4 5f 12 c0 mov %eax,0xc0125fe4 +c0103e8a: 89 15 e8 5f 12 c0 mov %edx,0xc0125fe8 + nr_free = nr_free_store; +c0103e90: 8b 45 e8 mov -0x18(%ebp),%eax +c0103e93: a3 ec 5f 12 c0 mov %eax,0xc0125fec + // 释放最后的页面 + free_page(p); +c0103e98: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103e9f: 00 +c0103ea0: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103ea3: 89 04 24 mov %eax,(%esp) +c0103ea6: e8 69 0a 00 00 call c0104914 + free_page(p1); +c0103eab: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103eb2: 00 +c0103eb3: 8b 45 f0 mov -0x10(%ebp),%eax +c0103eb6: 89 04 24 mov %eax,(%esp) +c0103eb9: e8 56 0a 00 00 call c0104914 + free_page(p2); +c0103ebe: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103ec5: 00 +c0103ec6: 8b 45 f4 mov -0xc(%ebp),%eax +c0103ec9: 89 04 24 mov %eax,(%esp) +c0103ecc: e8 43 0a 00 00 call c0104914 +} +c0103ed1: 90 nop +c0103ed2: 89 ec mov %ebp,%esp +c0103ed4: 5d pop %ebp +c0103ed5: c3 ret + +c0103ed6 : + +// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) +// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions! +static void +default_check(void) { +c0103ed6: 55 push %ebp +c0103ed7: 89 e5 mov %esp,%ebp +c0103ed9: 81 ec 98 00 00 00 sub $0x98,%esp + int count = 0, total = 0; +c0103edf: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0103ee6: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; +c0103eed: c7 45 ec e4 5f 12 c0 movl $0xc0125fe4,-0x14(%ebp) + // 遍历空闲列表,计算空闲页面的数量和总属性值 + while ((le = list_next(le)) != &free_list) { +c0103ef4: eb 6a jmp c0103f60 + struct Page *p = le2page(le, page_link); +c0103ef6: 8b 45 ec mov -0x14(%ebp),%eax +c0103ef9: 83 e8 0c sub $0xc,%eax +c0103efc: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(PageProperty(p));// 确保每个页面的属性是有效的 +c0103eff: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103f02: 83 c0 04 add $0x4,%eax +c0103f05: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c0103f0c: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0103f0f: 8b 45 cc mov -0x34(%ebp),%eax +c0103f12: 8b 55 d0 mov -0x30(%ebp),%edx +c0103f15: 0f a3 10 bt %edx,(%eax) +c0103f18: 19 c0 sbb %eax,%eax +c0103f1a: 89 45 c8 mov %eax,-0x38(%ebp) + return oldbit != 0; +c0103f1d: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) +c0103f21: 0f 95 c0 setne %al +c0103f24: 0f b6 c0 movzbl %al,%eax +c0103f27: 85 c0 test %eax,%eax +c0103f29: 75 24 jne c0103f4f +c0103f2b: c7 44 24 0c 56 98 10 movl $0xc0109856,0xc(%esp) +c0103f32: c0 +c0103f33: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103f3a: c0 +c0103f3b: c7 44 24 04 40 01 00 movl $0x140,0x4(%esp) +c0103f42: 00 +c0103f43: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103f4a: e8 f3 cc ff ff call c0100c42 <__panic> + count ++, total += p->property;// 累加页面属性 +c0103f4f: ff 45 f4 incl -0xc(%ebp) +c0103f52: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103f55: 8b 50 08 mov 0x8(%eax),%edx +c0103f58: 8b 45 f0 mov -0x10(%ebp),%eax +c0103f5b: 01 d0 add %edx,%eax +c0103f5d: 89 45 f0 mov %eax,-0x10(%ebp) +c0103f60: 8b 45 ec mov -0x14(%ebp),%eax +c0103f63: 89 45 c4 mov %eax,-0x3c(%ebp) + return listelm->next; +c0103f66: 8b 45 c4 mov -0x3c(%ebp),%eax +c0103f69: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0103f6c: 89 45 ec mov %eax,-0x14(%ebp) +c0103f6f: 81 7d ec e4 5f 12 c0 cmpl $0xc0125fe4,-0x14(%ebp) +c0103f76: 0f 85 7a ff ff ff jne c0103ef6 + } + // 确保总属性值与空闲页面数量匹配 + assert(total == nr_free_pages()); +c0103f7c: e8 c8 09 00 00 call c0104949 +c0103f81: 8b 55 f0 mov -0x10(%ebp),%edx +c0103f84: 39 d0 cmp %edx,%eax +c0103f86: 74 24 je c0103fac +c0103f88: c7 44 24 0c 66 98 10 movl $0xc0109866,0xc(%esp) +c0103f8f: c0 +c0103f90: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103f97: c0 +c0103f98: c7 44 24 04 44 01 00 movl $0x144,0x4(%esp) +c0103f9f: 00 +c0103fa0: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103fa7: e8 96 cc ff ff call c0100c42 <__panic> + // 调用 basic_check 以验证基本的内存管理功能 + basic_check(); +c0103fac: e8 e5 f9 ff ff call c0103996 + // 分配 5 个页面 + struct Page *p0 = alloc_pages(5), *p1, *p2; +c0103fb1: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c0103fb8: e8 ea 08 00 00 call c01048a7 +c0103fbd: 89 45 e8 mov %eax,-0x18(%ebp) + assert(p0 != NULL);// 确保成功分配 +c0103fc0: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0103fc4: 75 24 jne c0103fea +c0103fc6: c7 44 24 0c 7f 98 10 movl $0xc010987f,0xc(%esp) +c0103fcd: c0 +c0103fce: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0103fd5: c0 +c0103fd6: c7 44 24 04 49 01 00 movl $0x149,0x4(%esp) +c0103fdd: 00 +c0103fde: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0103fe5: e8 58 cc ff ff call c0100c42 <__panic> + assert(!PageProperty(p0));// 确保分配的页面不带属性 +c0103fea: 8b 45 e8 mov -0x18(%ebp),%eax +c0103fed: 83 c0 04 add $0x4,%eax +c0103ff0: c7 45 c0 01 00 00 00 movl $0x1,-0x40(%ebp) +c0103ff7: 89 45 bc mov %eax,-0x44(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0103ffa: 8b 45 bc mov -0x44(%ebp),%eax +c0103ffd: 8b 55 c0 mov -0x40(%ebp),%edx +c0104000: 0f a3 10 bt %edx,(%eax) +c0104003: 19 c0 sbb %eax,%eax +c0104005: 89 45 b8 mov %eax,-0x48(%ebp) + return oldbit != 0; +c0104008: 83 7d b8 00 cmpl $0x0,-0x48(%ebp) +c010400c: 0f 95 c0 setne %al +c010400f: 0f b6 c0 movzbl %al,%eax +c0104012: 85 c0 test %eax,%eax +c0104014: 74 24 je c010403a +c0104016: c7 44 24 0c 8a 98 10 movl $0xc010988a,0xc(%esp) +c010401d: c0 +c010401e: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104025: c0 +c0104026: c7 44 24 04 4a 01 00 movl $0x14a,0x4(%esp) +c010402d: 00 +c010402e: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104035: e8 08 cc ff ff call c0100c42 <__panic> + // 初始化并检查空闲列表 + list_entry_t free_list_store = free_list; +c010403a: a1 e4 5f 12 c0 mov 0xc0125fe4,%eax +c010403f: 8b 15 e8 5f 12 c0 mov 0xc0125fe8,%edx +c0104045: 89 45 80 mov %eax,-0x80(%ebp) +c0104048: 89 55 84 mov %edx,-0x7c(%ebp) +c010404b: c7 45 b0 e4 5f 12 c0 movl $0xc0125fe4,-0x50(%ebp) + elm->prev = elm->next = elm; +c0104052: 8b 45 b0 mov -0x50(%ebp),%eax +c0104055: 8b 55 b0 mov -0x50(%ebp),%edx +c0104058: 89 50 04 mov %edx,0x4(%eax) +c010405b: 8b 45 b0 mov -0x50(%ebp),%eax +c010405e: 8b 50 04 mov 0x4(%eax),%edx +c0104061: 8b 45 b0 mov -0x50(%ebp),%eax +c0104064: 89 10 mov %edx,(%eax) +} +c0104066: 90 nop +c0104067: c7 45 b4 e4 5f 12 c0 movl $0xc0125fe4,-0x4c(%ebp) + return list->next == list; +c010406e: 8b 45 b4 mov -0x4c(%ebp),%eax +c0104071: 8b 40 04 mov 0x4(%eax),%eax +c0104074: 39 45 b4 cmp %eax,-0x4c(%ebp) +c0104077: 0f 94 c0 sete %al +c010407a: 0f b6 c0 movzbl %al,%eax + list_init(&free_list); + assert(list_empty(&free_list));// 确保空闲列表为空 +c010407d: 85 c0 test %eax,%eax +c010407f: 75 24 jne c01040a5 +c0104081: c7 44 24 0c df 97 10 movl $0xc01097df,0xc(%esp) +c0104088: c0 +c0104089: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104090: c0 +c0104091: c7 44 24 04 4e 01 00 movl $0x14e,0x4(%esp) +c0104098: 00 +c0104099: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01040a0: e8 9d cb ff ff call c0100c42 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c01040a5: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01040ac: e8 f6 07 00 00 call c01048a7 +c01040b1: 85 c0 test %eax,%eax +c01040b3: 74 24 je c01040d9 +c01040b5: c7 44 24 0c f6 97 10 movl $0xc01097f6,0xc(%esp) +c01040bc: c0 +c01040bd: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01040c4: c0 +c01040c5: c7 44 24 04 4f 01 00 movl $0x14f,0x4(%esp) +c01040cc: 00 +c01040cd: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01040d4: e8 69 cb ff ff call c0100c42 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 +c01040d9: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c01040de: 89 45 e4 mov %eax,-0x1c(%ebp) + nr_free = 0;// 将空闲页数设为 0 +c01040e1: c7 05 ec 5f 12 c0 00 movl $0x0,0xc0125fec +c01040e8: 00 00 00 + // 释放 3 个页面并确保分配页面时没有足够的空闲页 + free_pages(p0 + 2, 3); +c01040eb: 8b 45 e8 mov -0x18(%ebp),%eax +c01040ee: 83 c0 40 add $0x40,%eax +c01040f1: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c01040f8: 00 +c01040f9: 89 04 24 mov %eax,(%esp) +c01040fc: e8 13 08 00 00 call c0104914 + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 +c0104101: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c0104108: e8 9a 07 00 00 call c01048a7 +c010410d: 85 c0 test %eax,%eax +c010410f: 74 24 je c0104135 +c0104111: c7 44 24 0c 9c 98 10 movl $0xc010989c,0xc(%esp) +c0104118: c0 +c0104119: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104120: c0 +c0104121: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) +c0104128: 00 +c0104129: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104130: e8 0d cb ff ff call c0100c42 <__panic> + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 +c0104135: 8b 45 e8 mov -0x18(%ebp),%eax +c0104138: 83 c0 40 add $0x40,%eax +c010413b: 83 c0 04 add $0x4,%eax +c010413e: c7 45 ac 01 00 00 00 movl $0x1,-0x54(%ebp) +c0104145: 89 45 a8 mov %eax,-0x58(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0104148: 8b 45 a8 mov -0x58(%ebp),%eax +c010414b: 8b 55 ac mov -0x54(%ebp),%edx +c010414e: 0f a3 10 bt %edx,(%eax) +c0104151: 19 c0 sbb %eax,%eax +c0104153: 89 45 a4 mov %eax,-0x5c(%ebp) + return oldbit != 0; +c0104156: 83 7d a4 00 cmpl $0x0,-0x5c(%ebp) +c010415a: 0f 95 c0 setne %al +c010415d: 0f b6 c0 movzbl %al,%eax +c0104160: 85 c0 test %eax,%eax +c0104162: 74 0e je c0104172 +c0104164: 8b 45 e8 mov -0x18(%ebp),%eax +c0104167: 83 c0 40 add $0x40,%eax +c010416a: 8b 40 08 mov 0x8(%eax),%eax +c010416d: 83 f8 03 cmp $0x3,%eax +c0104170: 74 24 je c0104196 +c0104172: c7 44 24 0c b4 98 10 movl $0xc01098b4,0xc(%esp) +c0104179: c0 +c010417a: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104181: c0 +c0104182: c7 44 24 04 56 01 00 movl $0x156,0x4(%esp) +c0104189: 00 +c010418a: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104191: e8 ac ca ff ff call c0100c42 <__panic> + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 +c0104196: c7 04 24 03 00 00 00 movl $0x3,(%esp) +c010419d: e8 05 07 00 00 call c01048a7 +c01041a2: 89 45 e0 mov %eax,-0x20(%ebp) +c01041a5: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c01041a9: 75 24 jne c01041cf +c01041ab: c7 44 24 0c e0 98 10 movl $0xc01098e0,0xc(%esp) +c01041b2: c0 +c01041b3: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01041ba: c0 +c01041bb: c7 44 24 04 57 01 00 movl $0x157,0x4(%esp) +c01041c2: 00 +c01041c3: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01041ca: e8 73 ca ff ff call c0100c42 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c01041cf: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01041d6: e8 cc 06 00 00 call c01048a7 +c01041db: 85 c0 test %eax,%eax +c01041dd: 74 24 je c0104203 +c01041df: c7 44 24 0c f6 97 10 movl $0xc01097f6,0xc(%esp) +c01041e6: c0 +c01041e7: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01041ee: c0 +c01041ef: c7 44 24 04 58 01 00 movl $0x158,0x4(%esp) +c01041f6: 00 +c01041f7: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01041fe: e8 3f ca ff ff call c0100c42 <__panic> + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 +c0104203: 8b 45 e8 mov -0x18(%ebp),%eax +c0104206: 83 c0 40 add $0x40,%eax +c0104209: 39 45 e0 cmp %eax,-0x20(%ebp) +c010420c: 74 24 je c0104232 +c010420e: c7 44 24 0c fe 98 10 movl $0xc01098fe,0xc(%esp) +c0104215: c0 +c0104216: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c010421d: c0 +c010421e: c7 44 24 04 59 01 00 movl $0x159,0x4(%esp) +c0104225: 00 +c0104226: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c010422d: e8 10 ca ff ff call c0100c42 <__panic> + + p2 = p0 + 1;// 设置 p2 为 p0 的下一个页面 +c0104232: 8b 45 e8 mov -0x18(%ebp),%eax +c0104235: 83 c0 20 add $0x20,%eax +c0104238: 89 45 dc mov %eax,-0x24(%ebp) + free_page(p0);// 释放 p0 页面 +c010423b: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104242: 00 +c0104243: 8b 45 e8 mov -0x18(%ebp),%eax +c0104246: 89 04 24 mov %eax,(%esp) +c0104249: e8 c6 06 00 00 call c0104914 + free_pages(p1, 3);// 释放 p1 指向的页面 +c010424e: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c0104255: 00 +c0104256: 8b 45 e0 mov -0x20(%ebp),%eax +c0104259: 89 04 24 mov %eax,(%esp) +c010425c: e8 b3 06 00 00 call c0104914 + assert(PageProperty(p0) && p0->property == 1);// 检查 p0 属性 +c0104261: 8b 45 e8 mov -0x18(%ebp),%eax +c0104264: 83 c0 04 add $0x4,%eax +c0104267: c7 45 a0 01 00 00 00 movl $0x1,-0x60(%ebp) +c010426e: 89 45 9c mov %eax,-0x64(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0104271: 8b 45 9c mov -0x64(%ebp),%eax +c0104274: 8b 55 a0 mov -0x60(%ebp),%edx +c0104277: 0f a3 10 bt %edx,(%eax) +c010427a: 19 c0 sbb %eax,%eax +c010427c: 89 45 98 mov %eax,-0x68(%ebp) + return oldbit != 0; +c010427f: 83 7d 98 00 cmpl $0x0,-0x68(%ebp) +c0104283: 0f 95 c0 setne %al +c0104286: 0f b6 c0 movzbl %al,%eax +c0104289: 85 c0 test %eax,%eax +c010428b: 74 0b je c0104298 +c010428d: 8b 45 e8 mov -0x18(%ebp),%eax +c0104290: 8b 40 08 mov 0x8(%eax),%eax +c0104293: 83 f8 01 cmp $0x1,%eax +c0104296: 74 24 je c01042bc +c0104298: c7 44 24 0c 0c 99 10 movl $0xc010990c,0xc(%esp) +c010429f: c0 +c01042a0: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01042a7: c0 +c01042a8: c7 44 24 04 5e 01 00 movl $0x15e,0x4(%esp) +c01042af: 00 +c01042b0: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01042b7: e8 86 c9 ff ff call c0100c42 <__panic> + assert(PageProperty(p1) && p1->property == 3);// 检查 p1 属性 +c01042bc: 8b 45 e0 mov -0x20(%ebp),%eax +c01042bf: 83 c0 04 add $0x4,%eax +c01042c2: c7 45 94 01 00 00 00 movl $0x1,-0x6c(%ebp) +c01042c9: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01042cc: 8b 45 90 mov -0x70(%ebp),%eax +c01042cf: 8b 55 94 mov -0x6c(%ebp),%edx +c01042d2: 0f a3 10 bt %edx,(%eax) +c01042d5: 19 c0 sbb %eax,%eax +c01042d7: 89 45 8c mov %eax,-0x74(%ebp) + return oldbit != 0; +c01042da: 83 7d 8c 00 cmpl $0x0,-0x74(%ebp) +c01042de: 0f 95 c0 setne %al +c01042e1: 0f b6 c0 movzbl %al,%eax +c01042e4: 85 c0 test %eax,%eax +c01042e6: 74 0b je c01042f3 +c01042e8: 8b 45 e0 mov -0x20(%ebp),%eax +c01042eb: 8b 40 08 mov 0x8(%eax),%eax +c01042ee: 83 f8 03 cmp $0x3,%eax +c01042f1: 74 24 je c0104317 +c01042f3: c7 44 24 0c 34 99 10 movl $0xc0109934,0xc(%esp) +c01042fa: c0 +c01042fb: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104302: c0 +c0104303: c7 44 24 04 5f 01 00 movl $0x15f,0x4(%esp) +c010430a: 00 +c010430b: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104312: e8 2b c9 ff ff call c0100c42 <__panic> + // 确保重分配的页面是之前释放的页面 + assert((p0 = alloc_page()) == p2 - 1); +c0104317: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010431e: e8 84 05 00 00 call c01048a7 +c0104323: 89 45 e8 mov %eax,-0x18(%ebp) +c0104326: 8b 45 dc mov -0x24(%ebp),%eax +c0104329: 83 e8 20 sub $0x20,%eax +c010432c: 39 45 e8 cmp %eax,-0x18(%ebp) +c010432f: 74 24 je c0104355 +c0104331: c7 44 24 0c 5a 99 10 movl $0xc010995a,0xc(%esp) +c0104338: c0 +c0104339: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104340: c0 +c0104341: c7 44 24 04 61 01 00 movl $0x161,0x4(%esp) +c0104348: 00 +c0104349: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104350: e8 ed c8 ff ff call c0100c42 <__panic> + free_page(p0);// 释放分配的页面 +c0104355: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010435c: 00 +c010435d: 8b 45 e8 mov -0x18(%ebp),%eax +c0104360: 89 04 24 mov %eax,(%esp) +c0104363: e8 ac 05 00 00 call c0104914 + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 +c0104368: c7 04 24 02 00 00 00 movl $0x2,(%esp) +c010436f: e8 33 05 00 00 call c01048a7 +c0104374: 89 45 e8 mov %eax,-0x18(%ebp) +c0104377: 8b 45 dc mov -0x24(%ebp),%eax +c010437a: 83 c0 20 add $0x20,%eax +c010437d: 39 45 e8 cmp %eax,-0x18(%ebp) +c0104380: 74 24 je c01043a6 +c0104382: c7 44 24 0c 78 99 10 movl $0xc0109978,0xc(%esp) +c0104389: c0 +c010438a: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104391: c0 +c0104392: c7 44 24 04 63 01 00 movl $0x163,0x4(%esp) +c0104399: 00 +c010439a: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01043a1: e8 9c c8 ff ff call c0100c42 <__panic> + // 释放页面并检查空闲状态 + free_pages(p0, 2); +c01043a6: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) +c01043ad: 00 +c01043ae: 8b 45 e8 mov -0x18(%ebp),%eax +c01043b1: 89 04 24 mov %eax,(%esp) +c01043b4: e8 5b 05 00 00 call c0104914 + free_page(p2); +c01043b9: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01043c0: 00 +c01043c1: 8b 45 dc mov -0x24(%ebp),%eax +c01043c4: 89 04 24 mov %eax,(%esp) +c01043c7: e8 48 05 00 00 call c0104914 + // 再次分配 5 个页面 + assert((p0 = alloc_pages(5)) != NULL); +c01043cc: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c01043d3: e8 cf 04 00 00 call c01048a7 +c01043d8: 89 45 e8 mov %eax,-0x18(%ebp) +c01043db: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01043df: 75 24 jne c0104405 +c01043e1: c7 44 24 0c 98 99 10 movl $0xc0109998,0xc(%esp) +c01043e8: c0 +c01043e9: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01043f0: c0 +c01043f1: c7 44 24 04 68 01 00 movl $0x168,0x4(%esp) +c01043f8: 00 +c01043f9: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104400: e8 3d c8 ff ff call c0100c42 <__panic> + assert(alloc_page() == NULL);// 确保没有额外页面可分配 +c0104405: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010440c: e8 96 04 00 00 call c01048a7 +c0104411: 85 c0 test %eax,%eax +c0104413: 74 24 je c0104439 +c0104415: c7 44 24 0c f6 97 10 movl $0xc01097f6,0xc(%esp) +c010441c: c0 +c010441d: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104424: c0 +c0104425: c7 44 24 04 69 01 00 movl $0x169,0x4(%esp) +c010442c: 00 +c010442d: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104434: e8 09 c8 ff ff call c0100c42 <__panic> + + assert(nr_free == 0);// 确保空闲页数为 0 +c0104439: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c010443e: 85 c0 test %eax,%eax +c0104440: 74 24 je c0104466 +c0104442: c7 44 24 0c 49 98 10 movl $0xc0109849,0xc(%esp) +c0104449: c0 +c010444a: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c0104451: c0 +c0104452: c7 44 24 04 6b 01 00 movl $0x16b,0x4(%esp) +c0104459: 00 +c010445a: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c0104461: e8 dc c7 ff ff call c0100c42 <__panic> + nr_free = nr_free_store;// 恢复空闲页数 +c0104466: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104469: a3 ec 5f 12 c0 mov %eax,0xc0125fec + // 恢复空闲列表状态 + free_list = free_list_store; +c010446e: 8b 45 80 mov -0x80(%ebp),%eax +c0104471: 8b 55 84 mov -0x7c(%ebp),%edx +c0104474: a3 e4 5f 12 c0 mov %eax,0xc0125fe4 +c0104479: 89 15 e8 5f 12 c0 mov %edx,0xc0125fe8 + free_pages(p0, 5);// 释放所有分配的页面 +c010447f: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp) +c0104486: 00 +c0104487: 8b 45 e8 mov -0x18(%ebp),%eax +c010448a: 89 04 24 mov %eax,(%esp) +c010448d: e8 82 04 00 00 call c0104914 + // 验证空闲列表的一致性 + le = &free_list; +c0104492: c7 45 ec e4 5f 12 c0 movl $0xc0125fe4,-0x14(%ebp) + while ((le = list_next(le)) != &free_list) { +c0104499: eb 1c jmp c01044b7 + struct Page *p = le2page(le, page_link); +c010449b: 8b 45 ec mov -0x14(%ebp),%eax +c010449e: 83 e8 0c sub $0xc,%eax +c01044a1: 89 45 d8 mov %eax,-0x28(%ebp) + count --, total -= p->property; +c01044a4: ff 4d f4 decl -0xc(%ebp) +c01044a7: 8b 55 f0 mov -0x10(%ebp),%edx +c01044aa: 8b 45 d8 mov -0x28(%ebp),%eax +c01044ad: 8b 48 08 mov 0x8(%eax),%ecx +c01044b0: 89 d0 mov %edx,%eax +c01044b2: 29 c8 sub %ecx,%eax +c01044b4: 89 45 f0 mov %eax,-0x10(%ebp) +c01044b7: 8b 45 ec mov -0x14(%ebp),%eax +c01044ba: 89 45 88 mov %eax,-0x78(%ebp) + return listelm->next; +c01044bd: 8b 45 88 mov -0x78(%ebp),%eax +c01044c0: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c01044c3: 89 45 ec mov %eax,-0x14(%ebp) +c01044c6: 81 7d ec e4 5f 12 c0 cmpl $0xc0125fe4,-0x14(%ebp) +c01044cd: 75 cc jne c010449b + } + assert(count == 0);// 确保所有页面都已处理 +c01044cf: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01044d3: 74 24 je c01044f9 +c01044d5: c7 44 24 0c b6 99 10 movl $0xc01099b6,0xc(%esp) +c01044dc: c0 +c01044dd: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c01044e4: c0 +c01044e5: c7 44 24 04 76 01 00 movl $0x176,0x4(%esp) +c01044ec: 00 +c01044ed: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c01044f4: e8 49 c7 ff ff call c0100c42 <__panic> + assert(total == 0);// 确保总属性值为 0 +c01044f9: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01044fd: 74 24 je c0104523 +c01044ff: c7 44 24 0c c1 99 10 movl $0xc01099c1,0xc(%esp) +c0104506: c0 +c0104507: c7 44 24 08 56 96 10 movl $0xc0109656,0x8(%esp) +c010450e: c0 +c010450f: c7 44 24 04 77 01 00 movl $0x177,0x4(%esp) +c0104516: 00 +c0104517: c7 04 24 6b 96 10 c0 movl $0xc010966b,(%esp) +c010451e: e8 1f c7 ff ff call c0100c42 <__panic> +} +c0104523: 90 nop +c0104524: 89 ec mov %ebp,%esp +c0104526: 5d pop %ebp +c0104527: c3 ret + +c0104528 : +page2ppn(struct Page *page) { +c0104528: 55 push %ebp +c0104529: 89 e5 mov %esp,%ebp + return page - pages; +c010452b: 8b 15 00 60 12 c0 mov 0xc0126000,%edx +c0104531: 8b 45 08 mov 0x8(%ebp),%eax +c0104534: 29 d0 sub %edx,%eax +c0104536: c1 f8 05 sar $0x5,%eax +} +c0104539: 5d pop %ebp +c010453a: c3 ret + +c010453b : +page2pa(struct Page *page) { +c010453b: 55 push %ebp +c010453c: 89 e5 mov %esp,%ebp +c010453e: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0104541: 8b 45 08 mov 0x8(%ebp),%eax +c0104544: 89 04 24 mov %eax,(%esp) +c0104547: e8 dc ff ff ff call c0104528 +c010454c: c1 e0 0c shl $0xc,%eax +} +c010454f: 89 ec mov %ebp,%esp +c0104551: 5d pop %ebp +c0104552: c3 ret + +c0104553 : +pa2page(uintptr_t pa) { +c0104553: 55 push %ebp +c0104554: 89 e5 mov %esp,%ebp +c0104556: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0104559: 8b 45 08 mov 0x8(%ebp),%eax +c010455c: c1 e8 0c shr $0xc,%eax +c010455f: 89 c2 mov %eax,%edx +c0104561: a1 04 60 12 c0 mov 0xc0126004,%eax +c0104566: 39 c2 cmp %eax,%edx +c0104568: 72 1c jb c0104586 + panic("pa2page called with invalid pa"); +c010456a: c7 44 24 08 fc 99 10 movl $0xc01099fc,0x8(%esp) +c0104571: c0 +c0104572: c7 44 24 04 5b 00 00 movl $0x5b,0x4(%esp) +c0104579: 00 +c010457a: c7 04 24 1b 9a 10 c0 movl $0xc0109a1b,(%esp) +c0104581: e8 bc c6 ff ff call c0100c42 <__panic> + return &pages[PPN(pa)]; +c0104586: 8b 15 00 60 12 c0 mov 0xc0126000,%edx +c010458c: 8b 45 08 mov 0x8(%ebp),%eax +c010458f: c1 e8 0c shr $0xc,%eax +c0104592: c1 e0 05 shl $0x5,%eax +c0104595: 01 d0 add %edx,%eax +} +c0104597: 89 ec mov %ebp,%esp +c0104599: 5d pop %ebp +c010459a: c3 ret + +c010459b : +page2kva(struct Page *page) { +c010459b: 55 push %ebp +c010459c: 89 e5 mov %esp,%ebp +c010459e: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c01045a1: 8b 45 08 mov 0x8(%ebp),%eax +c01045a4: 89 04 24 mov %eax,(%esp) +c01045a7: e8 8f ff ff ff call c010453b +c01045ac: 89 45 f4 mov %eax,-0xc(%ebp) +c01045af: 8b 45 f4 mov -0xc(%ebp),%eax +c01045b2: c1 e8 0c shr $0xc,%eax +c01045b5: 89 45 f0 mov %eax,-0x10(%ebp) +c01045b8: a1 04 60 12 c0 mov 0xc0126004,%eax +c01045bd: 39 45 f0 cmp %eax,-0x10(%ebp) +c01045c0: 72 23 jb c01045e5 +c01045c2: 8b 45 f4 mov -0xc(%ebp),%eax +c01045c5: 89 44 24 0c mov %eax,0xc(%esp) +c01045c9: c7 44 24 08 2c 9a 10 movl $0xc0109a2c,0x8(%esp) +c01045d0: c0 +c01045d1: c7 44 24 04 62 00 00 movl $0x62,0x4(%esp) +c01045d8: 00 +c01045d9: c7 04 24 1b 9a 10 c0 movl $0xc0109a1b,(%esp) +c01045e0: e8 5d c6 ff ff call c0100c42 <__panic> +c01045e5: 8b 45 f4 mov -0xc(%ebp),%eax +c01045e8: 2d 00 00 00 40 sub $0x40000000,%eax +} +c01045ed: 89 ec mov %ebp,%esp +c01045ef: 5d pop %ebp +c01045f0: c3 ret + +c01045f1 : +kva2page(void *kva) { +c01045f1: 55 push %ebp +c01045f2: 89 e5 mov %esp,%ebp +c01045f4: 83 ec 28 sub $0x28,%esp + return pa2page(PADDR(kva)); +c01045f7: 8b 45 08 mov 0x8(%ebp),%eax +c01045fa: 89 45 f4 mov %eax,-0xc(%ebp) +c01045fd: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0104604: 77 23 ja c0104629 +c0104606: 8b 45 f4 mov -0xc(%ebp),%eax +c0104609: 89 44 24 0c mov %eax,0xc(%esp) +c010460d: c7 44 24 08 50 9a 10 movl $0xc0109a50,0x8(%esp) +c0104614: c0 +c0104615: c7 44 24 04 67 00 00 movl $0x67,0x4(%esp) +c010461c: 00 +c010461d: c7 04 24 1b 9a 10 c0 movl $0xc0109a1b,(%esp) +c0104624: e8 19 c6 ff ff call c0100c42 <__panic> +c0104629: 8b 45 f4 mov -0xc(%ebp),%eax +c010462c: 05 00 00 00 40 add $0x40000000,%eax +c0104631: 89 04 24 mov %eax,(%esp) +c0104634: e8 1a ff ff ff call c0104553 +} +c0104639: 89 ec mov %ebp,%esp +c010463b: 5d pop %ebp +c010463c: c3 ret + +c010463d : +pte2page(pte_t pte) { +c010463d: 55 push %ebp +c010463e: 89 e5 mov %esp,%ebp +c0104640: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { +c0104643: 8b 45 08 mov 0x8(%ebp),%eax +c0104646: 83 e0 01 and $0x1,%eax +c0104649: 85 c0 test %eax,%eax +c010464b: 75 1c jne c0104669 + panic("pte2page called with invalid pte"); +c010464d: c7 44 24 08 74 9a 10 movl $0xc0109a74,0x8(%esp) +c0104654: c0 +c0104655: c7 44 24 04 6d 00 00 movl $0x6d,0x4(%esp) +c010465c: 00 +c010465d: c7 04 24 1b 9a 10 c0 movl $0xc0109a1b,(%esp) +c0104664: e8 d9 c5 ff ff call c0100c42 <__panic> + return pa2page(PTE_ADDR(pte)); +c0104669: 8b 45 08 mov 0x8(%ebp),%eax +c010466c: 25 00 f0 ff ff and $0xfffff000,%eax +c0104671: 89 04 24 mov %eax,(%esp) +c0104674: e8 da fe ff ff call c0104553 +} +c0104679: 89 ec mov %ebp,%esp +c010467b: 5d pop %ebp +c010467c: c3 ret + +c010467d : +pde2page(pde_t pde) { +c010467d: 55 push %ebp +c010467e: 89 e5 mov %esp,%ebp +c0104680: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); +c0104683: 8b 45 08 mov 0x8(%ebp),%eax +c0104686: 25 00 f0 ff ff and $0xfffff000,%eax +c010468b: 89 04 24 mov %eax,(%esp) +c010468e: e8 c0 fe ff ff call c0104553 +} +c0104693: 89 ec mov %ebp,%esp +c0104695: 5d pop %ebp +c0104696: c3 ret + +c0104697 : +page_ref(struct Page *page) { +c0104697: 55 push %ebp +c0104698: 89 e5 mov %esp,%ebp + return page->ref; +c010469a: 8b 45 08 mov 0x8(%ebp),%eax +c010469d: 8b 00 mov (%eax),%eax +} +c010469f: 5d pop %ebp +c01046a0: c3 ret + +c01046a1 : +set_page_ref(struct Page *page, int val) { +c01046a1: 55 push %ebp +c01046a2: 89 e5 mov %esp,%ebp + page->ref = val; +c01046a4: 8b 45 08 mov 0x8(%ebp),%eax +c01046a7: 8b 55 0c mov 0xc(%ebp),%edx +c01046aa: 89 10 mov %edx,(%eax) +} +c01046ac: 90 nop +c01046ad: 5d pop %ebp +c01046ae: c3 ret + +c01046af : + +static inline int +page_ref_inc(struct Page *page) { +c01046af: 55 push %ebp +c01046b0: 89 e5 mov %esp,%ebp + page->ref += 1; +c01046b2: 8b 45 08 mov 0x8(%ebp),%eax +c01046b5: 8b 00 mov (%eax),%eax +c01046b7: 8d 50 01 lea 0x1(%eax),%edx +c01046ba: 8b 45 08 mov 0x8(%ebp),%eax +c01046bd: 89 10 mov %edx,(%eax) + return page->ref; +c01046bf: 8b 45 08 mov 0x8(%ebp),%eax +c01046c2: 8b 00 mov (%eax),%eax +} +c01046c4: 5d pop %ebp +c01046c5: c3 ret + +c01046c6 : + +static inline int +page_ref_dec(struct Page *page) { +c01046c6: 55 push %ebp +c01046c7: 89 e5 mov %esp,%ebp + page->ref -= 1; +c01046c9: 8b 45 08 mov 0x8(%ebp),%eax +c01046cc: 8b 00 mov (%eax),%eax +c01046ce: 8d 50 ff lea -0x1(%eax),%edx +c01046d1: 8b 45 08 mov 0x8(%ebp),%eax +c01046d4: 89 10 mov %edx,(%eax) + return page->ref; +c01046d6: 8b 45 08 mov 0x8(%ebp),%eax +c01046d9: 8b 00 mov (%eax),%eax +} +c01046db: 5d pop %ebp +c01046dc: c3 ret + +c01046dd <__intr_save>: +__intr_save(void) { +c01046dd: 55 push %ebp +c01046de: 89 e5 mov %esp,%ebp +c01046e0: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c01046e3: 9c pushf +c01046e4: 58 pop %eax +c01046e5: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c01046e8: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c01046eb: 25 00 02 00 00 and $0x200,%eax +c01046f0: 85 c0 test %eax,%eax +c01046f2: 74 0c je c0104700 <__intr_save+0x23> + intr_disable(); +c01046f4: e8 ff d7 ff ff call c0101ef8 + return 1; +c01046f9: b8 01 00 00 00 mov $0x1,%eax +c01046fe: eb 05 jmp c0104705 <__intr_save+0x28> + return 0; +c0104700: b8 00 00 00 00 mov $0x0,%eax +} +c0104705: 89 ec mov %ebp,%esp +c0104707: 5d pop %ebp +c0104708: c3 ret + +c0104709 <__intr_restore>: +__intr_restore(bool flag) { +c0104709: 55 push %ebp +c010470a: 89 e5 mov %esp,%ebp +c010470c: 83 ec 08 sub $0x8,%esp + if (flag) { +c010470f: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0104713: 74 05 je c010471a <__intr_restore+0x11> + intr_enable(); +c0104715: e8 d6 d7 ff ff call c0101ef0 +} +c010471a: 90 nop +c010471b: 89 ec mov %ebp,%esp +c010471d: 5d pop %ebp +c010471e: c3 ret + +c010471f : + * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 + * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd +static inline void +lgdt(struct pseudodesc *pd) { +c010471f: 55 push %ebp +c0104720: 89 e5 mov %esp,%ebp + //这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 + asm volatile ("lgdt (%0)" :: "r" (pd)); +c0104722: 8b 45 08 mov 0x8(%ebp),%eax +c0104725: 0f 01 10 lgdtl (%eax) + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 +c0104728: b8 23 00 00 00 mov $0x23,%eax +c010472d: 8e e8 mov %eax,%gs + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 +c010472f: b8 23 00 00 00 mov $0x23,%eax +c0104734: 8e e0 mov %eax,%fs + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 +c0104736: b8 10 00 00 00 mov $0x10,%eax +c010473b: 8e c0 mov %eax,%es + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 +c010473d: b8 10 00 00 00 mov $0x10,%eax +c0104742: 8e d8 mov %eax,%ds + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 +c0104744: b8 10 00 00 00 mov $0x10,%eax +c0104749: 8e d0 mov %eax,%ss + // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 + asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); +c010474b: ea 52 47 10 c0 08 00 ljmp $0x8,$0xc0104752 +} +c0104752: 90 nop +c0104753: 5d pop %ebp +c0104754: c3 ret + +c0104755 : + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 + * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 +void +load_esp0(uintptr_t esp0) { +c0104755: 55 push %ebp +c0104756: 89 e5 mov %esp,%ebp + ts.ts_esp0 = esp0; +c0104758: 8b 45 08 mov 0x8(%ebp),%eax +c010475b: a3 24 60 12 c0 mov %eax,0xc0126024 +} +c0104760: 90 nop +c0104761: 5d pop %ebp +c0104762: c3 ret + +c0104763 : + +/* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ +static void +gdt_init(void) { +c0104763: 55 push %ebp +c0104764: 89 e5 mov %esp,%ebp +c0104766: 83 ec 14 sub $0x14,%esp + // 设置启动内核栈和默认的 SS0 + // set boot kernel stack and default SS0 + load_esp0((uintptr_t)bootstacktop); +c0104769: b8 00 20 12 c0 mov $0xc0122000,%eax +c010476e: 89 04 24 mov %eax,(%esp) +c0104771: e8 df ff ff ff call c0104755 + ts.ts_ss0 = KERNEL_DS; +c0104776: 66 c7 05 28 60 12 c0 movw $0x10,0xc0126028 +c010477d: 10 00 + // 初始化 GDT 中的 TSS 字段 + // initialize the TSS filed of the gdt + gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); +c010477f: 66 c7 05 28 2a 12 c0 movw $0x68,0xc0122a28 +c0104786: 68 00 +c0104788: b8 20 60 12 c0 mov $0xc0126020,%eax +c010478d: 0f b7 c0 movzwl %ax,%eax +c0104790: 66 a3 2a 2a 12 c0 mov %ax,0xc0122a2a +c0104796: b8 20 60 12 c0 mov $0xc0126020,%eax +c010479b: c1 e8 10 shr $0x10,%eax +c010479e: a2 2c 2a 12 c0 mov %al,0xc0122a2c +c01047a3: 0f b6 05 2d 2a 12 c0 movzbl 0xc0122a2d,%eax +c01047aa: 24 f0 and $0xf0,%al +c01047ac: 0c 09 or $0x9,%al +c01047ae: a2 2d 2a 12 c0 mov %al,0xc0122a2d +c01047b3: 0f b6 05 2d 2a 12 c0 movzbl 0xc0122a2d,%eax +c01047ba: 24 ef and $0xef,%al +c01047bc: a2 2d 2a 12 c0 mov %al,0xc0122a2d +c01047c1: 0f b6 05 2d 2a 12 c0 movzbl 0xc0122a2d,%eax +c01047c8: 24 9f and $0x9f,%al +c01047ca: a2 2d 2a 12 c0 mov %al,0xc0122a2d +c01047cf: 0f b6 05 2d 2a 12 c0 movzbl 0xc0122a2d,%eax +c01047d6: 0c 80 or $0x80,%al +c01047d8: a2 2d 2a 12 c0 mov %al,0xc0122a2d +c01047dd: 0f b6 05 2e 2a 12 c0 movzbl 0xc0122a2e,%eax +c01047e4: 24 f0 and $0xf0,%al +c01047e6: a2 2e 2a 12 c0 mov %al,0xc0122a2e +c01047eb: 0f b6 05 2e 2a 12 c0 movzbl 0xc0122a2e,%eax +c01047f2: 24 ef and $0xef,%al +c01047f4: a2 2e 2a 12 c0 mov %al,0xc0122a2e +c01047f9: 0f b6 05 2e 2a 12 c0 movzbl 0xc0122a2e,%eax +c0104800: 24 df and $0xdf,%al +c0104802: a2 2e 2a 12 c0 mov %al,0xc0122a2e +c0104807: 0f b6 05 2e 2a 12 c0 movzbl 0xc0122a2e,%eax +c010480e: 0c 40 or $0x40,%al +c0104810: a2 2e 2a 12 c0 mov %al,0xc0122a2e +c0104815: 0f b6 05 2e 2a 12 c0 movzbl 0xc0122a2e,%eax +c010481c: 24 7f and $0x7f,%al +c010481e: a2 2e 2a 12 c0 mov %al,0xc0122a2e +c0104823: b8 20 60 12 c0 mov $0xc0126020,%eax +c0104828: c1 e8 18 shr $0x18,%eax +c010482b: a2 2f 2a 12 c0 mov %al,0xc0122a2f + // 使用lgdt加载全局描述符表,更新所有段寄存器 + // reload all segment registers + lgdt(&gdt_pd); +c0104830: c7 04 24 30 2a 12 c0 movl $0xc0122a30,(%esp) +c0104837: e8 e3 fe ff ff call c010471f +c010483c: 66 c7 45 fe 28 00 movw $0x28,-0x2(%ebp) + asm volatile ("ltr %0" :: "r" (sel) : "memory"); +c0104842: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0104846: 0f 00 d8 ltr %ax +} +c0104849: 90 nop + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 + // load the TSS + ltr(GD_TSS); +} +c010484a: 90 nop +c010484b: 89 ec mov %ebp,%esp +c010484d: 5d pop %ebp +c010484e: c3 ret + +c010484f : + +//init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 +static void +init_pmm_manager(void) { +c010484f: 55 push %ebp +c0104850: 89 e5 mov %esp,%ebp +c0104852: 83 ec 18 sub $0x18,%esp + //将 pmm_manager 指向默认的 PMM 管理器实例。 + pmm_manager = &default_pmm_manager; +c0104855: c7 05 0c 60 12 c0 e0 movl $0xc01099e0,0xc012600c +c010485c: 99 10 c0 + //使用 cprintf 打印当前内存管理器的名称。 + cprintf("memory management: %s\n", pmm_manager->name); +c010485f: a1 0c 60 12 c0 mov 0xc012600c,%eax +c0104864: 8b 00 mov (%eax),%eax +c0104866: 89 44 24 04 mov %eax,0x4(%esp) +c010486a: c7 04 24 a0 9a 10 c0 movl $0xc0109aa0,(%esp) +c0104871: e8 ff ba ff ff call c0100375 + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 + pmm_manager->init(); +c0104876: a1 0c 60 12 c0 mov 0xc012600c,%eax +c010487b: 8b 40 04 mov 0x4(%eax),%eax +c010487e: ff d0 call *%eax +} +c0104880: 90 nop +c0104881: 89 ec mov %ebp,%esp +c0104883: 5d pop %ebp +c0104884: c3 ret + +c0104885 : + +//init_memmap - call pmm->init_memmap to build Page struct for free memory +// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构 +//struct Page *base:指向内存页的基础地址。 size_t n:要初始化的页数。 +static void +init_memmap(struct Page *base, size_t n) { +c0104885: 55 push %ebp +c0104886: 89 e5 mov %esp,%ebp +c0104888: 83 ec 18 sub $0x18,%esp + pmm_manager->init_memmap(base, n); +c010488b: a1 0c 60 12 c0 mov 0xc012600c,%eax +c0104890: 8b 40 08 mov 0x8(%eax),%eax +c0104893: 8b 55 0c mov 0xc(%ebp),%edx +c0104896: 89 54 24 04 mov %edx,0x4(%esp) +c010489a: 8b 55 08 mov 0x8(%ebp),%edx +c010489d: 89 14 24 mov %edx,(%esp) +c01048a0: ff d0 call *%eax +} +c01048a2: 90 nop +c01048a3: 89 ec mov %ebp,%esp +c01048a5: 5d pop %ebp +c01048a6: c3 ret + +c01048a7 : + +//alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory +// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存 +struct Page * +alloc_pages(size_t n) { +c01048a7: 55 push %ebp +c01048a8: 89 e5 mov %esp,%ebp +c01048aa: 83 ec 28 sub $0x28,%esp + struct Page *page=NULL; +c01048ad: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 + while (1) + { + local_intr_save(intr_flag); +c01048b4: e8 24 fe ff ff call c01046dd <__intr_save> +c01048b9: 89 45 f0 mov %eax,-0x10(%ebp) + { + page = pmm_manager->alloc_pages(n);//尝试分配 n 个页面。 +c01048bc: a1 0c 60 12 c0 mov 0xc012600c,%eax +c01048c1: 8b 40 0c mov 0xc(%eax),%eax +c01048c4: 8b 55 08 mov 0x8(%ebp),%edx +c01048c7: 89 14 24 mov %edx,(%esp) +c01048ca: ff d0 call *%eax +c01048cc: 89 45 f4 mov %eax,-0xc(%ebp) + } + local_intr_restore(intr_flag); +c01048cf: 8b 45 f0 mov -0x10(%ebp),%eax +c01048d2: 89 04 24 mov %eax,(%esp) +c01048d5: e8 2f fe ff ff call c0104709 <__intr_restore> + + if (page != NULL || n > 1 || swap_init_ok == 0) break; +c01048da: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01048de: 75 2d jne c010490d +c01048e0: 83 7d 08 01 cmpl $0x1,0x8(%ebp) +c01048e4: 77 27 ja c010490d +c01048e6: a1 a4 60 12 c0 mov 0xc01260a4,%eax +c01048eb: 85 c0 test %eax,%eax +c01048ed: 74 1e je c010490d + + extern struct mm_struct *check_mm_struct; + //cprintf("page %x, call swap_out in alloc_pages %d\n",page, n); + swap_out(check_mm_struct, n, 0); +c01048ef: 8b 55 08 mov 0x8(%ebp),%edx +c01048f2: a1 6c 61 12 c0 mov 0xc012616c,%eax +c01048f7: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01048fe: 00 +c01048ff: 89 54 24 04 mov %edx,0x4(%esp) +c0104903: 89 04 24 mov %eax,(%esp) +c0104906: e8 ff 19 00 00 call c010630a + { +c010490b: eb a7 jmp c01048b4 + } + //cprintf("n %d,get page %x, No %d in alloc_pages\n",n,page,(page-pages)); + return page; +c010490d: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0104910: 89 ec mov %ebp,%esp +c0104912: 5d pop %ebp +c0104913: c3 ret + +c0104914 : + +//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory +// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存 +//struct Page *base:指向要释放的内存页的基础地址。size_t n:要释放的页数。 +void +free_pages(struct Page *base, size_t n) { +c0104914: 55 push %ebp +c0104915: 89 e5 mov %esp,%ebp +c0104917: 83 ec 28 sub $0x28,%esp + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 + local_intr_save(intr_flag); +c010491a: e8 be fd ff ff call c01046dd <__intr_save> +c010491f: 89 45 f4 mov %eax,-0xc(%ebp) + { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 + pmm_manager->free_pages(base, n); +c0104922: a1 0c 60 12 c0 mov 0xc012600c,%eax +c0104927: 8b 40 10 mov 0x10(%eax),%eax +c010492a: 8b 55 0c mov 0xc(%ebp),%edx +c010492d: 89 54 24 04 mov %edx,0x4(%esp) +c0104931: 8b 55 08 mov 0x8(%ebp),%edx +c0104934: 89 14 24 mov %edx,(%esp) +c0104937: ff d0 call *%eax + } + local_intr_restore(intr_flag); +c0104939: 8b 45 f4 mov -0xc(%ebp),%eax +c010493c: 89 04 24 mov %eax,(%esp) +c010493f: e8 c5 fd ff ff call c0104709 <__intr_restore> +} +c0104944: 90 nop +c0104945: 89 ec mov %ebp,%esp +c0104947: 5d pop %ebp +c0104948: c3 ret + +c0104949 : + +//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) +//of current free memory +// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE) +size_t +nr_free_pages(void) { +c0104949: 55 push %ebp +c010494a: 89 e5 mov %esp,%ebp +c010494c: 83 ec 28 sub $0x28,%esp + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 +c010494f: e8 89 fd ff ff call c01046dd <__intr_save> +c0104954: 89 45 f4 mov %eax,-0xc(%ebp) + { + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 +c0104957: a1 0c 60 12 c0 mov 0xc012600c,%eax +c010495c: 8b 40 14 mov 0x14(%eax),%eax +c010495f: ff d0 call *%eax +c0104961: 89 45 f0 mov %eax,-0x10(%ebp) + } + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 +c0104964: 8b 45 f4 mov -0xc(%ebp),%eax +c0104967: 89 04 24 mov %eax,(%esp) +c010496a: e8 9a fd ff ff call c0104709 <__intr_restore> + return ret;// 返回空闲内存的大小 +c010496f: 8b 45 f0 mov -0x10(%ebp),%eax +} +c0104972: 89 ec mov %ebp,%esp +c0104974: 5d pop %ebp +c0104975: c3 ret + +c0104976 : + +/* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ +static void +page_init(void) { +c0104976: 55 push %ebp +c0104977: 89 e5 mov %esp,%ebp +c0104979: 57 push %edi +c010497a: 56 push %esi +c010497b: 53 push %ebx +c010497c: 81 ec 9c 00 00 00 sub $0x9c,%esp + // 获取物理内存映射信息,存于特定地址 + struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); +c0104982: c7 45 c4 00 80 00 c0 movl $0xc0008000,-0x3c(%ebp) + uint64_t maxpa = 0;// 初始化最大物理地址为0 +c0104989: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) +c0104990: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + + cprintf("e820map:\n");// 打印“e820map”标题 +c0104997: c7 04 24 b7 9a 10 c0 movl $0xc0109ab7,(%esp) +c010499e: e8 d2 b9 ff ff call c0100375 + int i; + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c01049a3: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c01049aa: e9 0c 01 00 00 jmp c0104abb + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 +c01049af: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01049b2: 8b 55 dc mov -0x24(%ebp),%edx +c01049b5: 89 d0 mov %edx,%eax +c01049b7: c1 e0 02 shl $0x2,%eax +c01049ba: 01 d0 add %edx,%eax +c01049bc: c1 e0 02 shl $0x2,%eax +c01049bf: 01 c8 add %ecx,%eax +c01049c1: 8b 50 08 mov 0x8(%eax),%edx +c01049c4: 8b 40 04 mov 0x4(%eax),%eax +c01049c7: 89 45 a0 mov %eax,-0x60(%ebp) +c01049ca: 89 55 a4 mov %edx,-0x5c(%ebp) +c01049cd: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01049d0: 8b 55 dc mov -0x24(%ebp),%edx +c01049d3: 89 d0 mov %edx,%eax +c01049d5: c1 e0 02 shl $0x2,%eax +c01049d8: 01 d0 add %edx,%eax +c01049da: c1 e0 02 shl $0x2,%eax +c01049dd: 01 c8 add %ecx,%eax +c01049df: 8b 48 0c mov 0xc(%eax),%ecx +c01049e2: 8b 58 10 mov 0x10(%eax),%ebx +c01049e5: 8b 45 a0 mov -0x60(%ebp),%eax +c01049e8: 8b 55 a4 mov -0x5c(%ebp),%edx +c01049eb: 01 c8 add %ecx,%eax +c01049ed: 11 da adc %ebx,%edx +c01049ef: 89 45 98 mov %eax,-0x68(%ebp) +c01049f2: 89 55 9c mov %edx,-0x64(%ebp) + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 +c01049f5: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01049f8: 8b 55 dc mov -0x24(%ebp),%edx +c01049fb: 89 d0 mov %edx,%eax +c01049fd: c1 e0 02 shl $0x2,%eax +c0104a00: 01 d0 add %edx,%eax +c0104a02: c1 e0 02 shl $0x2,%eax +c0104a05: 01 c8 add %ecx,%eax +c0104a07: 83 c0 14 add $0x14,%eax +c0104a0a: 8b 00 mov (%eax),%eax +c0104a0c: 89 85 7c ff ff ff mov %eax,-0x84(%ebp) +c0104a12: 8b 45 98 mov -0x68(%ebp),%eax +c0104a15: 8b 55 9c mov -0x64(%ebp),%edx +c0104a18: 83 c0 ff add $0xffffffff,%eax +c0104a1b: 83 d2 ff adc $0xffffffff,%edx +c0104a1e: 89 c6 mov %eax,%esi +c0104a20: 89 d7 mov %edx,%edi +c0104a22: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0104a25: 8b 55 dc mov -0x24(%ebp),%edx +c0104a28: 89 d0 mov %edx,%eax +c0104a2a: c1 e0 02 shl $0x2,%eax +c0104a2d: 01 d0 add %edx,%eax +c0104a2f: c1 e0 02 shl $0x2,%eax +c0104a32: 01 c8 add %ecx,%eax +c0104a34: 8b 48 0c mov 0xc(%eax),%ecx +c0104a37: 8b 58 10 mov 0x10(%eax),%ebx +c0104a3a: 8b 85 7c ff ff ff mov -0x84(%ebp),%eax +c0104a40: 89 44 24 1c mov %eax,0x1c(%esp) +c0104a44: 89 74 24 14 mov %esi,0x14(%esp) +c0104a48: 89 7c 24 18 mov %edi,0x18(%esp) +c0104a4c: 8b 45 a0 mov -0x60(%ebp),%eax +c0104a4f: 8b 55 a4 mov -0x5c(%ebp),%edx +c0104a52: 89 44 24 0c mov %eax,0xc(%esp) +c0104a56: 89 54 24 10 mov %edx,0x10(%esp) +c0104a5a: 89 4c 24 04 mov %ecx,0x4(%esp) +c0104a5e: 89 5c 24 08 mov %ebx,0x8(%esp) +c0104a62: c7 04 24 c4 9a 10 c0 movl $0xc0109ac4,(%esp) +c0104a69: e8 07 b9 ff ff call c0100375 + memmap->map[i].size, begin, end - 1, memmap->map[i].type); + if (memmap->map[i].type == E820_ARM) {// 检查内存类型是否为可用内存 +c0104a6e: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0104a71: 8b 55 dc mov -0x24(%ebp),%edx +c0104a74: 89 d0 mov %edx,%eax +c0104a76: c1 e0 02 shl $0x2,%eax +c0104a79: 01 d0 add %edx,%eax +c0104a7b: c1 e0 02 shl $0x2,%eax +c0104a7e: 01 c8 add %ecx,%eax +c0104a80: 83 c0 14 add $0x14,%eax +c0104a83: 8b 00 mov (%eax),%eax +c0104a85: 83 f8 01 cmp $0x1,%eax +c0104a88: 75 2e jne c0104ab8 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 +c0104a8a: 8b 45 e0 mov -0x20(%ebp),%eax +c0104a8d: 8b 55 e4 mov -0x1c(%ebp),%edx +c0104a90: 3b 45 98 cmp -0x68(%ebp),%eax +c0104a93: 89 d0 mov %edx,%eax +c0104a95: 1b 45 9c sbb -0x64(%ebp),%eax +c0104a98: 73 1e jae c0104ab8 +c0104a9a: ba ff ff ff 37 mov $0x37ffffff,%edx +c0104a9f: b8 00 00 00 00 mov $0x0,%eax +c0104aa4: 3b 55 a0 cmp -0x60(%ebp),%edx +c0104aa7: 1b 45 a4 sbb -0x5c(%ebp),%eax +c0104aaa: 72 0c jb c0104ab8 + maxpa = end;// 更新最大物理地址 +c0104aac: 8b 45 98 mov -0x68(%ebp),%eax +c0104aaf: 8b 55 9c mov -0x64(%ebp),%edx +c0104ab2: 89 45 e0 mov %eax,-0x20(%ebp) +c0104ab5: 89 55 e4 mov %edx,-0x1c(%ebp) + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c0104ab8: ff 45 dc incl -0x24(%ebp) +c0104abb: 8b 45 c4 mov -0x3c(%ebp),%eax +c0104abe: 8b 00 mov (%eax),%eax +c0104ac0: 39 45 dc cmp %eax,-0x24(%ebp) +c0104ac3: 0f 8c e6 fe ff ff jl c01049af + } + } + } + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 +c0104ac9: ba 00 00 00 38 mov $0x38000000,%edx +c0104ace: b8 00 00 00 00 mov $0x0,%eax +c0104ad3: 3b 55 e0 cmp -0x20(%ebp),%edx +c0104ad6: 1b 45 e4 sbb -0x1c(%ebp),%eax +c0104ad9: 73 0e jae c0104ae9 + maxpa = KMEMSIZE;// 将其限制为内存上限 +c0104adb: c7 45 e0 00 00 00 38 movl $0x38000000,-0x20(%ebp) +c0104ae2: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + } + + extern char end[];// 引入全局变量 end,指向内存的结束位置 + + npage = maxpa / PGSIZE;// 计算可用页数 +c0104ae9: 8b 45 e0 mov -0x20(%ebp),%eax +c0104aec: 8b 55 e4 mov -0x1c(%ebp),%edx +c0104aef: 0f ac d0 0c shrd $0xc,%edx,%eax +c0104af3: c1 ea 0c shr $0xc,%edx +c0104af6: a3 04 60 12 c0 mov %eax,0xc0126004 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 +c0104afb: c7 45 c0 00 10 00 00 movl $0x1000,-0x40(%ebp) +c0104b02: b8 74 61 12 c0 mov $0xc0126174,%eax +c0104b07: 8d 50 ff lea -0x1(%eax),%edx +c0104b0a: 8b 45 c0 mov -0x40(%ebp),%eax +c0104b0d: 01 d0 add %edx,%eax +c0104b0f: 89 45 bc mov %eax,-0x44(%ebp) +c0104b12: 8b 45 bc mov -0x44(%ebp),%eax +c0104b15: ba 00 00 00 00 mov $0x0,%edx +c0104b1a: f7 75 c0 divl -0x40(%ebp) +c0104b1d: 8b 45 bc mov -0x44(%ebp),%eax +c0104b20: 29 d0 sub %edx,%eax +c0104b22: a3 00 60 12 c0 mov %eax,0xc0126000 + + for (i = 0; i < npage; i ++) {// 遍历每一页 +c0104b27: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0104b2e: eb 28 jmp c0104b58 + SetPageReserved(pages + i);// 将每一页标记为保留状态 +c0104b30: 8b 15 00 60 12 c0 mov 0xc0126000,%edx +c0104b36: 8b 45 dc mov -0x24(%ebp),%eax +c0104b39: c1 e0 05 shl $0x5,%eax +c0104b3c: 01 d0 add %edx,%eax +c0104b3e: 83 c0 04 add $0x4,%eax +c0104b41: c7 45 94 00 00 00 00 movl $0x0,-0x6c(%ebp) +c0104b48: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0104b4b: 8b 45 90 mov -0x70(%ebp),%eax +c0104b4e: 8b 55 94 mov -0x6c(%ebp),%edx +c0104b51: 0f ab 10 bts %edx,(%eax) +} +c0104b54: 90 nop + for (i = 0; i < npage; i ++) {// 遍历每一页 +c0104b55: ff 45 dc incl -0x24(%ebp) +c0104b58: 8b 55 dc mov -0x24(%ebp),%edx +c0104b5b: a1 04 60 12 c0 mov 0xc0126004,%eax +c0104b60: 39 c2 cmp %eax,%edx +c0104b62: 72 cc jb c0104b30 + } + + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 +c0104b64: a1 04 60 12 c0 mov 0xc0126004,%eax +c0104b69: c1 e0 05 shl $0x5,%eax +c0104b6c: 89 c2 mov %eax,%edx +c0104b6e: a1 00 60 12 c0 mov 0xc0126000,%eax +c0104b73: 01 d0 add %edx,%eax +c0104b75: 89 45 b8 mov %eax,-0x48(%ebp) +c0104b78: 81 7d b8 ff ff ff bf cmpl $0xbfffffff,-0x48(%ebp) +c0104b7f: 77 23 ja c0104ba4 +c0104b81: 8b 45 b8 mov -0x48(%ebp),%eax +c0104b84: 89 44 24 0c mov %eax,0xc(%esp) +c0104b88: c7 44 24 08 50 9a 10 movl $0xc0109a50,0x8(%esp) +c0104b8f: c0 +c0104b90: c7 44 24 04 18 01 00 movl $0x118,0x4(%esp) +c0104b97: 00 +c0104b98: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0104b9f: e8 9e c0 ff ff call c0100c42 <__panic> +c0104ba4: 8b 45 b8 mov -0x48(%ebp),%eax +c0104ba7: 05 00 00 00 40 add $0x40000000,%eax +c0104bac: 89 45 b4 mov %eax,-0x4c(%ebp) + + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c0104baf: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0104bb6: e9 53 01 00 00 jmp c0104d0e + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 +c0104bbb: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0104bbe: 8b 55 dc mov -0x24(%ebp),%edx +c0104bc1: 89 d0 mov %edx,%eax +c0104bc3: c1 e0 02 shl $0x2,%eax +c0104bc6: 01 d0 add %edx,%eax +c0104bc8: c1 e0 02 shl $0x2,%eax +c0104bcb: 01 c8 add %ecx,%eax +c0104bcd: 8b 50 08 mov 0x8(%eax),%edx +c0104bd0: 8b 40 04 mov 0x4(%eax),%eax +c0104bd3: 89 45 d0 mov %eax,-0x30(%ebp) +c0104bd6: 89 55 d4 mov %edx,-0x2c(%ebp) +c0104bd9: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0104bdc: 8b 55 dc mov -0x24(%ebp),%edx +c0104bdf: 89 d0 mov %edx,%eax +c0104be1: c1 e0 02 shl $0x2,%eax +c0104be4: 01 d0 add %edx,%eax +c0104be6: c1 e0 02 shl $0x2,%eax +c0104be9: 01 c8 add %ecx,%eax +c0104beb: 8b 48 0c mov 0xc(%eax),%ecx +c0104bee: 8b 58 10 mov 0x10(%eax),%ebx +c0104bf1: 8b 45 d0 mov -0x30(%ebp),%eax +c0104bf4: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104bf7: 01 c8 add %ecx,%eax +c0104bf9: 11 da adc %ebx,%edx +c0104bfb: 89 45 c8 mov %eax,-0x38(%ebp) +c0104bfe: 89 55 cc mov %edx,-0x34(%ebp) + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 +c0104c01: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0104c04: 8b 55 dc mov -0x24(%ebp),%edx +c0104c07: 89 d0 mov %edx,%eax +c0104c09: c1 e0 02 shl $0x2,%eax +c0104c0c: 01 d0 add %edx,%eax +c0104c0e: c1 e0 02 shl $0x2,%eax +c0104c11: 01 c8 add %ecx,%eax +c0104c13: 83 c0 14 add $0x14,%eax +c0104c16: 8b 00 mov (%eax),%eax +c0104c18: 83 f8 01 cmp $0x1,%eax +c0104c1b: 0f 85 ea 00 00 00 jne c0104d0b + if (begin < freemem) {// 如果起始地址小于可用内存地址 +c0104c21: 8b 45 b4 mov -0x4c(%ebp),%eax +c0104c24: ba 00 00 00 00 mov $0x0,%edx +c0104c29: 8b 4d d4 mov -0x2c(%ebp),%ecx +c0104c2c: 39 45 d0 cmp %eax,-0x30(%ebp) +c0104c2f: 19 d1 sbb %edx,%ecx +c0104c31: 73 0d jae c0104c40 + begin = freemem;//将起始地址设置为可用内存地址 +c0104c33: 8b 45 b4 mov -0x4c(%ebp),%eax +c0104c36: 89 45 d0 mov %eax,-0x30(%ebp) +c0104c39: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%ebp) + } + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 +c0104c40: ba 00 00 00 38 mov $0x38000000,%edx +c0104c45: b8 00 00 00 00 mov $0x0,%eax +c0104c4a: 3b 55 c8 cmp -0x38(%ebp),%edx +c0104c4d: 1b 45 cc sbb -0x34(%ebp),%eax +c0104c50: 73 0e jae c0104c60 + end = KMEMSIZE;// 将其限制为内存上限 +c0104c52: c7 45 c8 00 00 00 38 movl $0x38000000,-0x38(%ebp) +c0104c59: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%ebp) + } + if (begin < end) {// 如果起始地址小于结束地址 +c0104c60: 8b 45 d0 mov -0x30(%ebp),%eax +c0104c63: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104c66: 3b 45 c8 cmp -0x38(%ebp),%eax +c0104c69: 89 d0 mov %edx,%eax +c0104c6b: 1b 45 cc sbb -0x34(%ebp),%eax +c0104c6e: 0f 83 97 00 00 00 jae c0104d0b + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 +c0104c74: c7 45 b0 00 10 00 00 movl $0x1000,-0x50(%ebp) +c0104c7b: 8b 55 d0 mov -0x30(%ebp),%edx +c0104c7e: 8b 45 b0 mov -0x50(%ebp),%eax +c0104c81: 01 d0 add %edx,%eax +c0104c83: 48 dec %eax +c0104c84: 89 45 ac mov %eax,-0x54(%ebp) +c0104c87: 8b 45 ac mov -0x54(%ebp),%eax +c0104c8a: ba 00 00 00 00 mov $0x0,%edx +c0104c8f: f7 75 b0 divl -0x50(%ebp) +c0104c92: 8b 45 ac mov -0x54(%ebp),%eax +c0104c95: 29 d0 sub %edx,%eax +c0104c97: ba 00 00 00 00 mov $0x0,%edx +c0104c9c: 89 45 d0 mov %eax,-0x30(%ebp) +c0104c9f: 89 55 d4 mov %edx,-0x2c(%ebp) + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 +c0104ca2: 8b 45 c8 mov -0x38(%ebp),%eax +c0104ca5: 89 45 a8 mov %eax,-0x58(%ebp) +c0104ca8: 8b 45 a8 mov -0x58(%ebp),%eax +c0104cab: ba 00 00 00 00 mov $0x0,%edx +c0104cb0: 89 c7 mov %eax,%edi +c0104cb2: 81 e7 00 f0 ff ff and $0xfffff000,%edi +c0104cb8: 89 7d 80 mov %edi,-0x80(%ebp) +c0104cbb: 89 d0 mov %edx,%eax +c0104cbd: 83 e0 00 and $0x0,%eax +c0104cc0: 89 45 84 mov %eax,-0x7c(%ebp) +c0104cc3: 8b 45 80 mov -0x80(%ebp),%eax +c0104cc6: 8b 55 84 mov -0x7c(%ebp),%edx +c0104cc9: 89 45 c8 mov %eax,-0x38(%ebp) +c0104ccc: 89 55 cc mov %edx,-0x34(%ebp) + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 +c0104ccf: 8b 45 d0 mov -0x30(%ebp),%eax +c0104cd2: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104cd5: 3b 45 c8 cmp -0x38(%ebp),%eax +c0104cd8: 89 d0 mov %edx,%eax +c0104cda: 1b 45 cc sbb -0x34(%ebp),%eax +c0104cdd: 73 2c jae c0104d0b + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 +c0104cdf: 8b 45 c8 mov -0x38(%ebp),%eax +c0104ce2: 8b 55 cc mov -0x34(%ebp),%edx +c0104ce5: 2b 45 d0 sub -0x30(%ebp),%eax +c0104ce8: 1b 55 d4 sbb -0x2c(%ebp),%edx +c0104ceb: 0f ac d0 0c shrd $0xc,%edx,%eax +c0104cef: c1 ea 0c shr $0xc,%edx +c0104cf2: 89 c3 mov %eax,%ebx +c0104cf4: 8b 45 d0 mov -0x30(%ebp),%eax +c0104cf7: 89 04 24 mov %eax,(%esp) +c0104cfa: e8 54 f8 ff ff call c0104553 +c0104cff: 89 5c 24 04 mov %ebx,0x4(%esp) +c0104d03: 89 04 24 mov %eax,(%esp) +c0104d06: e8 7a fb ff ff call c0104885 + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c0104d0b: ff 45 dc incl -0x24(%ebp) +c0104d0e: 8b 45 c4 mov -0x3c(%ebp),%eax +c0104d11: 8b 00 mov (%eax),%eax +c0104d13: 39 45 dc cmp %eax,-0x24(%ebp) +c0104d16: 0f 8c 9f fe ff ff jl c0104bbb + } + } + } + } +} +c0104d1c: 90 nop +c0104d1d: 90 nop +c0104d1e: 81 c4 9c 00 00 00 add $0x9c,%esp +c0104d24: 5b pop %ebx +c0104d25: 5e pop %esi +c0104d26: 5f pop %edi +c0104d27: 5d pop %ebp +c0104d28: c3 ret + +c0104d29 : +//la: 需要映射的线性地址(经过 x86 段映射后的地址) +// size: memory size size: 内存大小 +// pa: physical address of this memory pa:该内存的物理地址 +// perm: permission of this memory perm: 该内存的权限 +static void +boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) { +c0104d29: 55 push %ebp +c0104d2a: 89 e5 mov %esp,%ebp +c0104d2c: 83 ec 38 sub $0x38,%esp + // 确保线性地址和物理地址的页偏移相同 + assert(PGOFF(la) == PGOFF(pa)); +c0104d2f: 8b 45 0c mov 0xc(%ebp),%eax +c0104d32: 33 45 14 xor 0x14(%ebp),%eax +c0104d35: 25 ff 0f 00 00 and $0xfff,%eax +c0104d3a: 85 c0 test %eax,%eax +c0104d3c: 74 24 je c0104d62 +c0104d3e: c7 44 24 0c 02 9b 10 movl $0xc0109b02,0xc(%esp) +c0104d45: c0 +c0104d46: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0104d4d: c0 +c0104d4e: c7 44 24 04 39 01 00 movl $0x139,0x4(%esp) +c0104d55: 00 +c0104d56: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0104d5d: e8 e0 be ff ff call c0100c42 <__panic> + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 + size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; +c0104d62: c7 45 f0 00 10 00 00 movl $0x1000,-0x10(%ebp) +c0104d69: 8b 45 0c mov 0xc(%ebp),%eax +c0104d6c: 25 ff 0f 00 00 and $0xfff,%eax +c0104d71: 89 c2 mov %eax,%edx +c0104d73: 8b 45 10 mov 0x10(%ebp),%eax +c0104d76: 01 c2 add %eax,%edx +c0104d78: 8b 45 f0 mov -0x10(%ebp),%eax +c0104d7b: 01 d0 add %edx,%eax +c0104d7d: 48 dec %eax +c0104d7e: 89 45 ec mov %eax,-0x14(%ebp) +c0104d81: 8b 45 ec mov -0x14(%ebp),%eax +c0104d84: ba 00 00 00 00 mov $0x0,%edx +c0104d89: f7 75 f0 divl -0x10(%ebp) +c0104d8c: 8b 45 ec mov -0x14(%ebp),%eax +c0104d8f: 29 d0 sub %edx,%eax +c0104d91: c1 e8 0c shr $0xc,%eax +c0104d94: 89 45 f4 mov %eax,-0xc(%ebp) + // 将线性地址向下对齐到页边界 + la = ROUNDDOWN(la, PGSIZE); +c0104d97: 8b 45 0c mov 0xc(%ebp),%eax +c0104d9a: 89 45 e8 mov %eax,-0x18(%ebp) +c0104d9d: 8b 45 e8 mov -0x18(%ebp),%eax +c0104da0: 25 00 f0 ff ff and $0xfffff000,%eax +c0104da5: 89 45 0c mov %eax,0xc(%ebp) + // 将物理地址向下对齐到页边界 + pa = ROUNDDOWN(pa, PGSIZE); +c0104da8: 8b 45 14 mov 0x14(%ebp),%eax +c0104dab: 89 45 e4 mov %eax,-0x1c(%ebp) +c0104dae: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104db1: 25 00 f0 ff ff and $0xfffff000,%eax +c0104db6: 89 45 14 mov %eax,0x14(%ebp) + // 循环遍历每一页,直到映射的页数为零 + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c0104db9: eb 68 jmp c0104e23 + // 获取当前页的页表项指针,如果不存在则创建新的页表项 + pte_t *ptep = get_pte(pgdir, la, 1); +c0104dbb: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c0104dc2: 00 +c0104dc3: 8b 45 0c mov 0xc(%ebp),%eax +c0104dc6: 89 44 24 04 mov %eax,0x4(%esp) +c0104dca: 8b 45 08 mov 0x8(%ebp),%eax +c0104dcd: 89 04 24 mov %eax,(%esp) +c0104dd0: e8 88 01 00 00 call c0104f5d +c0104dd5: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保页表项指针不为空 + assert(ptep != NULL); +c0104dd8: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c0104ddc: 75 24 jne c0104e02 +c0104dde: c7 44 24 0c 2e 9b 10 movl $0xc0109b2e,0xc(%esp) +c0104de5: c0 +c0104de6: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0104ded: c0 +c0104dee: c7 44 24 04 45 01 00 movl $0x145,0x4(%esp) +c0104df5: 00 +c0104df6: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0104dfd: e8 40 be ff ff call c0100c42 <__panic> + // 设置页表项,包含物理地址、存在位和权限 + *ptep = pa | PTE_P | perm; +c0104e02: 8b 45 14 mov 0x14(%ebp),%eax +c0104e05: 0b 45 18 or 0x18(%ebp),%eax +c0104e08: 83 c8 01 or $0x1,%eax +c0104e0b: 89 c2 mov %eax,%edx +c0104e0d: 8b 45 e0 mov -0x20(%ebp),%eax +c0104e10: 89 10 mov %edx,(%eax) + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c0104e12: ff 4d f4 decl -0xc(%ebp) +c0104e15: 81 45 0c 00 10 00 00 addl $0x1000,0xc(%ebp) +c0104e1c: 81 45 14 00 10 00 00 addl $0x1000,0x14(%ebp) +c0104e23: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104e27: 75 92 jne c0104dbb + } +} +c0104e29: 90 nop +c0104e2a: 90 nop +c0104e2b: 89 ec mov %ebp,%esp +c0104e2d: 5d pop %ebp +c0104e2e: c3 ret + +c0104e2f : +// return value: the kernel virtual address of this allocated page +//note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table) +//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址 +//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存 +static void * +boot_alloc_page(void) { +c0104e2f: 55 push %ebp +c0104e30: 89 e5 mov %esp,%ebp +c0104e32: 83 ec 28 sub $0x28,%esp + struct Page *p = alloc_page();// 调用分配页面的函数 +c0104e35: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0104e3c: e8 66 fa ff ff call c01048a7 +c0104e41: 89 45 f4 mov %eax,-0xc(%ebp) + if (p == NULL) {// 检查分配是否成功 +c0104e44: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104e48: 75 1c jne c0104e66 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 +c0104e4a: c7 44 24 08 3b 9b 10 movl $0xc0109b3b,0x8(%esp) +c0104e51: c0 +c0104e52: c7 44 24 04 54 01 00 movl $0x154,0x4(%esp) +c0104e59: 00 +c0104e5a: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0104e61: e8 dc bd ff ff call c0100c42 <__panic> + } + return page2kva(p);// 返回分配页面的内核虚拟地址 +c0104e66: 8b 45 f4 mov -0xc(%ebp),%eax +c0104e69: 89 04 24 mov %eax,(%esp) +c0104e6c: e8 2a f7 ff ff call c010459b +} +c0104e71: 89 ec mov %ebp,%esp +c0104e73: 5d pop %ebp +c0104e74: c3 ret + +c0104e75 : +//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism +// - check the correctness of pmm & paging mechanism, print PDT&PT +//pmm_init - 设置物理内存管理器,构建页目录表(PDT)和页表(PT),以设置分页机制 +// - 检查物理内存管理器和分页机制的正确性,打印页目录表和页表 +void +pmm_init(void) { +c0104e75: 55 push %ebp +c0104e76: 89 e5 mov %esp,%ebp +c0104e78: 83 ec 38 sub $0x38,%esp + // We've already enabled paging + // 我们已经启用了分页 + boot_cr3 = PADDR(boot_pgdir); +c0104e7b: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0104e80: 89 45 f4 mov %eax,-0xc(%ebp) +c0104e83: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0104e8a: 77 23 ja c0104eaf +c0104e8c: 8b 45 f4 mov -0xc(%ebp),%eax +c0104e8f: 89 44 24 0c mov %eax,0xc(%esp) +c0104e93: c7 44 24 08 50 9a 10 movl $0xc0109a50,0x8(%esp) +c0104e9a: c0 +c0104e9b: c7 44 24 04 61 01 00 movl $0x161,0x4(%esp) +c0104ea2: 00 +c0104ea3: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0104eaa: e8 93 bd ff ff call c0100c42 <__panic> +c0104eaf: 8b 45 f4 mov -0xc(%ebp),%eax +c0104eb2: 05 00 00 00 40 add $0x40000000,%eax +c0104eb7: a3 08 60 12 c0 mov %eax,0xc0126008 + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 +c0104ebc: e8 8e f9 ff ff call c010484f + + // detect physical memory space, reserve already used memory, + // then use pmm->init_memmap to create free page list + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 +c0104ec1: e8 b0 fa ff ff call c0104976 + + //use pmm->check to verify the correctness of the alloc/free function in a pmm + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 +c0104ec6: e8 ba 04 00 00 call c0105385 + + check_pgdir();// 检查页目录的状态 +c0104ecb: e8 d6 04 00 00 call c01053a6 + + // recursively insert boot_pgdir in itself + // to form a virtual page table at virtual address VPT + // 递归地将 boot_pgdir 插入到自身中 + // 在虚拟地址 VPT 处形成虚拟页表 + boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项,映射自身 +c0104ed0: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0104ed5: 89 45 f0 mov %eax,-0x10(%ebp) +c0104ed8: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c0104edf: 77 23 ja c0104f04 +c0104ee1: 8b 45 f0 mov -0x10(%ebp),%eax +c0104ee4: 89 44 24 0c mov %eax,0xc(%esp) +c0104ee8: c7 44 24 08 50 9a 10 movl $0xc0109a50,0x8(%esp) +c0104eef: c0 +c0104ef0: c7 44 24 04 81 01 00 movl $0x181,0x4(%esp) +c0104ef7: 00 +c0104ef8: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0104eff: e8 3e bd ff ff call c0100c42 <__panic> +c0104f04: 8b 45 f0 mov -0x10(%ebp),%eax +c0104f07: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx +c0104f0d: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0104f12: 05 ac 0f 00 00 add $0xfac,%eax +c0104f17: 83 ca 03 or $0x3,%edx +c0104f1a: 89 10 mov %edx,(%eax) + + // map all physical memory to linear memory with base linear addr KERNBASE + // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE + // 将所有物理内存映射到线性内存,基地址为 KERNBASE + // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE + boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存 +c0104f1c: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0104f21: c7 44 24 10 02 00 00 movl $0x2,0x10(%esp) +c0104f28: 00 +c0104f29: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0104f30: 00 +c0104f31: c7 44 24 08 00 00 00 movl $0x38000000,0x8(%esp) +c0104f38: 38 +c0104f39: c7 44 24 04 00 00 00 movl $0xc0000000,0x4(%esp) +c0104f40: c0 +c0104f41: 89 04 24 mov %eax,(%esp) +c0104f44: e8 e0 fd ff ff call c0104d29 + // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS + // 由于我们正在使用引导加载程序的 GDT, + // 我们应该重新加载 GDT(第二次,也是最后一次),以获取用户段和 TSS + // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G + // 然后在 TSS 中设置内核栈 (ss:esp),在 gdt 中设置 TSS,加载 TSS + gdt_init();// 初始化全局描述符表 +c0104f49: e8 15 f8 ff ff call c0104763 + + //now the basic virtual memory map(see memalyout.h) is established. + //check the correctness of the basic virtual memory map. + // 现在基本的虚拟内存映射(见 memlayout.h)已建立。 + // 检查基础虚拟内存映射的正确性。 + check_boot_pgdir(); // 检查页目录的正确性 +c0104f4e: e8 f1 0a 00 00 call c0105a44 + + print_pgdir(); // 打印页目录表 +c0104f53: e8 6e 0f 00 00 call c0105ec6 + +} +c0104f58: 90 nop +c0104f59: 89 ec mov %ebp,%esp +c0104f5b: 5d pop %ebp +c0104f5c: c3 ret + +c0104f5d : +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 +pte_t * +get_pte(pde_t *pgdir, uintptr_t la, bool create) { +c0104f5d: 55 push %ebp +c0104f5e: 89 e5 mov %esp,%ebp +c0104f60: 83 ec 38 sub $0x38,%esp + // (7) set page directory entry's permission + } + return NULL; // (8) return page table entry +#endif + // (1) 找到页目录项 + pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引 +c0104f63: 8b 45 0c mov 0xc(%ebp),%eax +c0104f66: c1 e8 16 shr $0x16,%eax +c0104f69: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0104f70: 8b 45 08 mov 0x8(%ebp),%eax +c0104f73: 01 d0 add %edx,%eax +c0104f75: 89 45 f4 mov %eax,-0xc(%ebp) + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 +c0104f78: 8b 45 f4 mov -0xc(%ebp),%eax +c0104f7b: 8b 00 mov (%eax),%eax +c0104f7d: 83 e0 01 and $0x1,%eax +c0104f80: 85 c0 test %eax,%eax +c0104f82: 0f 85 af 00 00 00 jne c0105037 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 +c0104f88: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0104f8c: 74 15 je c0104fa3 +c0104f8e: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0104f95: e8 0d f9 ff ff call c01048a7 +c0104f9a: 89 45 f0 mov %eax,-0x10(%ebp) +c0104f9d: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104fa1: 75 0a jne c0104fad + return NULL;// 返回 NULL,表示无法获取页表 +c0104fa3: b8 00 00 00 00 mov $0x0,%eax +c0104fa8: e9 e7 00 00 00 jmp c0105094 + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); +c0104fad: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104fb4: 00 +c0104fb5: 8b 45 f0 mov -0x10(%ebp),%eax +c0104fb8: 89 04 24 mov %eax,(%esp) +c0104fbb: e8 e1 f6 ff ff call c01046a1 + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 +c0104fc0: 8b 45 f0 mov -0x10(%ebp),%eax +c0104fc3: 89 04 24 mov %eax,(%esp) +c0104fc6: e8 70 f5 ff ff call c010453b +c0104fcb: 89 45 ec mov %eax,-0x14(%ebp) + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 +c0104fce: 8b 45 ec mov -0x14(%ebp),%eax +c0104fd1: 89 45 e8 mov %eax,-0x18(%ebp) +c0104fd4: 8b 45 e8 mov -0x18(%ebp),%eax +c0104fd7: c1 e8 0c shr $0xc,%eax +c0104fda: 89 45 e4 mov %eax,-0x1c(%ebp) +c0104fdd: a1 04 60 12 c0 mov 0xc0126004,%eax +c0104fe2: 39 45 e4 cmp %eax,-0x1c(%ebp) +c0104fe5: 72 23 jb c010500a +c0104fe7: 8b 45 e8 mov -0x18(%ebp),%eax +c0104fea: 89 44 24 0c mov %eax,0xc(%esp) +c0104fee: c7 44 24 08 2c 9a 10 movl $0xc0109a2c,0x8(%esp) +c0104ff5: c0 +c0104ff6: c7 44 24 04 da 01 00 movl $0x1da,0x4(%esp) +c0104ffd: 00 +c0104ffe: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105005: e8 38 bc ff ff call c0100c42 <__panic> +c010500a: 8b 45 e8 mov -0x18(%ebp),%eax +c010500d: 2d 00 00 00 40 sub $0x40000000,%eax +c0105012: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0105019: 00 +c010501a: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0105021: 00 +c0105022: 89 04 24 mov %eax,(%esp) +c0105025: e8 a4 3b 00 00 call c0108bce + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 +c010502a: 8b 45 ec mov -0x14(%ebp),%eax +c010502d: 83 c8 07 or $0x7,%eax +c0105030: 89 c2 mov %eax,%edx +c0105032: 8b 45 f4 mov -0xc(%ebp),%eax +c0105035: 89 10 mov %edx,(%eax) + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 +c0105037: 8b 45 f4 mov -0xc(%ebp),%eax +c010503a: 8b 00 mov (%eax),%eax +c010503c: 25 00 f0 ff ff and $0xfffff000,%eax +c0105041: 89 45 e0 mov %eax,-0x20(%ebp) +c0105044: 8b 45 e0 mov -0x20(%ebp),%eax +c0105047: c1 e8 0c shr $0xc,%eax +c010504a: 89 45 dc mov %eax,-0x24(%ebp) +c010504d: a1 04 60 12 c0 mov 0xc0126004,%eax +c0105052: 39 45 dc cmp %eax,-0x24(%ebp) +c0105055: 72 23 jb c010507a +c0105057: 8b 45 e0 mov -0x20(%ebp),%eax +c010505a: 89 44 24 0c mov %eax,0xc(%esp) +c010505e: c7 44 24 08 2c 9a 10 movl $0xc0109a2c,0x8(%esp) +c0105065: c0 +c0105066: c7 44 24 04 df 01 00 movl $0x1df,0x4(%esp) +c010506d: 00 +c010506e: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105075: e8 c8 bb ff ff call c0100c42 <__panic> +c010507a: 8b 45 e0 mov -0x20(%ebp),%eax +c010507d: 2d 00 00 00 40 sub $0x40000000,%eax +c0105082: 89 c2 mov %eax,%edx +c0105084: 8b 45 0c mov 0xc(%ebp),%eax +c0105087: c1 e8 0c shr $0xc,%eax +c010508a: 25 ff 03 00 00 and $0x3ff,%eax +c010508f: c1 e0 02 shl $0x2,%eax +c0105092: 01 d0 add %edx,%eax +} +c0105094: 89 ec mov %ebp,%esp +c0105096: 5d pop %ebp +c0105097: c3 ret + +c0105098 : + +//get_page - get related Page struct for linear address la using PDT pgdir +// get_page - 获取与线性地址 la 相关的 Page 结构体,使用页目录 pgdir +struct Page * +get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) { +c0105098: 55 push %ebp +c0105099: 89 e5 mov %esp,%ebp +c010509b: 83 ec 28 sub $0x28,%esp + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 + pte_t *ptep = get_pte(pgdir, la, 0); +c010509e: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01050a5: 00 +c01050a6: 8b 45 0c mov 0xc(%ebp),%eax +c01050a9: 89 44 24 04 mov %eax,0x4(%esp) +c01050ad: 8b 45 08 mov 0x8(%ebp),%eax +c01050b0: 89 04 24 mov %eax,(%esp) +c01050b3: e8 a5 fe ff ff call c0104f5d +c01050b8: 89 45 f4 mov %eax,-0xc(%ebp) + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 + if (ptep_store != NULL) { +c01050bb: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c01050bf: 74 08 je c01050c9 + *ptep_store = ptep; // 存储当前页表项的指针 +c01050c1: 8b 45 10 mov 0x10(%ebp),%eax +c01050c4: 8b 55 f4 mov -0xc(%ebp),%edx +c01050c7: 89 10 mov %edx,(%eax) + } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 + if (ptep != NULL && *ptep & PTE_P) { +c01050c9: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01050cd: 74 1b je c01050ea +c01050cf: 8b 45 f4 mov -0xc(%ebp),%eax +c01050d2: 8b 00 mov (%eax),%eax +c01050d4: 83 e0 01 and $0x1,%eax +c01050d7: 85 c0 test %eax,%eax +c01050d9: 74 0f je c01050ea + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 +c01050db: 8b 45 f4 mov -0xc(%ebp),%eax +c01050de: 8b 00 mov (%eax),%eax +c01050e0: 89 04 24 mov %eax,(%esp) +c01050e3: e8 55 f5 ff ff call c010463d +c01050e8: eb 05 jmp c01050ef + } + // 如果未找到有效的页,返回 NULL + return NULL; +c01050ea: b8 00 00 00 00 mov $0x0,%eax +} +c01050ef: 89 ec mov %ebp,%esp +c01050f1: 5d pop %ebp +c01050f2: c3 ret + +c01050f3 : + +//page_remove_pte - free an Page sturct which is related linear address la +// - and clean(invalidate) pte which is related linear address la +//note: PT is changed, so the TLB need to be invalidate +static inline void +page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) { +c01050f3: 55 push %ebp +c01050f4: 89 e5 mov %esp,%ebp +c01050f6: 83 ec 28 sub $0x28,%esp + //(4) and free this page when page reference reachs 0 + //(5) clear second page table entry + //(6) flush tlb + } +#endif + if (*ptep & PTE_P) { +c01050f9: 8b 45 10 mov 0x10(%ebp),%eax +c01050fc: 8b 00 mov (%eax),%eax +c01050fe: 83 e0 01 and $0x1,%eax +c0105101: 85 c0 test %eax,%eax +c0105103: 74 4d je c0105152 + struct Page *page = pte2page(*ptep);// 找到对应的物理页 +c0105105: 8b 45 10 mov 0x10(%ebp),%eax +c0105108: 8b 00 mov (%eax),%eax +c010510a: 89 04 24 mov %eax,(%esp) +c010510d: e8 2b f5 ff ff call c010463d +c0105112: 89 45 f4 mov %eax,-0xc(%ebp) + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { +c0105115: 8b 45 f4 mov -0xc(%ebp),%eax +c0105118: 89 04 24 mov %eax,(%esp) +c010511b: e8 a6 f5 ff ff call c01046c6 +c0105120: 85 c0 test %eax,%eax +c0105122: 75 13 jne c0105137 + free_page(page); +c0105124: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010512b: 00 +c010512c: 8b 45 f4 mov -0xc(%ebp),%eax +c010512f: 89 04 24 mov %eax,(%esp) +c0105132: e8 dd f7 ff ff call c0104914 + } + *ptep = 0;// 清除页表项 +c0105137: 8b 45 10 mov 0x10(%ebp),%eax +c010513a: c7 00 00 00 00 00 movl $0x0,(%eax) + tlb_invalidate(pgdir, la);// 刷新 TLB +c0105140: 8b 45 0c mov 0xc(%ebp),%eax +c0105143: 89 44 24 04 mov %eax,0x4(%esp) +c0105147: 8b 45 08 mov 0x8(%ebp),%eax +c010514a: 89 04 24 mov %eax,(%esp) +c010514d: e8 07 01 00 00 call c0105259 + } +} +c0105152: 90 nop +c0105153: 89 ec mov %ebp,%esp +c0105155: 5d pop %ebp +c0105156: c3 ret + +c0105157 : + +//page_remove - free an Page which is related linear address la and has an validated pte +//移除一个虚拟地址对应的页面 +void +page_remove(pde_t *pgdir, uintptr_t la) { +c0105157: 55 push %ebp +c0105158: 89 e5 mov %esp,%ebp +c010515a: 83 ec 28 sub $0x28,%esp + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 0); +c010515d: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0105164: 00 +c0105165: 8b 45 0c mov 0xc(%ebp),%eax +c0105168: 89 44 24 04 mov %eax,0x4(%esp) +c010516c: 8b 45 08 mov 0x8(%ebp),%eax +c010516f: 89 04 24 mov %eax,(%esp) +c0105172: e8 e6 fd ff ff call c0104f5d +c0105177: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 + if (ptep != NULL) { +c010517a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010517e: 74 19 je c0105199 + page_remove_pte(pgdir, la, ptep); +c0105180: 8b 45 f4 mov -0xc(%ebp),%eax +c0105183: 89 44 24 08 mov %eax,0x8(%esp) +c0105187: 8b 45 0c mov 0xc(%ebp),%eax +c010518a: 89 44 24 04 mov %eax,0x4(%esp) +c010518e: 8b 45 08 mov 0x8(%ebp),%eax +c0105191: 89 04 24 mov %eax,(%esp) +c0105194: e8 5a ff ff ff call c01050f3 + } +} +c0105199: 90 nop +c010519a: 89 ec mov %ebp,%esp +c010519c: 5d pop %ebp +c010519d: c3 ret + +c010519e : +// perm: the permission of this Page which is setted in related pte +// return value: always 0 +//note: PT is changed, so the TLB need to be invalidate +//将一个页面插入到页表中。 +int +page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) { +c010519e: 55 push %ebp +c010519f: 89 e5 mov %esp,%ebp +c01051a1: 83 ec 28 sub $0x28,%esp + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 1); +c01051a4: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c01051ab: 00 +c01051ac: 8b 45 10 mov 0x10(%ebp),%eax +c01051af: 89 44 24 04 mov %eax,0x4(%esp) +c01051b3: 8b 45 08 mov 0x8(%ebp),%eax +c01051b6: 89 04 24 mov %eax,(%esp) +c01051b9: e8 9f fd ff ff call c0104f5d +c01051be: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 + if (ptep == NULL) { +c01051c1: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01051c5: 75 0a jne c01051d1 + return -E_NO_MEM; +c01051c7: b8 fc ff ff ff mov $0xfffffffc,%eax +c01051cc: e9 84 00 00 00 jmp c0105255 + } + //调用 page_ref_inc 增加页面的引用计数。 + page_ref_inc(page); +c01051d1: 8b 45 0c mov 0xc(%ebp),%eax +c01051d4: 89 04 24 mov %eax,(%esp) +c01051d7: e8 d3 f4 ff ff call c01046af + //如果页表项已存在且指向当前页面,则减少页面引用计数。 + if (*ptep & PTE_P) { +c01051dc: 8b 45 f4 mov -0xc(%ebp),%eax +c01051df: 8b 00 mov (%eax),%eax +c01051e1: 83 e0 01 and $0x1,%eax +c01051e4: 85 c0 test %eax,%eax +c01051e6: 74 3e je c0105226 + struct Page *p = pte2page(*ptep); +c01051e8: 8b 45 f4 mov -0xc(%ebp),%eax +c01051eb: 8b 00 mov (%eax),%eax +c01051ed: 89 04 24 mov %eax,(%esp) +c01051f0: e8 48 f4 ff ff call c010463d +c01051f5: 89 45 f0 mov %eax,-0x10(%ebp) + if (p == page) { +c01051f8: 8b 45 f0 mov -0x10(%ebp),%eax +c01051fb: 3b 45 0c cmp 0xc(%ebp),%eax +c01051fe: 75 0d jne c010520d + page_ref_dec(page); +c0105200: 8b 45 0c mov 0xc(%ebp),%eax +c0105203: 89 04 24 mov %eax,(%esp) +c0105206: e8 bb f4 ff ff call c01046c6 +c010520b: eb 19 jmp c0105226 + } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 + else { + page_remove_pte(pgdir, la, ptep); +c010520d: 8b 45 f4 mov -0xc(%ebp),%eax +c0105210: 89 44 24 08 mov %eax,0x8(%esp) +c0105214: 8b 45 10 mov 0x10(%ebp),%eax +c0105217: 89 44 24 04 mov %eax,0x4(%esp) +c010521b: 8b 45 08 mov 0x8(%ebp),%eax +c010521e: 89 04 24 mov %eax,(%esp) +c0105221: e8 cd fe ff ff call c01050f3 + } + } + *ptep = page2pa(page) | PTE_P | perm; +c0105226: 8b 45 0c mov 0xc(%ebp),%eax +c0105229: 89 04 24 mov %eax,(%esp) +c010522c: e8 0a f3 ff ff call c010453b +c0105231: 0b 45 14 or 0x14(%ebp),%eax +c0105234: 83 c8 01 or $0x1,%eax +c0105237: 89 c2 mov %eax,%edx +c0105239: 8b 45 f4 mov -0xc(%ebp),%eax +c010523c: 89 10 mov %edx,(%eax) + tlb_invalidate(pgdir, la);//刷新 TLB +c010523e: 8b 45 10 mov 0x10(%ebp),%eax +c0105241: 89 44 24 04 mov %eax,0x4(%esp) +c0105245: 8b 45 08 mov 0x8(%ebp),%eax +c0105248: 89 04 24 mov %eax,(%esp) +c010524b: e8 09 00 00 00 call c0105259 + return 0; +c0105250: b8 00 00 00 00 mov $0x0,%eax +} +c0105255: 89 ec mov %ebp,%esp +c0105257: 5d pop %ebp +c0105258: c3 ret + +c0105259 : + +// invalidate a TLB entry, but only if the page tables being +// edited are the ones currently in use by the processor. +//无效化指定地址的TLB条目 +void +tlb_invalidate(pde_t *pgdir, uintptr_t la) { +c0105259: 55 push %ebp +c010525a: 89 e5 mov %esp,%ebp +c010525c: 83 ec 28 sub $0x28,%esp +} + +static inline uintptr_t +rcr3(void) { + uintptr_t cr3; + asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory"); +c010525f: 0f 20 d8 mov %cr3,%eax +c0105262: 89 45 f0 mov %eax,-0x10(%ebp) + return cr3; +c0105265: 8b 55 f0 mov -0x10(%ebp),%edx + //检查当前页目录地址是否与传入的页目录地址相同。 + if (rcr3() == PADDR(pgdir)) { +c0105268: 8b 45 08 mov 0x8(%ebp),%eax +c010526b: 89 45 f4 mov %eax,-0xc(%ebp) +c010526e: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0105275: 77 23 ja c010529a +c0105277: 8b 45 f4 mov -0xc(%ebp),%eax +c010527a: 89 44 24 0c mov %eax,0xc(%esp) +c010527e: c7 44 24 08 50 9a 10 movl $0xc0109a50,0x8(%esp) +c0105285: c0 +c0105286: c7 44 24 04 53 02 00 movl $0x253,0x4(%esp) +c010528d: 00 +c010528e: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105295: e8 a8 b9 ff ff call c0100c42 <__panic> +c010529a: 8b 45 f4 mov -0xc(%ebp),%eax +c010529d: 05 00 00 00 40 add $0x40000000,%eax +c01052a2: 39 d0 cmp %edx,%eax +c01052a4: 75 0d jne c01052b3 + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 + invlpg((void *)la); +c01052a6: 8b 45 0c mov 0xc(%ebp),%eax +c01052a9: 89 45 ec mov %eax,-0x14(%ebp) +} + +static inline void +invlpg(void *addr) { + asm volatile ("invlpg (%0)" :: "r" (addr) : "memory"); +c01052ac: 8b 45 ec mov -0x14(%ebp),%eax +c01052af: 0f 01 38 invlpg (%eax) +} +c01052b2: 90 nop + } +} +c01052b3: 90 nop +c01052b4: 89 ec mov %ebp,%esp +c01052b6: 5d pop %ebp +c01052b7: c3 ret + +c01052b8 : +// pgdir_alloc_page - call alloc_page & page_insert functions to +// - allocate a page size memory & setup an addr map +// - pa<->la with linear address la and the PDT pgdir +//参数包括页目录指针 pgdir、线性地址 la 和权限 perm。 +struct Page * +pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm) { +c01052b8: 55 push %ebp +c01052b9: 89 e5 mov %esp,%ebp +c01052bb: 83 ec 28 sub $0x28,%esp + struct Page *page = alloc_page();//分配一个新的页面存储在 page 指针中 +c01052be: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01052c5: e8 dd f5 ff ff call c01048a7 +c01052ca: 89 45 f4 mov %eax,-0xc(%ebp) + if (page != NULL) {//检查 page 是否不为 NULL,即分配是否成功。 +c01052cd: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01052d1: 0f 84 a7 00 00 00 je c010537e + if (page_insert(pgdir, page, la, perm) != 0) {//将页面插入到指定的线性地址 la 处。 +c01052d7: 8b 45 10 mov 0x10(%ebp),%eax +c01052da: 89 44 24 0c mov %eax,0xc(%esp) +c01052de: 8b 45 0c mov 0xc(%ebp),%eax +c01052e1: 89 44 24 08 mov %eax,0x8(%esp) +c01052e5: 8b 45 f4 mov -0xc(%ebp),%eax +c01052e8: 89 44 24 04 mov %eax,0x4(%esp) +c01052ec: 8b 45 08 mov 0x8(%ebp),%eax +c01052ef: 89 04 24 mov %eax,(%esp) +c01052f2: e8 a7 fe ff ff call c010519e +c01052f7: 85 c0 test %eax,%eax +c01052f9: 74 1a je c0105315 + free_page(page);//释放分配的页面。 +c01052fb: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0105302: 00 +c0105303: 8b 45 f4 mov -0xc(%ebp),%eax +c0105306: 89 04 24 mov %eax,(%esp) +c0105309: e8 06 f6 ff ff call c0104914 + return NULL;//返回 NULL,表示页面插入失败。 +c010530e: b8 00 00 00 00 mov $0x0,%eax +c0105313: eb 6c jmp c0105381 + } + if (swap_init_ok){//检查交换区是否已初始化成功 +c0105315: a1 a4 60 12 c0 mov 0xc01260a4,%eax +c010531a: 85 c0 test %eax,%eax +c010531c: 74 60 je c010537e + //将页面映射到交换区。 + swap_map_swappable(check_mm_struct, la, page, 0); +c010531e: a1 6c 61 12 c0 mov 0xc012616c,%eax +c0105323: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c010532a: 00 +c010532b: 8b 55 f4 mov -0xc(%ebp),%edx +c010532e: 89 54 24 08 mov %edx,0x8(%esp) +c0105332: 8b 55 0c mov 0xc(%ebp),%edx +c0105335: 89 54 24 04 mov %edx,0x4(%esp) +c0105339: 89 04 24 mov %eax,(%esp) +c010533c: e8 79 0f 00 00 call c01062ba + //设置页面的虚拟地址 pra_vaddr 为 la + page->pra_vaddr=la; +c0105341: 8b 45 f4 mov -0xc(%ebp),%eax +c0105344: 8b 55 0c mov 0xc(%ebp),%edx +c0105347: 89 50 1c mov %edx,0x1c(%eax) + //断言页面的引用计数为1,确保页面没有被其他地方引用。 + assert(page_ref(page) == 1); +c010534a: 8b 45 f4 mov -0xc(%ebp),%eax +c010534d: 89 04 24 mov %eax,(%esp) +c0105350: e8 42 f3 ff ff call c0104697 +c0105355: 83 f8 01 cmp $0x1,%eax +c0105358: 74 24 je c010537e +c010535a: c7 44 24 0c 54 9b 10 movl $0xc0109b54,0xc(%esp) +c0105361: c0 +c0105362: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105369: c0 +c010536a: c7 44 24 04 6b 02 00 movl $0x26b,0x4(%esp) +c0105371: 00 +c0105372: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105379: e8 c4 b8 ff ff call c0100c42 <__panic> + //cprintf("get No. %d page: pra_vaddr %x, pra_link.prev %x, pra_link_next %x in pgdir_alloc_page\n", (page-pages), page->pra_vaddr,page->pra_page_link.prev, page->pra_page_link.next); + } + + } + + return page; +c010537e: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0105381: 89 ec mov %ebp,%esp +c0105383: 5d pop %ebp +c0105384: c3 ret + +c0105385 : + +static void +check_alloc_page(void) { +c0105385: 55 push %ebp +c0105386: 89 e5 mov %esp,%ebp +c0105388: 83 ec 18 sub $0x18,%esp + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 + pmm_manager->check(); +c010538b: a1 0c 60 12 c0 mov 0xc012600c,%eax +c0105390: 8b 40 18 mov 0x18(%eax),%eax +c0105393: ff d0 call *%eax + cprintf("check_alloc_page() succeeded!\n"); +c0105395: c7 04 24 68 9b 10 c0 movl $0xc0109b68,(%esp) +c010539c: e8 d4 af ff ff call c0100375 +} +c01053a1: 90 nop +c01053a2: 89 ec mov %ebp,%esp +c01053a4: 5d pop %ebp +c01053a5: c3 ret + +c01053a6 : + +//用于验证页目录和页表的正确性。 +static void +check_pgdir(void) { +c01053a6: 55 push %ebp +c01053a7: 89 e5 mov %esp,%ebp +c01053a9: 83 ec 38 sub $0x38,%esp + //确保内存页面数量在合理范围内 + assert(npage <= KMEMSIZE / PGSIZE); +c01053ac: a1 04 60 12 c0 mov 0xc0126004,%eax +c01053b1: 3d 00 80 03 00 cmp $0x38000,%eax +c01053b6: 76 24 jbe c01053dc +c01053b8: c7 44 24 0c 87 9b 10 movl $0xc0109b87,0xc(%esp) +c01053bf: c0 +c01053c0: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01053c7: c0 +c01053c8: c7 44 24 04 7f 02 00 movl $0x27f,0x4(%esp) +c01053cf: 00 +c01053d0: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01053d7: e8 66 b8 ff ff call c0100c42 <__panic> + //确保页目录不为空且对齐, + assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); +c01053dc: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c01053e1: 85 c0 test %eax,%eax +c01053e3: 74 0e je c01053f3 +c01053e5: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c01053ea: 25 ff 0f 00 00 and $0xfff,%eax +c01053ef: 85 c0 test %eax,%eax +c01053f1: 74 24 je c0105417 +c01053f3: c7 44 24 0c a4 9b 10 movl $0xc0109ba4,0xc(%esp) +c01053fa: c0 +c01053fb: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105402: c0 +c0105403: c7 44 24 04 81 02 00 movl $0x281,0x4(%esp) +c010540a: 00 +c010540b: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105412: e8 2b b8 ff ff call c0100c42 <__panic> + //确保虚拟地址 0x0 没有映射任何页面 + assert(get_page(boot_pgdir, 0x0, NULL) == NULL); +c0105417: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c010541c: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0105423: 00 +c0105424: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010542b: 00 +c010542c: 89 04 24 mov %eax,(%esp) +c010542f: e8 64 fc ff ff call c0105098 +c0105434: 85 c0 test %eax,%eax +c0105436: 74 24 je c010545c +c0105438: c7 44 24 0c dc 9b 10 movl $0xc0109bdc,0xc(%esp) +c010543f: c0 +c0105440: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105447: c0 +c0105448: c7 44 24 04 83 02 00 movl $0x283,0x4(%esp) +c010544f: 00 +c0105450: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105457: e8 e6 b7 ff ff call c0100c42 <__panic> + + //定义两个页面指针 p1 和 p2 + struct Page *p1, *p2; + //分配一个页面 p1 + p1 = alloc_page(); +c010545c: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0105463: e8 3f f4 ff ff call c01048a7 +c0105468: 89 45 f4 mov %eax,-0xc(%ebp) + //将 p1 插入到虚拟地址 0x0 + assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); +c010546b: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105470: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0105477: 00 +c0105478: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010547f: 00 +c0105480: 8b 55 f4 mov -0xc(%ebp),%edx +c0105483: 89 54 24 04 mov %edx,0x4(%esp) +c0105487: 89 04 24 mov %eax,(%esp) +c010548a: e8 0f fd ff ff call c010519e +c010548f: 85 c0 test %eax,%eax +c0105491: 74 24 je c01054b7 +c0105493: c7 44 24 0c 04 9c 10 movl $0xc0109c04,0xc(%esp) +c010549a: c0 +c010549b: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01054a2: c0 +c01054a3: c7 44 24 04 8a 02 00 movl $0x28a,0x4(%esp) +c01054aa: 00 +c01054ab: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01054b2: e8 8b b7 ff ff call c0100c42 <__panic> + + // 获取虚拟地址 0x0 对应的页表项指针 + pte_t *ptep; + assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); +c01054b7: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c01054bc: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01054c3: 00 +c01054c4: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01054cb: 00 +c01054cc: 89 04 24 mov %eax,(%esp) +c01054cf: e8 89 fa ff ff call c0104f5d +c01054d4: 89 45 f0 mov %eax,-0x10(%ebp) +c01054d7: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01054db: 75 24 jne c0105501 +c01054dd: c7 44 24 0c 30 9c 10 movl $0xc0109c30,0xc(%esp) +c01054e4: c0 +c01054e5: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01054ec: c0 +c01054ed: c7 44 24 04 8e 02 00 movl $0x28e,0x4(%esp) +c01054f4: 00 +c01054f5: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01054fc: e8 41 b7 ff ff call c0100c42 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c0105501: 8b 45 f0 mov -0x10(%ebp),%eax +c0105504: 8b 00 mov (%eax),%eax +c0105506: 89 04 24 mov %eax,(%esp) +c0105509: e8 2f f1 ff ff call c010463d +c010550e: 39 45 f4 cmp %eax,-0xc(%ebp) +c0105511: 74 24 je c0105537 +c0105513: c7 44 24 0c 5d 9c 10 movl $0xc0109c5d,0xc(%esp) +c010551a: c0 +c010551b: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105522: c0 +c0105523: c7 44 24 04 90 02 00 movl $0x290,0x4(%esp) +c010552a: 00 +c010552b: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105532: e8 0b b7 ff ff call c0100c42 <__panic> + // 验证 p1 的引用计数为 1 + assert(page_ref(p1) == 1); +c0105537: 8b 45 f4 mov -0xc(%ebp),%eax +c010553a: 89 04 24 mov %eax,(%esp) +c010553d: e8 55 f1 ff ff call c0104697 +c0105542: 83 f8 01 cmp $0x1,%eax +c0105545: 74 24 je c010556b +c0105547: c7 44 24 0c 73 9c 10 movl $0xc0109c73,0xc(%esp) +c010554e: c0 +c010554f: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105556: c0 +c0105557: c7 44 24 04 92 02 00 movl $0x292,0x4(%esp) +c010555e: 00 +c010555f: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105566: e8 d7 b6 ff ff call c0100c42 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; +c010556b: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105570: 8b 00 mov (%eax),%eax +c0105572: 25 00 f0 ff ff and $0xfffff000,%eax +c0105577: 89 45 ec mov %eax,-0x14(%ebp) +c010557a: 8b 45 ec mov -0x14(%ebp),%eax +c010557d: c1 e8 0c shr $0xc,%eax +c0105580: 89 45 e8 mov %eax,-0x18(%ebp) +c0105583: a1 04 60 12 c0 mov 0xc0126004,%eax +c0105588: 39 45 e8 cmp %eax,-0x18(%ebp) +c010558b: 72 23 jb c01055b0 +c010558d: 8b 45 ec mov -0x14(%ebp),%eax +c0105590: 89 44 24 0c mov %eax,0xc(%esp) +c0105594: c7 44 24 08 2c 9a 10 movl $0xc0109a2c,0x8(%esp) +c010559b: c0 +c010559c: c7 44 24 04 94 02 00 movl $0x294,0x4(%esp) +c01055a3: 00 +c01055a4: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01055ab: e8 92 b6 ff ff call c0100c42 <__panic> +c01055b0: 8b 45 ec mov -0x14(%ebp),%eax +c01055b3: 2d 00 00 00 40 sub $0x40000000,%eax +c01055b8: 83 c0 04 add $0x4,%eax +c01055bb: 89 45 f0 mov %eax,-0x10(%ebp) + assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); +c01055be: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c01055c3: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01055ca: 00 +c01055cb: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c01055d2: 00 +c01055d3: 89 04 24 mov %eax,(%esp) +c01055d6: e8 82 f9 ff ff call c0104f5d +c01055db: 39 45 f0 cmp %eax,-0x10(%ebp) +c01055de: 74 24 je c0105604 +c01055e0: c7 44 24 0c 88 9c 10 movl $0xc0109c88,0xc(%esp) +c01055e7: c0 +c01055e8: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01055ef: c0 +c01055f0: c7 44 24 04 95 02 00 movl $0x295,0x4(%esp) +c01055f7: 00 +c01055f8: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01055ff: e8 3e b6 ff ff call c0100c42 <__panic> + // 分配一个页面 p2 + p2 = alloc_page(); +c0105604: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010560b: e8 97 f2 ff ff call c01048a7 +c0105610: 89 45 e4 mov %eax,-0x1c(%ebp) + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 + assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); +c0105613: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105618: c7 44 24 0c 06 00 00 movl $0x6,0xc(%esp) +c010561f: 00 +c0105620: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0105627: 00 +c0105628: 8b 55 e4 mov -0x1c(%ebp),%edx +c010562b: 89 54 24 04 mov %edx,0x4(%esp) +c010562f: 89 04 24 mov %eax,(%esp) +c0105632: e8 67 fb ff ff call c010519e +c0105637: 85 c0 test %eax,%eax +c0105639: 74 24 je c010565f +c010563b: c7 44 24 0c b0 9c 10 movl $0xc0109cb0,0xc(%esp) +c0105642: c0 +c0105643: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c010564a: c0 +c010564b: c7 44 24 04 99 02 00 movl $0x299,0x4(%esp) +c0105652: 00 +c0105653: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c010565a: e8 e3 b5 ff ff call c0100c42 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c010565f: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105664: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010566b: 00 +c010566c: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0105673: 00 +c0105674: 89 04 24 mov %eax,(%esp) +c0105677: e8 e1 f8 ff ff call c0104f5d +c010567c: 89 45 f0 mov %eax,-0x10(%ebp) +c010567f: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0105683: 75 24 jne c01056a9 +c0105685: c7 44 24 0c e8 9c 10 movl $0xc0109ce8,0xc(%esp) +c010568c: c0 +c010568d: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105694: c0 +c0105695: c7 44 24 04 9b 02 00 movl $0x29b,0x4(%esp) +c010569c: 00 +c010569d: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01056a4: e8 99 b5 ff ff call c0100c42 <__panic> + // 验证页表项设置了用户权限 + assert(*ptep & PTE_U); +c01056a9: 8b 45 f0 mov -0x10(%ebp),%eax +c01056ac: 8b 00 mov (%eax),%eax +c01056ae: 83 e0 04 and $0x4,%eax +c01056b1: 85 c0 test %eax,%eax +c01056b3: 75 24 jne c01056d9 +c01056b5: c7 44 24 0c 18 9d 10 movl $0xc0109d18,0xc(%esp) +c01056bc: c0 +c01056bd: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01056c4: c0 +c01056c5: c7 44 24 04 9d 02 00 movl $0x29d,0x4(%esp) +c01056cc: 00 +c01056cd: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01056d4: e8 69 b5 ff ff call c0100c42 <__panic> + // 验证页表项设置了写权限 + assert(*ptep & PTE_W); +c01056d9: 8b 45 f0 mov -0x10(%ebp),%eax +c01056dc: 8b 00 mov (%eax),%eax +c01056de: 83 e0 02 and $0x2,%eax +c01056e1: 85 c0 test %eax,%eax +c01056e3: 75 24 jne c0105709 +c01056e5: c7 44 24 0c 26 9d 10 movl $0xc0109d26,0xc(%esp) +c01056ec: c0 +c01056ed: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01056f4: c0 +c01056f5: c7 44 24 04 9f 02 00 movl $0x29f,0x4(%esp) +c01056fc: 00 +c01056fd: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105704: e8 39 b5 ff ff call c0100c42 <__panic> + // 验证页目录项设置了用户权限 + assert(boot_pgdir[0] & PTE_U); +c0105709: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c010570e: 8b 00 mov (%eax),%eax +c0105710: 83 e0 04 and $0x4,%eax +c0105713: 85 c0 test %eax,%eax +c0105715: 75 24 jne c010573b +c0105717: c7 44 24 0c 34 9d 10 movl $0xc0109d34,0xc(%esp) +c010571e: c0 +c010571f: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105726: c0 +c0105727: c7 44 24 04 a1 02 00 movl $0x2a1,0x4(%esp) +c010572e: 00 +c010572f: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105736: e8 07 b5 ff ff call c0100c42 <__panic> + // 验证 p2 的引用计数为 1 + assert(page_ref(p2) == 1); +c010573b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010573e: 89 04 24 mov %eax,(%esp) +c0105741: e8 51 ef ff ff call c0104697 +c0105746: 83 f8 01 cmp $0x1,%eax +c0105749: 74 24 je c010576f +c010574b: c7 44 24 0c 4a 9d 10 movl $0xc0109d4a,0xc(%esp) +c0105752: c0 +c0105753: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c010575a: c0 +c010575b: c7 44 24 04 a3 02 00 movl $0x2a3,0x4(%esp) +c0105762: 00 +c0105763: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c010576a: e8 d3 b4 ff ff call c0100c42 <__panic> + + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 + assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); +c010576f: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105774: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c010577b: 00 +c010577c: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0105783: 00 +c0105784: 8b 55 f4 mov -0xc(%ebp),%edx +c0105787: 89 54 24 04 mov %edx,0x4(%esp) +c010578b: 89 04 24 mov %eax,(%esp) +c010578e: e8 0b fa ff ff call c010519e +c0105793: 85 c0 test %eax,%eax +c0105795: 74 24 je c01057bb +c0105797: c7 44 24 0c 5c 9d 10 movl $0xc0109d5c,0xc(%esp) +c010579e: c0 +c010579f: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01057a6: c0 +c01057a7: c7 44 24 04 a6 02 00 movl $0x2a6,0x4(%esp) +c01057ae: 00 +c01057af: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01057b6: e8 87 b4 ff ff call c0100c42 <__panic> + // 验证 p1 的引用计数增加到 2 + assert(page_ref(p1) == 2); +c01057bb: 8b 45 f4 mov -0xc(%ebp),%eax +c01057be: 89 04 24 mov %eax,(%esp) +c01057c1: e8 d1 ee ff ff call c0104697 +c01057c6: 83 f8 02 cmp $0x2,%eax +c01057c9: 74 24 je c01057ef +c01057cb: c7 44 24 0c 88 9d 10 movl $0xc0109d88,0xc(%esp) +c01057d2: c0 +c01057d3: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01057da: c0 +c01057db: c7 44 24 04 a8 02 00 movl $0x2a8,0x4(%esp) +c01057e2: 00 +c01057e3: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01057ea: e8 53 b4 ff ff call c0100c42 <__panic> + // 验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c01057ef: 8b 45 e4 mov -0x1c(%ebp),%eax +c01057f2: 89 04 24 mov %eax,(%esp) +c01057f5: e8 9d ee ff ff call c0104697 +c01057fa: 85 c0 test %eax,%eax +c01057fc: 74 24 je c0105822 +c01057fe: c7 44 24 0c 9a 9d 10 movl $0xc0109d9a,0xc(%esp) +c0105805: c0 +c0105806: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c010580d: c0 +c010580e: c7 44 24 04 aa 02 00 movl $0x2aa,0x4(%esp) +c0105815: 00 +c0105816: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c010581d: e8 20 b4 ff ff call c0100c42 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c0105822: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105827: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010582e: 00 +c010582f: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0105836: 00 +c0105837: 89 04 24 mov %eax,(%esp) +c010583a: e8 1e f7 ff ff call c0104f5d +c010583f: 89 45 f0 mov %eax,-0x10(%ebp) +c0105842: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0105846: 75 24 jne c010586c +c0105848: c7 44 24 0c e8 9c 10 movl $0xc0109ce8,0xc(%esp) +c010584f: c0 +c0105850: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105857: c0 +c0105858: c7 44 24 04 ac 02 00 movl $0x2ac,0x4(%esp) +c010585f: 00 +c0105860: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105867: e8 d6 b3 ff ff call c0100c42 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c010586c: 8b 45 f0 mov -0x10(%ebp),%eax +c010586f: 8b 00 mov (%eax),%eax +c0105871: 89 04 24 mov %eax,(%esp) +c0105874: e8 c4 ed ff ff call c010463d +c0105879: 39 45 f4 cmp %eax,-0xc(%ebp) +c010587c: 74 24 je c01058a2 +c010587e: c7 44 24 0c 5d 9c 10 movl $0xc0109c5d,0xc(%esp) +c0105885: c0 +c0105886: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c010588d: c0 +c010588e: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) +c0105895: 00 +c0105896: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c010589d: e8 a0 b3 ff ff call c0100c42 <__panic> + // 验证页表项没有设置用户权限 + assert((*ptep & PTE_U) == 0); +c01058a2: 8b 45 f0 mov -0x10(%ebp),%eax +c01058a5: 8b 00 mov (%eax),%eax +c01058a7: 83 e0 04 and $0x4,%eax +c01058aa: 85 c0 test %eax,%eax +c01058ac: 74 24 je c01058d2 +c01058ae: c7 44 24 0c ac 9d 10 movl $0xc0109dac,0xc(%esp) +c01058b5: c0 +c01058b6: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01058bd: c0 +c01058be: c7 44 24 04 b0 02 00 movl $0x2b0,0x4(%esp) +c01058c5: 00 +c01058c6: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01058cd: e8 70 b3 ff ff call c0100c42 <__panic> + + //移除虚拟地址 0x0 的映射, + page_remove(boot_pgdir, 0x0); +c01058d2: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c01058d7: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01058de: 00 +c01058df: 89 04 24 mov %eax,(%esp) +c01058e2: e8 70 f8 ff ff call c0105157 + //验证 p1 的引用计数减少到 1。 + assert(page_ref(p1) == 1); +c01058e7: 8b 45 f4 mov -0xc(%ebp),%eax +c01058ea: 89 04 24 mov %eax,(%esp) +c01058ed: e8 a5 ed ff ff call c0104697 +c01058f2: 83 f8 01 cmp $0x1,%eax +c01058f5: 74 24 je c010591b +c01058f7: c7 44 24 0c 73 9c 10 movl $0xc0109c73,0xc(%esp) +c01058fe: c0 +c01058ff: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105906: c0 +c0105907: c7 44 24 04 b5 02 00 movl $0x2b5,0x4(%esp) +c010590e: 00 +c010590f: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105916: e8 27 b3 ff ff call c0100c42 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c010591b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010591e: 89 04 24 mov %eax,(%esp) +c0105921: e8 71 ed ff ff call c0104697 +c0105926: 85 c0 test %eax,%eax +c0105928: 74 24 je c010594e +c010592a: c7 44 24 0c 9a 9d 10 movl $0xc0109d9a,0xc(%esp) +c0105931: c0 +c0105932: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105939: c0 +c010593a: c7 44 24 04 b7 02 00 movl $0x2b7,0x4(%esp) +c0105941: 00 +c0105942: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105949: e8 f4 b2 ff ff call c0100c42 <__panic> + + //移除虚拟地址 PGSIZE 的映射, + page_remove(boot_pgdir, PGSIZE); +c010594e: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105953: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c010595a: 00 +c010595b: 89 04 24 mov %eax,(%esp) +c010595e: e8 f4 f7 ff ff call c0105157 + //验证 p1 的引用计数减少到 0 + assert(page_ref(p1) == 0); +c0105963: 8b 45 f4 mov -0xc(%ebp),%eax +c0105966: 89 04 24 mov %eax,(%esp) +c0105969: e8 29 ed ff ff call c0104697 +c010596e: 85 c0 test %eax,%eax +c0105970: 74 24 je c0105996 +c0105972: c7 44 24 0c c1 9d 10 movl $0xc0109dc1,0xc(%esp) +c0105979: c0 +c010597a: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105981: c0 +c0105982: c7 44 24 04 bc 02 00 movl $0x2bc,0x4(%esp) +c0105989: 00 +c010598a: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105991: e8 ac b2 ff ff call c0100c42 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0105996: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105999: 89 04 24 mov %eax,(%esp) +c010599c: e8 f6 ec ff ff call c0104697 +c01059a1: 85 c0 test %eax,%eax +c01059a3: 74 24 je c01059c9 +c01059a5: c7 44 24 0c 9a 9d 10 movl $0xc0109d9a,0xc(%esp) +c01059ac: c0 +c01059ad: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01059b4: c0 +c01059b5: c7 44 24 04 be 02 00 movl $0x2be,0x4(%esp) +c01059bc: 00 +c01059bd: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01059c4: e8 79 b2 ff ff call c0100c42 <__panic> + + //验证页目录的第一页表的引用计数为 1。 + assert(page_ref(pde2page(boot_pgdir[0])) == 1); +c01059c9: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c01059ce: 8b 00 mov (%eax),%eax +c01059d0: 89 04 24 mov %eax,(%esp) +c01059d3: e8 a5 ec ff ff call c010467d +c01059d8: 89 04 24 mov %eax,(%esp) +c01059db: e8 b7 ec ff ff call c0104697 +c01059e0: 83 f8 01 cmp $0x1,%eax +c01059e3: 74 24 je c0105a09 +c01059e5: c7 44 24 0c d4 9d 10 movl $0xc0109dd4,0xc(%esp) +c01059ec: c0 +c01059ed: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01059f4: c0 +c01059f5: c7 44 24 04 c1 02 00 movl $0x2c1,0x4(%esp) +c01059fc: 00 +c01059fd: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105a04: e8 39 b2 ff ff call c0100c42 <__panic> + //释放页目录的第一页表 + free_page(pde2page(boot_pgdir[0])); +c0105a09: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105a0e: 8b 00 mov (%eax),%eax +c0105a10: 89 04 24 mov %eax,(%esp) +c0105a13: e8 65 ec ff ff call c010467d +c0105a18: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0105a1f: 00 +c0105a20: 89 04 24 mov %eax,(%esp) +c0105a23: e8 ec ee ff ff call c0104914 + //清空页目录的第一页表 + boot_pgdir[0] = 0; +c0105a28: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105a2d: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_pgdir() succeeded!\n"); +c0105a33: c7 04 24 fb 9d 10 c0 movl $0xc0109dfb,(%esp) +c0105a3a: e8 36 a9 ff ff call c0100375 +} +c0105a3f: 90 nop +c0105a40: 89 ec mov %ebp,%esp +c0105a42: 5d pop %ebp +c0105a43: c3 ret + +c0105a44 : + +//检查内核页表 boot_pgdir 的正确性 +static void +check_boot_pgdir(void) { +c0105a44: 55 push %ebp +c0105a45: 89 e5 mov %esp,%ebp +c0105a47: 83 ec 38 sub $0x38,%esp + pte_t *ptep;// 定义一个指向页表项的指针 + int i; + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0105a4a: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0105a51: e9 ca 00 00 00 jmp c0105b20 + // 获取第 i 个页面的页表项,并确保其不为空 + assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); +c0105a56: 8b 45 f4 mov -0xc(%ebp),%eax +c0105a59: 89 45 e4 mov %eax,-0x1c(%ebp) +c0105a5c: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105a5f: c1 e8 0c shr $0xc,%eax +c0105a62: 89 45 e0 mov %eax,-0x20(%ebp) +c0105a65: a1 04 60 12 c0 mov 0xc0126004,%eax +c0105a6a: 39 45 e0 cmp %eax,-0x20(%ebp) +c0105a6d: 72 23 jb c0105a92 +c0105a6f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105a72: 89 44 24 0c mov %eax,0xc(%esp) +c0105a76: c7 44 24 08 2c 9a 10 movl $0xc0109a2c,0x8(%esp) +c0105a7d: c0 +c0105a7e: c7 44 24 04 d1 02 00 movl $0x2d1,0x4(%esp) +c0105a85: 00 +c0105a86: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105a8d: e8 b0 b1 ff ff call c0100c42 <__panic> +c0105a92: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105a95: 2d 00 00 00 40 sub $0x40000000,%eax +c0105a9a: 89 c2 mov %eax,%edx +c0105a9c: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105aa1: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0105aa8: 00 +c0105aa9: 89 54 24 04 mov %edx,0x4(%esp) +c0105aad: 89 04 24 mov %eax,(%esp) +c0105ab0: e8 a8 f4 ff ff call c0104f5d +c0105ab5: 89 45 dc mov %eax,-0x24(%ebp) +c0105ab8: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0105abc: 75 24 jne c0105ae2 +c0105abe: c7 44 24 0c 18 9e 10 movl $0xc0109e18,0xc(%esp) +c0105ac5: c0 +c0105ac6: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105acd: c0 +c0105ace: c7 44 24 04 d1 02 00 movl $0x2d1,0x4(%esp) +c0105ad5: 00 +c0105ad6: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105add: e8 60 b1 ff ff call c0100c42 <__panic> + // 验证页表项的物理地址是否正确 + assert(PTE_ADDR(*ptep) == i); +c0105ae2: 8b 45 dc mov -0x24(%ebp),%eax +c0105ae5: 8b 00 mov (%eax),%eax +c0105ae7: 25 00 f0 ff ff and $0xfffff000,%eax +c0105aec: 89 c2 mov %eax,%edx +c0105aee: 8b 45 f4 mov -0xc(%ebp),%eax +c0105af1: 39 c2 cmp %eax,%edx +c0105af3: 74 24 je c0105b19 +c0105af5: c7 44 24 0c 55 9e 10 movl $0xc0109e55,0xc(%esp) +c0105afc: c0 +c0105afd: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105b04: c0 +c0105b05: c7 44 24 04 d3 02 00 movl $0x2d3,0x4(%esp) +c0105b0c: 00 +c0105b0d: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105b14: e8 29 b1 ff ff call c0100c42 <__panic> + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0105b19: 81 45 f4 00 10 00 00 addl $0x1000,-0xc(%ebp) +c0105b20: 8b 55 f4 mov -0xc(%ebp),%edx +c0105b23: a1 04 60 12 c0 mov 0xc0126004,%eax +c0105b28: 39 c2 cmp %eax,%edx +c0105b2a: 0f 82 26 ff ff ff jb c0105a56 + } + // 验证页目录项的物理地址是否正确 + assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); +c0105b30: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105b35: 05 ac 0f 00 00 add $0xfac,%eax +c0105b3a: 8b 00 mov (%eax),%eax +c0105b3c: 25 00 f0 ff ff and $0xfffff000,%eax +c0105b41: 89 c2 mov %eax,%edx +c0105b43: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105b48: 89 45 f0 mov %eax,-0x10(%ebp) +c0105b4b: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c0105b52: 77 23 ja c0105b77 +c0105b54: 8b 45 f0 mov -0x10(%ebp),%eax +c0105b57: 89 44 24 0c mov %eax,0xc(%esp) +c0105b5b: c7 44 24 08 50 9a 10 movl $0xc0109a50,0x8(%esp) +c0105b62: c0 +c0105b63: c7 44 24 04 d6 02 00 movl $0x2d6,0x4(%esp) +c0105b6a: 00 +c0105b6b: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105b72: e8 cb b0 ff ff call c0100c42 <__panic> +c0105b77: 8b 45 f0 mov -0x10(%ebp),%eax +c0105b7a: 05 00 00 00 40 add $0x40000000,%eax +c0105b7f: 39 d0 cmp %edx,%eax +c0105b81: 74 24 je c0105ba7 +c0105b83: c7 44 24 0c 6c 9e 10 movl $0xc0109e6c,0xc(%esp) +c0105b8a: c0 +c0105b8b: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105b92: c0 +c0105b93: c7 44 24 04 d6 02 00 movl $0x2d6,0x4(%esp) +c0105b9a: 00 +c0105b9b: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105ba2: e8 9b b0 ff ff call c0100c42 <__panic> + + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 +c0105ba7: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105bac: 8b 00 mov (%eax),%eax +c0105bae: 85 c0 test %eax,%eax +c0105bb0: 74 24 je c0105bd6 +c0105bb2: c7 44 24 0c a0 9e 10 movl $0xc0109ea0,0xc(%esp) +c0105bb9: c0 +c0105bba: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105bc1: c0 +c0105bc2: c7 44 24 04 d8 02 00 movl $0x2d8,0x4(%esp) +c0105bc9: 00 +c0105bca: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105bd1: e8 6c b0 ff ff call c0100c42 <__panic> + + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 +c0105bd6: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0105bdd: e8 c5 ec ff ff call c01048a7 +c0105be2: 89 45 ec mov %eax,-0x14(%ebp) + // 将页面插入到虚拟地址 0x100,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); +c0105be5: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105bea: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c0105bf1: 00 +c0105bf2: c7 44 24 08 00 01 00 movl $0x100,0x8(%esp) +c0105bf9: 00 +c0105bfa: 8b 55 ec mov -0x14(%ebp),%edx +c0105bfd: 89 54 24 04 mov %edx,0x4(%esp) +c0105c01: 89 04 24 mov %eax,(%esp) +c0105c04: e8 95 f5 ff ff call c010519e +c0105c09: 85 c0 test %eax,%eax +c0105c0b: 74 24 je c0105c31 +c0105c0d: c7 44 24 0c b4 9e 10 movl $0xc0109eb4,0xc(%esp) +c0105c14: c0 +c0105c15: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105c1c: c0 +c0105c1d: c7 44 24 04 dd 02 00 movl $0x2dd,0x4(%esp) +c0105c24: 00 +c0105c25: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105c2c: e8 11 b0 ff ff call c0100c42 <__panic> + assert(page_ref(p) == 1);// 验证页面的引用计数为1 +c0105c31: 8b 45 ec mov -0x14(%ebp),%eax +c0105c34: 89 04 24 mov %eax,(%esp) +c0105c37: e8 5b ea ff ff call c0104697 +c0105c3c: 83 f8 01 cmp $0x1,%eax +c0105c3f: 74 24 je c0105c65 +c0105c41: c7 44 24 0c e2 9e 10 movl $0xc0109ee2,0xc(%esp) +c0105c48: c0 +c0105c49: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105c50: c0 +c0105c51: c7 44 24 04 de 02 00 movl $0x2de,0x4(%esp) +c0105c58: 00 +c0105c59: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105c60: e8 dd af ff ff call c0100c42 <__panic> + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); +c0105c65: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105c6a: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c0105c71: 00 +c0105c72: c7 44 24 08 00 11 00 movl $0x1100,0x8(%esp) +c0105c79: 00 +c0105c7a: 8b 55 ec mov -0x14(%ebp),%edx +c0105c7d: 89 54 24 04 mov %edx,0x4(%esp) +c0105c81: 89 04 24 mov %eax,(%esp) +c0105c84: e8 15 f5 ff ff call c010519e +c0105c89: 85 c0 test %eax,%eax +c0105c8b: 74 24 je c0105cb1 +c0105c8d: c7 44 24 0c f4 9e 10 movl $0xc0109ef4,0xc(%esp) +c0105c94: c0 +c0105c95: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105c9c: c0 +c0105c9d: c7 44 24 04 e0 02 00 movl $0x2e0,0x4(%esp) +c0105ca4: 00 +c0105ca5: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105cac: e8 91 af ff ff call c0100c42 <__panic> + assert(page_ref(p) == 2);// 验证页面的引用计数为2 +c0105cb1: 8b 45 ec mov -0x14(%ebp),%eax +c0105cb4: 89 04 24 mov %eax,(%esp) +c0105cb7: e8 db e9 ff ff call c0104697 +c0105cbc: 83 f8 02 cmp $0x2,%eax +c0105cbf: 74 24 je c0105ce5 +c0105cc1: c7 44 24 0c 2b 9f 10 movl $0xc0109f2b,0xc(%esp) +c0105cc8: c0 +c0105cc9: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105cd0: c0 +c0105cd1: c7 44 24 04 e1 02 00 movl $0x2e1,0x4(%esp) +c0105cd8: 00 +c0105cd9: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105ce0: e8 5d af ff ff call c0100c42 <__panic> + + const char *str = "ucore: Hello world!!";// 定义一个字符串 +c0105ce5: c7 45 e8 3c 9f 10 c0 movl $0xc0109f3c,-0x18(%ebp) + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 +c0105cec: 8b 45 e8 mov -0x18(%ebp),%eax +c0105cef: 89 44 24 04 mov %eax,0x4(%esp) +c0105cf3: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0105cfa: e8 ff 2b 00 00 call c01088fe + // 验证两个映射地址的数据是否一致 + assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); +c0105cff: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) +c0105d06: 00 +c0105d07: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0105d0e: e8 63 2c 00 00 call c0108976 +c0105d13: 85 c0 test %eax,%eax +c0105d15: 74 24 je c0105d3b +c0105d17: c7 44 24 0c 54 9f 10 movl $0xc0109f54,0xc(%esp) +c0105d1e: c0 +c0105d1f: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105d26: c0 +c0105d27: c7 44 24 04 e6 02 00 movl $0x2e6,0x4(%esp) +c0105d2e: 00 +c0105d2f: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105d36: e8 07 af ff ff call c0100c42 <__panic> + // 在页面的 0x100 偏移处设置字符串结束符 + *(char *)(page2kva(p) + 0x100) = '\0'; +c0105d3b: 8b 45 ec mov -0x14(%ebp),%eax +c0105d3e: 89 04 24 mov %eax,(%esp) +c0105d41: e8 55 e8 ff ff call c010459b +c0105d46: 05 00 01 00 00 add $0x100,%eax +c0105d4b: c6 00 00 movb $0x0,(%eax) + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 +c0105d4e: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0105d55: e8 4a 2b 00 00 call c01088a4 +c0105d5a: 85 c0 test %eax,%eax +c0105d5c: 74 24 je c0105d82 +c0105d5e: c7 44 24 0c 8c 9f 10 movl $0xc0109f8c,0xc(%esp) +c0105d65: c0 +c0105d66: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c0105d6d: c0 +c0105d6e: c7 44 24 04 e9 02 00 movl $0x2e9,0x4(%esp) +c0105d75: 00 +c0105d76: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0105d7d: e8 c0 ae ff ff call c0100c42 <__panic> + + free_page(p);// 释放页面 p +c0105d82: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0105d89: 00 +c0105d8a: 8b 45 ec mov -0x14(%ebp),%eax +c0105d8d: 89 04 24 mov %eax,(%esp) +c0105d90: e8 7f eb ff ff call c0104914 + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 +c0105d95: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105d9a: 8b 00 mov (%eax),%eax +c0105d9c: 89 04 24 mov %eax,(%esp) +c0105d9f: e8 d9 e8 ff ff call c010467d +c0105da4: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0105dab: 00 +c0105dac: 89 04 24 mov %eax,(%esp) +c0105daf: e8 60 eb ff ff call c0104914 + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 +c0105db4: a1 e0 29 12 c0 mov 0xc01229e0,%eax +c0105db9: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息 +c0105dbf: c7 04 24 b0 9f 10 c0 movl $0xc0109fb0,(%esp) +c0105dc6: e8 aa a5 ff ff call c0100375 +} +c0105dcb: 90 nop +c0105dcc: 89 ec mov %ebp,%esp +c0105dce: 5d pop %ebp +c0105dcf: c3 ret + +c0105dd0 : + +//perm2str - use string 'u,r,w,-' to present the permission +static const char * +perm2str(int perm) { +c0105dd0: 55 push %ebp +c0105dd1: 89 e5 mov %esp,%ebp + //定义一个静态字符数组 str,长度为4 + static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' + str[0] = (perm & PTE_U) ? 'u' : '-'; +c0105dd3: 8b 45 08 mov 0x8(%ebp),%eax +c0105dd6: 83 e0 04 and $0x4,%eax +c0105dd9: 85 c0 test %eax,%eax +c0105ddb: 74 04 je c0105de1 +c0105ddd: b0 75 mov $0x75,%al +c0105ddf: eb 02 jmp c0105de3 +c0105de1: b0 2d mov $0x2d,%al +c0105de3: a2 88 60 12 c0 mov %al,0xc0126088 + //str[1] 始终设置为 'r' + str[1] = 'r'; +c0105de8: c6 05 89 60 12 c0 72 movb $0x72,0xc0126089 + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' + str[2] = (perm & PTE_W) ? 'w' : '-'; +c0105def: 8b 45 08 mov 0x8(%ebp),%eax +c0105df2: 83 e0 02 and $0x2,%eax +c0105df5: 85 c0 test %eax,%eax +c0105df7: 74 04 je c0105dfd +c0105df9: b0 77 mov $0x77,%al +c0105dfb: eb 02 jmp c0105dff +c0105dfd: b0 2d mov $0x2d,%al +c0105dff: a2 8a 60 12 c0 mov %al,0xc012608a + //str[3] 设置为字符串结束符 \0 + str[3] = '\0'; +c0105e04: c6 05 8b 60 12 c0 00 movb $0x0,0xc012608b + return str; +c0105e0b: b8 88 60 12 c0 mov $0xc0126088,%eax +} +c0105e10: 5d pop %ebp +c0105e11: c3 ret + +c0105e12 : +// left_store: the pointer of the high side of table's next range +// right_store: the pointer of the low side of table's next range +// return value: 0 - not a invalid item range, perm - a valid item range with perm permission +//从页表中获取指定范围内的有效项,并根据权限进行处理。 +static int +get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) { +c0105e12: 55 push %ebp +c0105e13: 89 e5 mov %esp,%ebp +c0105e15: 83 ec 10 sub $0x10,%esp + if (start >= right) {// 检查起始索引是否超出右边界 +c0105e18: 8b 45 10 mov 0x10(%ebp),%eax +c0105e1b: 3b 45 0c cmp 0xc(%ebp),%eax +c0105e1e: 72 0d jb c0105e2d + return 0;// 如果超出右边界,返回0 +c0105e20: b8 00 00 00 00 mov $0x0,%eax +c0105e25: e9 98 00 00 00 jmp c0105ec2 + } + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 +c0105e2a: ff 45 10 incl 0x10(%ebp) + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) +c0105e2d: 8b 45 10 mov 0x10(%ebp),%eax +c0105e30: 3b 45 0c cmp 0xc(%ebp),%eax +c0105e33: 73 18 jae c0105e4d +c0105e35: 8b 45 10 mov 0x10(%ebp),%eax +c0105e38: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0105e3f: 8b 45 14 mov 0x14(%ebp),%eax +c0105e42: 01 d0 add %edx,%eax +c0105e44: 8b 00 mov (%eax),%eax +c0105e46: 83 e0 01 and $0x1,%eax +c0105e49: 85 c0 test %eax,%eax +c0105e4b: 74 dd je c0105e2a + } + if (start < right) {// 检查是否找到有效项 +c0105e4d: 8b 45 10 mov 0x10(%ebp),%eax +c0105e50: 3b 45 0c cmp 0xc(%ebp),%eax +c0105e53: 73 68 jae c0105ebd + if (left_store != NULL) {// 如果left_store不为NULL +c0105e55: 83 7d 18 00 cmpl $0x0,0x18(%ebp) +c0105e59: 74 08 je c0105e63 + *left_store = start;// 记录左边界索引 +c0105e5b: 8b 45 18 mov 0x18(%ebp),%eax +c0105e5e: 8b 55 10 mov 0x10(%ebp),%edx +c0105e61: 89 10 mov %edx,(%eax) + } + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 +c0105e63: 8b 45 10 mov 0x10(%ebp),%eax +c0105e66: 8d 50 01 lea 0x1(%eax),%edx +c0105e69: 89 55 10 mov %edx,0x10(%ebp) +c0105e6c: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0105e73: 8b 45 14 mov 0x14(%ebp),%eax +c0105e76: 01 d0 add %edx,%eax +c0105e78: 8b 00 mov (%eax),%eax +c0105e7a: 83 e0 07 and $0x7,%eax +c0105e7d: 89 45 fc mov %eax,-0x4(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c0105e80: eb 03 jmp c0105e85 + start ++;// 索引递增 +c0105e82: ff 45 10 incl 0x10(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c0105e85: 8b 45 10 mov 0x10(%ebp),%eax +c0105e88: 3b 45 0c cmp 0xc(%ebp),%eax +c0105e8b: 73 1d jae c0105eaa +c0105e8d: 8b 45 10 mov 0x10(%ebp),%eax +c0105e90: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0105e97: 8b 45 14 mov 0x14(%ebp),%eax +c0105e9a: 01 d0 add %edx,%eax +c0105e9c: 8b 00 mov (%eax),%eax +c0105e9e: 83 e0 07 and $0x7,%eax +c0105ea1: 89 c2 mov %eax,%edx +c0105ea3: 8b 45 fc mov -0x4(%ebp),%eax +c0105ea6: 39 c2 cmp %eax,%edx +c0105ea8: 74 d8 je c0105e82 + } + if (right_store != NULL) {// 如果right_store不为NULL +c0105eaa: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c0105eae: 74 08 je c0105eb8 + *right_store = start;// 记录右边界索引 +c0105eb0: 8b 45 1c mov 0x1c(%ebp),%eax +c0105eb3: 8b 55 10 mov 0x10(%ebp),%edx +c0105eb6: 89 10 mov %edx,(%eax) + } + return perm;// 返回用户权限位 +c0105eb8: 8b 45 fc mov -0x4(%ebp),%eax +c0105ebb: eb 05 jmp c0105ec2 + } + return 0;// 如果未找到有效项,返回0 +c0105ebd: b8 00 00 00 00 mov $0x0,%eax +} +c0105ec2: 89 ec mov %ebp,%esp +c0105ec4: 5d pop %ebp +c0105ec5: c3 ret + +c0105ec6 : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { +c0105ec6: 55 push %ebp +c0105ec7: 89 e5 mov %esp,%ebp +c0105ec9: 57 push %edi +c0105eca: 56 push %esi +c0105ecb: 53 push %ebx +c0105ecc: 83 ec 4c sub $0x4c,%esp + cprintf("-------------------- BEGIN --------------------\n"); +c0105ecf: c7 04 24 d0 9f 10 c0 movl $0xc0109fd0,(%esp) +c0105ed6: e8 9a a4 ff ff call c0100375 + // 定义变量 left, right 和 perm + size_t left, right = 0, perm; +c0105edb: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + // 遍历页目录项 + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c0105ee2: e9 f2 00 00 00 jmp c0105fd9 + // 打印页目录项的信息 + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0105ee7: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105eea: 89 04 24 mov %eax,(%esp) +c0105eed: e8 de fe ff ff call c0105dd0 + left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); +c0105ef2: 8b 55 dc mov -0x24(%ebp),%edx +c0105ef5: 8b 4d e0 mov -0x20(%ebp),%ecx +c0105ef8: 29 ca sub %ecx,%edx + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0105efa: 89 d6 mov %edx,%esi +c0105efc: c1 e6 16 shl $0x16,%esi +c0105eff: 8b 55 dc mov -0x24(%ebp),%edx +c0105f02: 89 d3 mov %edx,%ebx +c0105f04: c1 e3 16 shl $0x16,%ebx +c0105f07: 8b 55 e0 mov -0x20(%ebp),%edx +c0105f0a: 89 d1 mov %edx,%ecx +c0105f0c: c1 e1 16 shl $0x16,%ecx +c0105f0f: 8b 55 dc mov -0x24(%ebp),%edx +c0105f12: 8b 7d e0 mov -0x20(%ebp),%edi +c0105f15: 29 fa sub %edi,%edx +c0105f17: 89 44 24 14 mov %eax,0x14(%esp) +c0105f1b: 89 74 24 10 mov %esi,0x10(%esp) +c0105f1f: 89 5c 24 0c mov %ebx,0xc(%esp) +c0105f23: 89 4c 24 08 mov %ecx,0x8(%esp) +c0105f27: 89 54 24 04 mov %edx,0x4(%esp) +c0105f2b: c7 04 24 01 a0 10 c0 movl $0xc010a001,(%esp) +c0105f32: e8 3e a4 ff ff call c0100375 + // 计算页表项的起始和结束索引 + size_t l, r = left * NPTEENTRY; +c0105f37: 8b 45 e0 mov -0x20(%ebp),%eax +c0105f3a: c1 e0 0a shl $0xa,%eax +c0105f3d: 89 45 d4 mov %eax,-0x2c(%ebp) + // 遍历页表项 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c0105f40: eb 50 jmp c0105f92 + // 打印页表项的信息 + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c0105f42: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105f45: 89 04 24 mov %eax,(%esp) +c0105f48: e8 83 fe ff ff call c0105dd0 + l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); +c0105f4d: 8b 55 d4 mov -0x2c(%ebp),%edx +c0105f50: 8b 4d d8 mov -0x28(%ebp),%ecx +c0105f53: 29 ca sub %ecx,%edx + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c0105f55: 89 d6 mov %edx,%esi +c0105f57: c1 e6 0c shl $0xc,%esi +c0105f5a: 8b 55 d4 mov -0x2c(%ebp),%edx +c0105f5d: 89 d3 mov %edx,%ebx +c0105f5f: c1 e3 0c shl $0xc,%ebx +c0105f62: 8b 55 d8 mov -0x28(%ebp),%edx +c0105f65: 89 d1 mov %edx,%ecx +c0105f67: c1 e1 0c shl $0xc,%ecx +c0105f6a: 8b 55 d4 mov -0x2c(%ebp),%edx +c0105f6d: 8b 7d d8 mov -0x28(%ebp),%edi +c0105f70: 29 fa sub %edi,%edx +c0105f72: 89 44 24 14 mov %eax,0x14(%esp) +c0105f76: 89 74 24 10 mov %esi,0x10(%esp) +c0105f7a: 89 5c 24 0c mov %ebx,0xc(%esp) +c0105f7e: 89 4c 24 08 mov %ecx,0x8(%esp) +c0105f82: 89 54 24 04 mov %edx,0x4(%esp) +c0105f86: c7 04 24 20 a0 10 c0 movl $0xc010a020,(%esp) +c0105f8d: e8 e3 a3 ff ff call c0100375 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c0105f92: be 00 00 c0 fa mov $0xfac00000,%esi +c0105f97: 8b 45 d4 mov -0x2c(%ebp),%eax +c0105f9a: 8b 55 dc mov -0x24(%ebp),%edx +c0105f9d: 89 d3 mov %edx,%ebx +c0105f9f: c1 e3 0a shl $0xa,%ebx +c0105fa2: 8b 55 e0 mov -0x20(%ebp),%edx +c0105fa5: 89 d1 mov %edx,%ecx +c0105fa7: c1 e1 0a shl $0xa,%ecx +c0105faa: 8d 55 d4 lea -0x2c(%ebp),%edx +c0105fad: 89 54 24 14 mov %edx,0x14(%esp) +c0105fb1: 8d 55 d8 lea -0x28(%ebp),%edx +c0105fb4: 89 54 24 10 mov %edx,0x10(%esp) +c0105fb8: 89 74 24 0c mov %esi,0xc(%esp) +c0105fbc: 89 44 24 08 mov %eax,0x8(%esp) +c0105fc0: 89 5c 24 04 mov %ebx,0x4(%esp) +c0105fc4: 89 0c 24 mov %ecx,(%esp) +c0105fc7: e8 46 fe ff ff call c0105e12 +c0105fcc: 89 45 e4 mov %eax,-0x1c(%ebp) +c0105fcf: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0105fd3: 0f 85 69 ff ff ff jne c0105f42 + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c0105fd9: b9 00 b0 fe fa mov $0xfafeb000,%ecx +c0105fde: 8b 45 dc mov -0x24(%ebp),%eax +c0105fe1: 8d 55 dc lea -0x24(%ebp),%edx +c0105fe4: 89 54 24 14 mov %edx,0x14(%esp) +c0105fe8: 8d 55 e0 lea -0x20(%ebp),%edx +c0105feb: 89 54 24 10 mov %edx,0x10(%esp) +c0105fef: 89 4c 24 0c mov %ecx,0xc(%esp) +c0105ff3: 89 44 24 08 mov %eax,0x8(%esp) +c0105ff7: c7 44 24 04 00 04 00 movl $0x400,0x4(%esp) +c0105ffe: 00 +c0105fff: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0106006: e8 07 fe ff ff call c0105e12 +c010600b: 89 45 e4 mov %eax,-0x1c(%ebp) +c010600e: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0106012: 0f 85 cf fe ff ff jne c0105ee7 + } + } + cprintf("--------------------- END ---------------------\n"); +c0106018: c7 04 24 44 a0 10 c0 movl $0xc010a044,(%esp) +c010601f: e8 51 a3 ff ff call c0100375 +} +c0106024: 90 nop +c0106025: 83 c4 4c add $0x4c,%esp +c0106028: 5b pop %ebx +c0106029: 5e pop %esi +c010602a: 5f pop %edi +c010602b: 5d pop %ebp +c010602c: c3 ret + +c010602d : + +//size_t n,表示请求的内存大小。 +void * +kmalloc(size_t n) { +c010602d: 55 push %ebp +c010602e: 89 e5 mov %esp,%ebp +c0106030: 83 ec 28 sub $0x28,%esp + //ptr用于存储分配的内存地址。 + void * ptr=NULL; +c0106033: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + //base用于存储分配的页面基址 + struct Page *base=NULL; +c010603a: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + assert(n > 0 && n < 1024*0124); +c0106041: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0106045: 74 09 je c0106050 +c0106047: 81 7d 08 ff 4f 01 00 cmpl $0x14fff,0x8(%ebp) +c010604e: 76 24 jbe c0106074 +c0106050: c7 44 24 0c 75 a0 10 movl $0xc010a075,0xc(%esp) +c0106057: c0 +c0106058: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c010605f: c0 +c0106060: c7 44 24 04 44 03 00 movl $0x344,0x4(%esp) +c0106067: 00 +c0106068: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c010606f: e8 ce ab ff ff call c0100c42 <__panic> + //计算所需页数 + int num_pages=(n+PGSIZE-1)/PGSIZE; +c0106074: 8b 45 08 mov 0x8(%ebp),%eax +c0106077: 05 ff 0f 00 00 add $0xfff,%eax +c010607c: c1 e8 0c shr $0xc,%eax +c010607f: 89 45 ec mov %eax,-0x14(%ebp) + //分配num_pages个页面,结果存储在 base 中 + base = alloc_pages(num_pages); +c0106082: 8b 45 ec mov -0x14(%ebp),%eax +c0106085: 89 04 24 mov %eax,(%esp) +c0106088: e8 1a e8 ff ff call c01048a7 +c010608d: 89 45 f0 mov %eax,-0x10(%ebp) + //检查页面分配是否成功 + assert(base != NULL); +c0106090: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0106094: 75 24 jne c01060ba +c0106096: c7 44 24 0c 8c a0 10 movl $0xc010a08c,0xc(%esp) +c010609d: c0 +c010609e: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01060a5: c0 +c01060a6: c7 44 24 04 4a 03 00 movl $0x34a,0x4(%esp) +c01060ad: 00 +c01060ae: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c01060b5: e8 88 ab ff ff call c0100c42 <__panic> + //将分配的页面基址 base 转换为内核虚拟地址,结果存储在 ptr 中 + ptr=page2kva(base); +c01060ba: 8b 45 f0 mov -0x10(%ebp),%eax +c01060bd: 89 04 24 mov %eax,(%esp) +c01060c0: e8 d6 e4 ff ff call c010459b +c01060c5: 89 45 f4 mov %eax,-0xc(%ebp) + return ptr; +c01060c8: 8b 45 f4 mov -0xc(%ebp),%eax +} +c01060cb: 89 ec mov %ebp,%esp +c01060cd: 5d pop %ebp +c01060ce: c3 ret + +c01060cf : + +void +kfree(void *ptr, size_t n) { +c01060cf: 55 push %ebp +c01060d0: 89 e5 mov %esp,%ebp +c01060d2: 83 ec 28 sub $0x28,%esp + assert(n > 0 && n < 1024*0124); +c01060d5: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01060d9: 74 09 je c01060e4 +c01060db: 81 7d 0c ff 4f 01 00 cmpl $0x14fff,0xc(%ebp) +c01060e2: 76 24 jbe c0106108 +c01060e4: c7 44 24 0c 75 a0 10 movl $0xc010a075,0xc(%esp) +c01060eb: c0 +c01060ec: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c01060f3: c0 +c01060f4: c7 44 24 04 52 03 00 movl $0x352,0x4(%esp) +c01060fb: 00 +c01060fc: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c0106103: e8 3a ab ff ff call c0100c42 <__panic> + assert(ptr != NULL); +c0106108: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010610c: 75 24 jne c0106132 +c010610e: c7 44 24 0c 99 a0 10 movl $0xc010a099,0xc(%esp) +c0106115: c0 +c0106116: c7 44 24 08 19 9b 10 movl $0xc0109b19,0x8(%esp) +c010611d: c0 +c010611e: c7 44 24 04 53 03 00 movl $0x353,0x4(%esp) +c0106125: 00 +c0106126: c7 04 24 f4 9a 10 c0 movl $0xc0109af4,(%esp) +c010612d: e8 10 ab ff ff call c0100c42 <__panic> + struct Page *base=NULL; +c0106132: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + //计算需要释放的页数 + int num_pages=(n+PGSIZE-1)/PGSIZE; +c0106139: 8b 45 0c mov 0xc(%ebp),%eax +c010613c: 05 ff 0f 00 00 add $0xfff,%eax +c0106141: c1 e8 0c shr $0xc,%eax +c0106144: 89 45 f0 mov %eax,-0x10(%ebp) + //将虚拟地址 ptr 转换为物理页的指针 base + base = kva2page(ptr); +c0106147: 8b 45 08 mov 0x8(%ebp),%eax +c010614a: 89 04 24 mov %eax,(%esp) +c010614d: e8 9f e4 ff ff call c01045f1 +c0106152: 89 45 f4 mov %eax,-0xc(%ebp) + //释放从 base 开始的 num_pages 个页面 + free_pages(base, num_pages); +c0106155: 8b 45 f0 mov -0x10(%ebp),%eax +c0106158: 89 44 24 04 mov %eax,0x4(%esp) +c010615c: 8b 45 f4 mov -0xc(%ebp),%eax +c010615f: 89 04 24 mov %eax,(%esp) +c0106162: e8 ad e7 ff ff call c0104914 +} +c0106167: 90 nop +c0106168: 89 ec mov %ebp,%esp +c010616a: 5d pop %ebp +c010616b: c3 ret + +c010616c : +pa2page(uintptr_t pa) { +c010616c: 55 push %ebp +c010616d: 89 e5 mov %esp,%ebp +c010616f: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0106172: 8b 45 08 mov 0x8(%ebp),%eax +c0106175: c1 e8 0c shr $0xc,%eax +c0106178: 89 c2 mov %eax,%edx +c010617a: a1 04 60 12 c0 mov 0xc0126004,%eax +c010617f: 39 c2 cmp %eax,%edx +c0106181: 72 1c jb c010619f + panic("pa2page called with invalid pa"); +c0106183: c7 44 24 08 a8 a0 10 movl $0xc010a0a8,0x8(%esp) +c010618a: c0 +c010618b: c7 44 24 04 5b 00 00 movl $0x5b,0x4(%esp) +c0106192: 00 +c0106193: c7 04 24 c7 a0 10 c0 movl $0xc010a0c7,(%esp) +c010619a: e8 a3 aa ff ff call c0100c42 <__panic> + return &pages[PPN(pa)]; +c010619f: 8b 15 00 60 12 c0 mov 0xc0126000,%edx +c01061a5: 8b 45 08 mov 0x8(%ebp),%eax +c01061a8: c1 e8 0c shr $0xc,%eax +c01061ab: c1 e0 05 shl $0x5,%eax +c01061ae: 01 d0 add %edx,%eax +} +c01061b0: 89 ec mov %ebp,%esp +c01061b2: 5d pop %ebp +c01061b3: c3 ret + +c01061b4 : +pte2page(pte_t pte) { +c01061b4: 55 push %ebp +c01061b5: 89 e5 mov %esp,%ebp +c01061b7: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { +c01061ba: 8b 45 08 mov 0x8(%ebp),%eax +c01061bd: 83 e0 01 and $0x1,%eax +c01061c0: 85 c0 test %eax,%eax +c01061c2: 75 1c jne c01061e0 + panic("pte2page called with invalid pte"); +c01061c4: c7 44 24 08 d8 a0 10 movl $0xc010a0d8,0x8(%esp) +c01061cb: c0 +c01061cc: c7 44 24 04 6d 00 00 movl $0x6d,0x4(%esp) +c01061d3: 00 +c01061d4: c7 04 24 c7 a0 10 c0 movl $0xc010a0c7,(%esp) +c01061db: e8 62 aa ff ff call c0100c42 <__panic> + return pa2page(PTE_ADDR(pte)); +c01061e0: 8b 45 08 mov 0x8(%ebp),%eax +c01061e3: 25 00 f0 ff ff and $0xfffff000,%eax +c01061e8: 89 04 24 mov %eax,(%esp) +c01061eb: e8 7c ff ff ff call c010616c +} +c01061f0: 89 ec mov %ebp,%esp +c01061f2: 5d pop %ebp +c01061f3: c3 ret + +c01061f4 : + +static void check_swap(void); + +int +swap_init(void) +{ +c01061f4: 55 push %ebp +c01061f5: 89 e5 mov %esp,%ebp +c01061f7: 83 ec 28 sub $0x28,%esp + swapfs_init(); +c01061fa: e8 26 1e 00 00 call c0108025 + + if (!(1024 <= max_swap_offset && max_swap_offset < MAX_SWAP_OFFSET_LIMIT)) +c01061ff: a1 a0 60 12 c0 mov 0xc01260a0,%eax +c0106204: 3d ff 03 00 00 cmp $0x3ff,%eax +c0106209: 76 0c jbe c0106217 +c010620b: a1 a0 60 12 c0 mov 0xc01260a0,%eax +c0106210: 3d ff ff ff 00 cmp $0xffffff,%eax +c0106215: 76 25 jbe c010623c + { + panic("bad max_swap_offset %08x.\n", max_swap_offset); +c0106217: a1 a0 60 12 c0 mov 0xc01260a0,%eax +c010621c: 89 44 24 0c mov %eax,0xc(%esp) +c0106220: c7 44 24 08 f9 a0 10 movl $0xc010a0f9,0x8(%esp) +c0106227: c0 +c0106228: c7 44 24 04 25 00 00 movl $0x25,0x4(%esp) +c010622f: 00 +c0106230: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106237: e8 06 aa ff ff call c0100c42 <__panic> + } + + + sm = &swap_manager_fifo; +c010623c: c7 05 60 61 12 c0 40 movl $0xc0122a40,0xc0126160 +c0106243: 2a 12 c0 + int r = sm->init(); +c0106246: a1 60 61 12 c0 mov 0xc0126160,%eax +c010624b: 8b 40 04 mov 0x4(%eax),%eax +c010624e: ff d0 call *%eax +c0106250: 89 45 f4 mov %eax,-0xc(%ebp) + + if (r == 0) +c0106253: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0106257: 75 26 jne c010627f + { + swap_init_ok = 1; +c0106259: c7 05 a4 60 12 c0 01 movl $0x1,0xc01260a4 +c0106260: 00 00 00 + cprintf("SWAP: manager = %s\n", sm->name); +c0106263: a1 60 61 12 c0 mov 0xc0126160,%eax +c0106268: 8b 00 mov (%eax),%eax +c010626a: 89 44 24 04 mov %eax,0x4(%esp) +c010626e: c7 04 24 23 a1 10 c0 movl $0xc010a123,(%esp) +c0106275: e8 fb a0 ff ff call c0100375 + check_swap(); +c010627a: e8 b0 04 00 00 call c010672f + } + + return r; +c010627f: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0106282: 89 ec mov %ebp,%esp +c0106284: 5d pop %ebp +c0106285: c3 ret + +c0106286 : + +int +swap_init_mm(struct mm_struct *mm) +{ +c0106286: 55 push %ebp +c0106287: 89 e5 mov %esp,%ebp +c0106289: 83 ec 18 sub $0x18,%esp + return sm->init_mm(mm); +c010628c: a1 60 61 12 c0 mov 0xc0126160,%eax +c0106291: 8b 40 08 mov 0x8(%eax),%eax +c0106294: 8b 55 08 mov 0x8(%ebp),%edx +c0106297: 89 14 24 mov %edx,(%esp) +c010629a: ff d0 call *%eax +} +c010629c: 89 ec mov %ebp,%esp +c010629e: 5d pop %ebp +c010629f: c3 ret + +c01062a0 : + +int +swap_tick_event(struct mm_struct *mm) +{ +c01062a0: 55 push %ebp +c01062a1: 89 e5 mov %esp,%ebp +c01062a3: 83 ec 18 sub $0x18,%esp + return sm->tick_event(mm); +c01062a6: a1 60 61 12 c0 mov 0xc0126160,%eax +c01062ab: 8b 40 0c mov 0xc(%eax),%eax +c01062ae: 8b 55 08 mov 0x8(%ebp),%edx +c01062b1: 89 14 24 mov %edx,(%esp) +c01062b4: ff d0 call *%eax +} +c01062b6: 89 ec mov %ebp,%esp +c01062b8: 5d pop %ebp +c01062b9: c3 ret + +c01062ba : + +int +swap_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in) +{ +c01062ba: 55 push %ebp +c01062bb: 89 e5 mov %esp,%ebp +c01062bd: 83 ec 18 sub $0x18,%esp + return sm->map_swappable(mm, addr, page, swap_in); +c01062c0: a1 60 61 12 c0 mov 0xc0126160,%eax +c01062c5: 8b 40 10 mov 0x10(%eax),%eax +c01062c8: 8b 55 14 mov 0x14(%ebp),%edx +c01062cb: 89 54 24 0c mov %edx,0xc(%esp) +c01062cf: 8b 55 10 mov 0x10(%ebp),%edx +c01062d2: 89 54 24 08 mov %edx,0x8(%esp) +c01062d6: 8b 55 0c mov 0xc(%ebp),%edx +c01062d9: 89 54 24 04 mov %edx,0x4(%esp) +c01062dd: 8b 55 08 mov 0x8(%ebp),%edx +c01062e0: 89 14 24 mov %edx,(%esp) +c01062e3: ff d0 call *%eax +} +c01062e5: 89 ec mov %ebp,%esp +c01062e7: 5d pop %ebp +c01062e8: c3 ret + +c01062e9 : + +int +swap_set_unswappable(struct mm_struct *mm, uintptr_t addr) +{ +c01062e9: 55 push %ebp +c01062ea: 89 e5 mov %esp,%ebp +c01062ec: 83 ec 18 sub $0x18,%esp + return sm->set_unswappable(mm, addr); +c01062ef: a1 60 61 12 c0 mov 0xc0126160,%eax +c01062f4: 8b 40 14 mov 0x14(%eax),%eax +c01062f7: 8b 55 0c mov 0xc(%ebp),%edx +c01062fa: 89 54 24 04 mov %edx,0x4(%esp) +c01062fe: 8b 55 08 mov 0x8(%ebp),%edx +c0106301: 89 14 24 mov %edx,(%esp) +c0106304: ff d0 call *%eax +} +c0106306: 89 ec mov %ebp,%esp +c0106308: 5d pop %ebp +c0106309: c3 ret + +c010630a : + +volatile unsigned int swap_out_num=0; + +int +swap_out(struct mm_struct *mm, int n, int in_tick) +{ +c010630a: 55 push %ebp +c010630b: 89 e5 mov %esp,%ebp +c010630d: 83 ec 38 sub $0x38,%esp + int i; + for (i = 0; i != n; ++ i) +c0106310: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0106317: e9 53 01 00 00 jmp c010646f + { + uintptr_t v; + //struct Page **ptr_page=NULL; + struct Page *page; + // cprintf("i %d, SWAP: call swap_out_victim\n",i); + int r = sm->swap_out_victim(mm, &page, in_tick); +c010631c: a1 60 61 12 c0 mov 0xc0126160,%eax +c0106321: 8b 40 18 mov 0x18(%eax),%eax +c0106324: 8b 55 10 mov 0x10(%ebp),%edx +c0106327: 89 54 24 08 mov %edx,0x8(%esp) +c010632b: 8d 55 e4 lea -0x1c(%ebp),%edx +c010632e: 89 54 24 04 mov %edx,0x4(%esp) +c0106332: 8b 55 08 mov 0x8(%ebp),%edx +c0106335: 89 14 24 mov %edx,(%esp) +c0106338: ff d0 call *%eax +c010633a: 89 45 f0 mov %eax,-0x10(%ebp) + if (r != 0) { +c010633d: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0106341: 74 18 je c010635b + cprintf("i %d, swap_out: call swap_out_victim failed\n",i); +c0106343: 8b 45 f4 mov -0xc(%ebp),%eax +c0106346: 89 44 24 04 mov %eax,0x4(%esp) +c010634a: c7 04 24 38 a1 10 c0 movl $0xc010a138,(%esp) +c0106351: e8 1f a0 ff ff call c0100375 +c0106356: e9 20 01 00 00 jmp c010647b + } + //assert(!PageReserved(page)); + + //cprintf("SWAP: choose victim page 0x%08x\n", page); + + v=page->pra_vaddr; +c010635b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010635e: 8b 40 1c mov 0x1c(%eax),%eax +c0106361: 89 45 ec mov %eax,-0x14(%ebp) + pte_t *ptep = get_pte(mm->pgdir, v, 0); +c0106364: 8b 45 08 mov 0x8(%ebp),%eax +c0106367: 8b 40 0c mov 0xc(%eax),%eax +c010636a: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0106371: 00 +c0106372: 8b 55 ec mov -0x14(%ebp),%edx +c0106375: 89 54 24 04 mov %edx,0x4(%esp) +c0106379: 89 04 24 mov %eax,(%esp) +c010637c: e8 dc eb ff ff call c0104f5d +c0106381: 89 45 e8 mov %eax,-0x18(%ebp) + assert((*ptep & PTE_P) != 0); +c0106384: 8b 45 e8 mov -0x18(%ebp),%eax +c0106387: 8b 00 mov (%eax),%eax +c0106389: 83 e0 01 and $0x1,%eax +c010638c: 85 c0 test %eax,%eax +c010638e: 75 24 jne c01063b4 +c0106390: c7 44 24 0c 65 a1 10 movl $0xc010a165,0xc(%esp) +c0106397: c0 +c0106398: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c010639f: c0 +c01063a0: c7 44 24 04 65 00 00 movl $0x65,0x4(%esp) +c01063a7: 00 +c01063a8: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01063af: e8 8e a8 ff ff call c0100c42 <__panic> + + if (swapfs_write( (page->pra_vaddr/PGSIZE+1)<<8, page) != 0) { +c01063b4: 8b 45 e4 mov -0x1c(%ebp),%eax +c01063b7: 8b 55 e4 mov -0x1c(%ebp),%edx +c01063ba: 8b 52 1c mov 0x1c(%edx),%edx +c01063bd: c1 ea 0c shr $0xc,%edx +c01063c0: 42 inc %edx +c01063c1: c1 e2 08 shl $0x8,%edx +c01063c4: 89 44 24 04 mov %eax,0x4(%esp) +c01063c8: 89 14 24 mov %edx,(%esp) +c01063cb: e8 14 1d 00 00 call c01080e4 +c01063d0: 85 c0 test %eax,%eax +c01063d2: 74 34 je c0106408 + cprintf("SWAP: failed to save\n"); +c01063d4: c7 04 24 8f a1 10 c0 movl $0xc010a18f,(%esp) +c01063db: e8 95 9f ff ff call c0100375 + sm->map_swappable(mm, v, page, 0); +c01063e0: a1 60 61 12 c0 mov 0xc0126160,%eax +c01063e5: 8b 40 10 mov 0x10(%eax),%eax +c01063e8: 8b 55 e4 mov -0x1c(%ebp),%edx +c01063eb: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c01063f2: 00 +c01063f3: 89 54 24 08 mov %edx,0x8(%esp) +c01063f7: 8b 55 ec mov -0x14(%ebp),%edx +c01063fa: 89 54 24 04 mov %edx,0x4(%esp) +c01063fe: 8b 55 08 mov 0x8(%ebp),%edx +c0106401: 89 14 24 mov %edx,(%esp) +c0106404: ff d0 call *%eax +c0106406: eb 64 jmp c010646c + continue; + } + else { + cprintf("swap_out: i %d, store page in vaddr 0x%x to disk swap entry %d\n", i, v, page->pra_vaddr/PGSIZE+1); +c0106408: 8b 45 e4 mov -0x1c(%ebp),%eax +c010640b: 8b 40 1c mov 0x1c(%eax),%eax +c010640e: c1 e8 0c shr $0xc,%eax +c0106411: 40 inc %eax +c0106412: 89 44 24 0c mov %eax,0xc(%esp) +c0106416: 8b 45 ec mov -0x14(%ebp),%eax +c0106419: 89 44 24 08 mov %eax,0x8(%esp) +c010641d: 8b 45 f4 mov -0xc(%ebp),%eax +c0106420: 89 44 24 04 mov %eax,0x4(%esp) +c0106424: c7 04 24 a8 a1 10 c0 movl $0xc010a1a8,(%esp) +c010642b: e8 45 9f ff ff call c0100375 + *ptep = (page->pra_vaddr/PGSIZE+1)<<8; +c0106430: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106433: 8b 40 1c mov 0x1c(%eax),%eax +c0106436: c1 e8 0c shr $0xc,%eax +c0106439: 40 inc %eax +c010643a: c1 e0 08 shl $0x8,%eax +c010643d: 89 c2 mov %eax,%edx +c010643f: 8b 45 e8 mov -0x18(%ebp),%eax +c0106442: 89 10 mov %edx,(%eax) + free_page(page); +c0106444: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106447: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010644e: 00 +c010644f: 89 04 24 mov %eax,(%esp) +c0106452: e8 bd e4 ff ff call c0104914 + } + + tlb_invalidate(mm->pgdir, v); +c0106457: 8b 45 08 mov 0x8(%ebp),%eax +c010645a: 8b 40 0c mov 0xc(%eax),%eax +c010645d: 8b 55 ec mov -0x14(%ebp),%edx +c0106460: 89 54 24 04 mov %edx,0x4(%esp) +c0106464: 89 04 24 mov %eax,(%esp) +c0106467: e8 ed ed ff ff call c0105259 + for (i = 0; i != n; ++ i) +c010646c: ff 45 f4 incl -0xc(%ebp) +c010646f: 8b 45 f4 mov -0xc(%ebp),%eax +c0106472: 3b 45 0c cmp 0xc(%ebp),%eax +c0106475: 0f 85 a1 fe ff ff jne c010631c + } + return i; +c010647b: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010647e: 89 ec mov %ebp,%esp +c0106480: 5d pop %ebp +c0106481: c3 ret + +c0106482 : + +//实现一个页交换功能。 +int +swap_in(struct mm_struct *mm, uintptr_t addr, struct Page **ptr_result) +{ +c0106482: 55 push %ebp +c0106483: 89 e5 mov %esp,%ebp +c0106485: 83 ec 28 sub $0x28,%esp + //分配一个新的页面result + struct Page *result = alloc_page(); +c0106488: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010648f: e8 13 e4 ff ff call c01048a7 +c0106494: 89 45 f4 mov %eax,-0xc(%ebp) + assert(result!=NULL); +c0106497: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010649b: 75 24 jne c01064c1 +c010649d: c7 44 24 0c e8 a1 10 movl $0xc010a1e8,0xc(%esp) +c01064a4: c0 +c01064a5: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01064ac: c0 +c01064ad: c7 44 24 04 7d 00 00 movl $0x7d,0x4(%esp) +c01064b4: 00 +c01064b5: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01064bc: e8 81 a7 ff ff call c0100c42 <__panic> + //获取虚拟地址 addr 对应的页表项指针 ptep + pte_t *ptep = get_pte(mm->pgdir, addr, 0); +c01064c1: 8b 45 08 mov 0x8(%ebp),%eax +c01064c4: 8b 40 0c mov 0xc(%eax),%eax +c01064c7: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01064ce: 00 +c01064cf: 8b 55 0c mov 0xc(%ebp),%edx +c01064d2: 89 54 24 04 mov %edx,0x4(%esp) +c01064d6: 89 04 24 mov %eax,(%esp) +c01064d9: e8 7f ea ff ff call c0104f5d +c01064de: 89 45 f0 mov %eax,-0x10(%ebp) + // cprintf("SWAP: load ptep %x swap entry %d to vaddr 0x%08x, page %x, No %d\n", ptep, (*ptep)>>8, addr, result, (result-pages)); + + int r; + //从交换文件中读取数据到新分配的页面 result 中 + if ((r = swapfs_read((*ptep), result)) != 0) +c01064e1: 8b 45 f0 mov -0x10(%ebp),%eax +c01064e4: 8b 00 mov (%eax),%eax +c01064e6: 8b 55 f4 mov -0xc(%ebp),%edx +c01064e9: 89 54 24 04 mov %edx,0x4(%esp) +c01064ed: 89 04 24 mov %eax,(%esp) +c01064f0: e8 7b 1b 00 00 call c0108070 +c01064f5: 89 45 ec mov %eax,-0x14(%ebp) +c01064f8: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c01064fc: 74 2a je c0106528 + { + assert(r!=0); +c01064fe: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0106502: 75 24 jne c0106528 +c0106504: c7 44 24 0c f5 a1 10 movl $0xc010a1f5,0xc(%esp) +c010650b: c0 +c010650c: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106513: c0 +c0106514: c7 44 24 04 86 00 00 movl $0x86,0x4(%esp) +c010651b: 00 +c010651c: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106523: e8 1a a7 ff ff call c0100c42 <__panic> + } + cprintf("swap_in: load disk swap entry %d with swap_page in vadr 0x%x\n", (*ptep)>>8, addr); +c0106528: 8b 45 f0 mov -0x10(%ebp),%eax +c010652b: 8b 00 mov (%eax),%eax +c010652d: c1 e8 08 shr $0x8,%eax +c0106530: 89 c2 mov %eax,%edx +c0106532: 8b 45 0c mov 0xc(%ebp),%eax +c0106535: 89 44 24 08 mov %eax,0x8(%esp) +c0106539: 89 54 24 04 mov %edx,0x4(%esp) +c010653d: c7 04 24 fc a1 10 c0 movl $0xc010a1fc,(%esp) +c0106544: e8 2c 9e ff ff call c0100375 + *ptr_result=result; +c0106549: 8b 45 10 mov 0x10(%ebp),%eax +c010654c: 8b 55 f4 mov -0xc(%ebp),%edx +c010654f: 89 10 mov %edx,(%eax) + return 0; +c0106551: b8 00 00 00 00 mov $0x0,%eax +} +c0106556: 89 ec mov %ebp,%esp +c0106558: 5d pop %ebp +c0106559: c3 ret + +c010655a : + + + +static inline void +check_content_set(void) +{ +c010655a: 55 push %ebp +c010655b: 89 e5 mov %esp,%ebp +c010655d: 83 ec 18 sub $0x18,%esp + *(unsigned char *)0x1000 = 0x0a; +c0106560: b8 00 10 00 00 mov $0x1000,%eax +c0106565: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==1); +c0106568: a1 70 61 12 c0 mov 0xc0126170,%eax +c010656d: 83 f8 01 cmp $0x1,%eax +c0106570: 74 24 je c0106596 +c0106572: c7 44 24 0c 3a a2 10 movl $0xc010a23a,0xc(%esp) +c0106579: c0 +c010657a: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106581: c0 +c0106582: c7 44 24 04 93 00 00 movl $0x93,0x4(%esp) +c0106589: 00 +c010658a: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106591: e8 ac a6 ff ff call c0100c42 <__panic> + *(unsigned char *)0x1010 = 0x0a; +c0106596: b8 10 10 00 00 mov $0x1010,%eax +c010659b: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==1); +c010659e: a1 70 61 12 c0 mov 0xc0126170,%eax +c01065a3: 83 f8 01 cmp $0x1,%eax +c01065a6: 74 24 je c01065cc +c01065a8: c7 44 24 0c 3a a2 10 movl $0xc010a23a,0xc(%esp) +c01065af: c0 +c01065b0: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01065b7: c0 +c01065b8: c7 44 24 04 95 00 00 movl $0x95,0x4(%esp) +c01065bf: 00 +c01065c0: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01065c7: e8 76 a6 ff ff call c0100c42 <__panic> + *(unsigned char *)0x2000 = 0x0b; +c01065cc: b8 00 20 00 00 mov $0x2000,%eax +c01065d1: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==2); +c01065d4: a1 70 61 12 c0 mov 0xc0126170,%eax +c01065d9: 83 f8 02 cmp $0x2,%eax +c01065dc: 74 24 je c0106602 +c01065de: c7 44 24 0c 49 a2 10 movl $0xc010a249,0xc(%esp) +c01065e5: c0 +c01065e6: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01065ed: c0 +c01065ee: c7 44 24 04 97 00 00 movl $0x97,0x4(%esp) +c01065f5: 00 +c01065f6: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01065fd: e8 40 a6 ff ff call c0100c42 <__panic> + *(unsigned char *)0x2010 = 0x0b; +c0106602: b8 10 20 00 00 mov $0x2010,%eax +c0106607: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==2); +c010660a: a1 70 61 12 c0 mov 0xc0126170,%eax +c010660f: 83 f8 02 cmp $0x2,%eax +c0106612: 74 24 je c0106638 +c0106614: c7 44 24 0c 49 a2 10 movl $0xc010a249,0xc(%esp) +c010661b: c0 +c010661c: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106623: c0 +c0106624: c7 44 24 04 99 00 00 movl $0x99,0x4(%esp) +c010662b: 00 +c010662c: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106633: e8 0a a6 ff ff call c0100c42 <__panic> + *(unsigned char *)0x3000 = 0x0c; +c0106638: b8 00 30 00 00 mov $0x3000,%eax +c010663d: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==3); +c0106640: a1 70 61 12 c0 mov 0xc0126170,%eax +c0106645: 83 f8 03 cmp $0x3,%eax +c0106648: 74 24 je c010666e +c010664a: c7 44 24 0c 58 a2 10 movl $0xc010a258,0xc(%esp) +c0106651: c0 +c0106652: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106659: c0 +c010665a: c7 44 24 04 9b 00 00 movl $0x9b,0x4(%esp) +c0106661: 00 +c0106662: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106669: e8 d4 a5 ff ff call c0100c42 <__panic> + *(unsigned char *)0x3010 = 0x0c; +c010666e: b8 10 30 00 00 mov $0x3010,%eax +c0106673: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==3); +c0106676: a1 70 61 12 c0 mov 0xc0126170,%eax +c010667b: 83 f8 03 cmp $0x3,%eax +c010667e: 74 24 je c01066a4 +c0106680: c7 44 24 0c 58 a2 10 movl $0xc010a258,0xc(%esp) +c0106687: c0 +c0106688: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c010668f: c0 +c0106690: c7 44 24 04 9d 00 00 movl $0x9d,0x4(%esp) +c0106697: 00 +c0106698: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c010669f: e8 9e a5 ff ff call c0100c42 <__panic> + *(unsigned char *)0x4000 = 0x0d; +c01066a4: b8 00 40 00 00 mov $0x4000,%eax +c01066a9: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==4); +c01066ac: a1 70 61 12 c0 mov 0xc0126170,%eax +c01066b1: 83 f8 04 cmp $0x4,%eax +c01066b4: 74 24 je c01066da +c01066b6: c7 44 24 0c 67 a2 10 movl $0xc010a267,0xc(%esp) +c01066bd: c0 +c01066be: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01066c5: c0 +c01066c6: c7 44 24 04 9f 00 00 movl $0x9f,0x4(%esp) +c01066cd: 00 +c01066ce: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01066d5: e8 68 a5 ff ff call c0100c42 <__panic> + *(unsigned char *)0x4010 = 0x0d; +c01066da: b8 10 40 00 00 mov $0x4010,%eax +c01066df: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==4); +c01066e2: a1 70 61 12 c0 mov 0xc0126170,%eax +c01066e7: 83 f8 04 cmp $0x4,%eax +c01066ea: 74 24 je c0106710 +c01066ec: c7 44 24 0c 67 a2 10 movl $0xc010a267,0xc(%esp) +c01066f3: c0 +c01066f4: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01066fb: c0 +c01066fc: c7 44 24 04 a1 00 00 movl $0xa1,0x4(%esp) +c0106703: 00 +c0106704: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c010670b: e8 32 a5 ff ff call c0100c42 <__panic> +} +c0106710: 90 nop +c0106711: 89 ec mov %ebp,%esp +c0106713: 5d pop %ebp +c0106714: c3 ret + +c0106715 : + +static inline int +check_content_access(void) +{ +c0106715: 55 push %ebp +c0106716: 89 e5 mov %esp,%ebp +c0106718: 83 ec 18 sub $0x18,%esp + int ret = sm->check_swap(); +c010671b: a1 60 61 12 c0 mov 0xc0126160,%eax +c0106720: 8b 40 1c mov 0x1c(%eax),%eax +c0106723: ff d0 call *%eax +c0106725: 89 45 f4 mov %eax,-0xc(%ebp) + return ret; +c0106728: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010672b: 89 ec mov %ebp,%esp +c010672d: 5d pop %ebp +c010672e: c3 ret + +c010672f : +#define free_list (free_area.free_list) +#define nr_free (free_area.nr_free) + +static void +check_swap(void) +{ +c010672f: 55 push %ebp +c0106730: 89 e5 mov %esp,%ebp +c0106732: 83 ec 78 sub $0x78,%esp + //backup mem env + int ret, count = 0, total = 0, i; +c0106735: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c010673c: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; +c0106743: c7 45 e8 e4 5f 12 c0 movl $0xc0125fe4,-0x18(%ebp) + while ((le = list_next(le)) != &free_list) { +c010674a: eb 6a jmp c01067b6 + struct Page *p = le2page(le, page_link); +c010674c: 8b 45 e8 mov -0x18(%ebp),%eax +c010674f: 83 e8 0c sub $0xc,%eax +c0106752: 89 45 c8 mov %eax,-0x38(%ebp) + assert(PageProperty(p)); +c0106755: 8b 45 c8 mov -0x38(%ebp),%eax +c0106758: 83 c0 04 add $0x4,%eax +c010675b: c7 45 c4 01 00 00 00 movl $0x1,-0x3c(%ebp) +c0106762: 89 45 c0 mov %eax,-0x40(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0106765: 8b 45 c0 mov -0x40(%ebp),%eax +c0106768: 8b 55 c4 mov -0x3c(%ebp),%edx +c010676b: 0f a3 10 bt %edx,(%eax) +c010676e: 19 c0 sbb %eax,%eax +c0106770: 89 45 bc mov %eax,-0x44(%ebp) + return oldbit != 0; +c0106773: 83 7d bc 00 cmpl $0x0,-0x44(%ebp) +c0106777: 0f 95 c0 setne %al +c010677a: 0f b6 c0 movzbl %al,%eax +c010677d: 85 c0 test %eax,%eax +c010677f: 75 24 jne c01067a5 +c0106781: c7 44 24 0c 76 a2 10 movl $0xc010a276,0xc(%esp) +c0106788: c0 +c0106789: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106790: c0 +c0106791: c7 44 24 04 bc 00 00 movl $0xbc,0x4(%esp) +c0106798: 00 +c0106799: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01067a0: e8 9d a4 ff ff call c0100c42 <__panic> + count ++, total += p->property; +c01067a5: ff 45 f4 incl -0xc(%ebp) +c01067a8: 8b 45 c8 mov -0x38(%ebp),%eax +c01067ab: 8b 50 08 mov 0x8(%eax),%edx +c01067ae: 8b 45 f0 mov -0x10(%ebp),%eax +c01067b1: 01 d0 add %edx,%eax +c01067b3: 89 45 f0 mov %eax,-0x10(%ebp) +c01067b6: 8b 45 e8 mov -0x18(%ebp),%eax +c01067b9: 89 45 b8 mov %eax,-0x48(%ebp) +c01067bc: 8b 45 b8 mov -0x48(%ebp),%eax +c01067bf: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c01067c2: 89 45 e8 mov %eax,-0x18(%ebp) +c01067c5: 81 7d e8 e4 5f 12 c0 cmpl $0xc0125fe4,-0x18(%ebp) +c01067cc: 0f 85 7a ff ff ff jne c010674c + } + assert(total == nr_free_pages()); +c01067d2: e8 72 e1 ff ff call c0104949 +c01067d7: 8b 55 f0 mov -0x10(%ebp),%edx +c01067da: 39 d0 cmp %edx,%eax +c01067dc: 74 24 je c0106802 +c01067de: c7 44 24 0c 86 a2 10 movl $0xc010a286,0xc(%esp) +c01067e5: c0 +c01067e6: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01067ed: c0 +c01067ee: c7 44 24 04 bf 00 00 movl $0xbf,0x4(%esp) +c01067f5: 00 +c01067f6: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01067fd: e8 40 a4 ff ff call c0100c42 <__panic> + cprintf("BEGIN check_swap: count %d, total %d\n",count,total); +c0106802: 8b 45 f0 mov -0x10(%ebp),%eax +c0106805: 89 44 24 08 mov %eax,0x8(%esp) +c0106809: 8b 45 f4 mov -0xc(%ebp),%eax +c010680c: 89 44 24 04 mov %eax,0x4(%esp) +c0106810: c7 04 24 a0 a2 10 c0 movl $0xc010a2a0,(%esp) +c0106817: e8 59 9b ff ff call c0100375 + + //now we set the phy pages env + struct mm_struct *mm = mm_create(); +c010681c: e8 31 0a 00 00 call c0107252 +c0106821: 89 45 e4 mov %eax,-0x1c(%ebp) + assert(mm != NULL); +c0106824: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0106828: 75 24 jne c010684e +c010682a: c7 44 24 0c c6 a2 10 movl $0xc010a2c6,0xc(%esp) +c0106831: c0 +c0106832: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106839: c0 +c010683a: c7 44 24 04 c4 00 00 movl $0xc4,0x4(%esp) +c0106841: 00 +c0106842: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106849: e8 f4 a3 ff ff call c0100c42 <__panic> + + extern struct mm_struct *check_mm_struct; + assert(check_mm_struct == NULL); +c010684e: a1 6c 61 12 c0 mov 0xc012616c,%eax +c0106853: 85 c0 test %eax,%eax +c0106855: 74 24 je c010687b +c0106857: c7 44 24 0c d1 a2 10 movl $0xc010a2d1,0xc(%esp) +c010685e: c0 +c010685f: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106866: c0 +c0106867: c7 44 24 04 c7 00 00 movl $0xc7,0x4(%esp) +c010686e: 00 +c010686f: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106876: e8 c7 a3 ff ff call c0100c42 <__panic> + + check_mm_struct = mm; +c010687b: 8b 45 e4 mov -0x1c(%ebp),%eax +c010687e: a3 6c 61 12 c0 mov %eax,0xc012616c + + pde_t *pgdir = mm->pgdir = boot_pgdir; +c0106883: 8b 15 e0 29 12 c0 mov 0xc01229e0,%edx +c0106889: 8b 45 e4 mov -0x1c(%ebp),%eax +c010688c: 89 50 0c mov %edx,0xc(%eax) +c010688f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106892: 8b 40 0c mov 0xc(%eax),%eax +c0106895: 89 45 e0 mov %eax,-0x20(%ebp) + assert(pgdir[0] == 0); +c0106898: 8b 45 e0 mov -0x20(%ebp),%eax +c010689b: 8b 00 mov (%eax),%eax +c010689d: 85 c0 test %eax,%eax +c010689f: 74 24 je c01068c5 +c01068a1: c7 44 24 0c e9 a2 10 movl $0xc010a2e9,0xc(%esp) +c01068a8: c0 +c01068a9: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01068b0: c0 +c01068b1: c7 44 24 04 cc 00 00 movl $0xcc,0x4(%esp) +c01068b8: 00 +c01068b9: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01068c0: e8 7d a3 ff ff call c0100c42 <__panic> + + struct vma_struct *vma = vma_create(BEING_CHECK_VALID_VADDR, CHECK_VALID_VADDR, VM_WRITE | VM_READ); +c01068c5: c7 44 24 08 03 00 00 movl $0x3,0x8(%esp) +c01068cc: 00 +c01068cd: c7 44 24 04 00 60 00 movl $0x6000,0x4(%esp) +c01068d4: 00 +c01068d5: c7 04 24 00 10 00 00 movl $0x1000,(%esp) +c01068dc: e8 ec 09 00 00 call c01072cd +c01068e1: 89 45 dc mov %eax,-0x24(%ebp) + assert(vma != NULL); +c01068e4: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c01068e8: 75 24 jne c010690e +c01068ea: c7 44 24 0c f7 a2 10 movl $0xc010a2f7,0xc(%esp) +c01068f1: c0 +c01068f2: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01068f9: c0 +c01068fa: c7 44 24 04 cf 00 00 movl $0xcf,0x4(%esp) +c0106901: 00 +c0106902: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106909: e8 34 a3 ff ff call c0100c42 <__panic> + + insert_vma_struct(mm, vma); +c010690e: 8b 45 dc mov -0x24(%ebp),%eax +c0106911: 89 44 24 04 mov %eax,0x4(%esp) +c0106915: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106918: 89 04 24 mov %eax,(%esp) +c010691b: e8 44 0b 00 00 call c0107464 + + //setup the temp Page Table vaddr 0~4MB + cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n"); +c0106920: c7 04 24 04 a3 10 c0 movl $0xc010a304,(%esp) +c0106927: e8 49 9a ff ff call c0100375 + pte_t *temp_ptep=NULL; +c010692c: c7 45 d8 00 00 00 00 movl $0x0,-0x28(%ebp) + temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1); +c0106933: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106936: 8b 40 0c mov 0xc(%eax),%eax +c0106939: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c0106940: 00 +c0106941: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0106948: 00 +c0106949: 89 04 24 mov %eax,(%esp) +c010694c: e8 0c e6 ff ff call c0104f5d +c0106951: 89 45 d8 mov %eax,-0x28(%ebp) + assert(temp_ptep!= NULL); +c0106954: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c0106958: 75 24 jne c010697e +c010695a: c7 44 24 0c 38 a3 10 movl $0xc010a338,0xc(%esp) +c0106961: c0 +c0106962: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106969: c0 +c010696a: c7 44 24 04 d7 00 00 movl $0xd7,0x4(%esp) +c0106971: 00 +c0106972: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106979: e8 c4 a2 ff ff call c0100c42 <__panic> + cprintf("setup Page Table vaddr 0~4MB OVER!\n"); +c010697e: c7 04 24 4c a3 10 c0 movl $0xc010a34c,(%esp) +c0106985: e8 eb 99 ff ff call c0100375 + + for (i=0;i + check_rp[i] = alloc_page(); +c0106996: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010699d: e8 05 df ff ff call c01048a7 +c01069a2: 8b 55 ec mov -0x14(%ebp),%edx +c01069a5: 89 04 95 2c 61 12 c0 mov %eax,-0x3fed9ed4(,%edx,4) + assert(check_rp[i] != NULL ); +c01069ac: 8b 45 ec mov -0x14(%ebp),%eax +c01069af: 8b 04 85 2c 61 12 c0 mov -0x3fed9ed4(,%eax,4),%eax +c01069b6: 85 c0 test %eax,%eax +c01069b8: 75 24 jne c01069de +c01069ba: c7 44 24 0c 70 a3 10 movl $0xc010a370,0xc(%esp) +c01069c1: c0 +c01069c2: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c01069c9: c0 +c01069ca: c7 44 24 04 dc 00 00 movl $0xdc,0x4(%esp) +c01069d1: 00 +c01069d2: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c01069d9: e8 64 a2 ff ff call c0100c42 <__panic> + assert(!PageProperty(check_rp[i])); +c01069de: 8b 45 ec mov -0x14(%ebp),%eax +c01069e1: 8b 04 85 2c 61 12 c0 mov -0x3fed9ed4(,%eax,4),%eax +c01069e8: 83 c0 04 add $0x4,%eax +c01069eb: c7 45 b4 01 00 00 00 movl $0x1,-0x4c(%ebp) +c01069f2: 89 45 b0 mov %eax,-0x50(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01069f5: 8b 45 b0 mov -0x50(%ebp),%eax +c01069f8: 8b 55 b4 mov -0x4c(%ebp),%edx +c01069fb: 0f a3 10 bt %edx,(%eax) +c01069fe: 19 c0 sbb %eax,%eax +c0106a00: 89 45 ac mov %eax,-0x54(%ebp) + return oldbit != 0; +c0106a03: 83 7d ac 00 cmpl $0x0,-0x54(%ebp) +c0106a07: 0f 95 c0 setne %al +c0106a0a: 0f b6 c0 movzbl %al,%eax +c0106a0d: 85 c0 test %eax,%eax +c0106a0f: 74 24 je c0106a35 +c0106a11: c7 44 24 0c 84 a3 10 movl $0xc010a384,0xc(%esp) +c0106a18: c0 +c0106a19: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106a20: c0 +c0106a21: c7 44 24 04 dd 00 00 movl $0xdd,0x4(%esp) +c0106a28: 00 +c0106a29: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106a30: e8 0d a2 ff ff call c0100c42 <__panic> + for (i=0;i + } + list_entry_t free_list_store = free_list; +c0106a42: a1 e4 5f 12 c0 mov 0xc0125fe4,%eax +c0106a47: 8b 15 e8 5f 12 c0 mov 0xc0125fe8,%edx +c0106a4d: 89 45 98 mov %eax,-0x68(%ebp) +c0106a50: 89 55 9c mov %edx,-0x64(%ebp) +c0106a53: c7 45 a4 e4 5f 12 c0 movl $0xc0125fe4,-0x5c(%ebp) + elm->prev = elm->next = elm; +c0106a5a: 8b 45 a4 mov -0x5c(%ebp),%eax +c0106a5d: 8b 55 a4 mov -0x5c(%ebp),%edx +c0106a60: 89 50 04 mov %edx,0x4(%eax) +c0106a63: 8b 45 a4 mov -0x5c(%ebp),%eax +c0106a66: 8b 50 04 mov 0x4(%eax),%edx +c0106a69: 8b 45 a4 mov -0x5c(%ebp),%eax +c0106a6c: 89 10 mov %edx,(%eax) +} +c0106a6e: 90 nop +c0106a6f: c7 45 a8 e4 5f 12 c0 movl $0xc0125fe4,-0x58(%ebp) + return list->next == list; +c0106a76: 8b 45 a8 mov -0x58(%ebp),%eax +c0106a79: 8b 40 04 mov 0x4(%eax),%eax +c0106a7c: 39 45 a8 cmp %eax,-0x58(%ebp) +c0106a7f: 0f 94 c0 sete %al +c0106a82: 0f b6 c0 movzbl %al,%eax + list_init(&free_list); + assert(list_empty(&free_list)); +c0106a85: 85 c0 test %eax,%eax +c0106a87: 75 24 jne c0106aad +c0106a89: c7 44 24 0c 9f a3 10 movl $0xc010a39f,0xc(%esp) +c0106a90: c0 +c0106a91: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106a98: c0 +c0106a99: c7 44 24 04 e1 00 00 movl $0xe1,0x4(%esp) +c0106aa0: 00 +c0106aa1: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106aa8: e8 95 a1 ff ff call c0100c42 <__panic> + + //assert(alloc_page() == NULL); + + unsigned int nr_free_store = nr_free; +c0106aad: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c0106ab2: 89 45 d4 mov %eax,-0x2c(%ebp) + nr_free = 0; +c0106ab5: c7 05 ec 5f 12 c0 00 movl $0x0,0xc0125fec +c0106abc: 00 00 00 + for (i=0;i + free_pages(check_rp[i],1); +c0106ac8: 8b 45 ec mov -0x14(%ebp),%eax +c0106acb: 8b 04 85 2c 61 12 c0 mov -0x3fed9ed4(,%eax,4),%eax +c0106ad2: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0106ad9: 00 +c0106ada: 89 04 24 mov %eax,(%esp) +c0106add: e8 32 de ff ff call c0104914 + for (i=0;i + } + assert(nr_free==CHECK_VALID_PHY_PAGE_NUM); +c0106aeb: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c0106af0: 83 f8 04 cmp $0x4,%eax +c0106af3: 74 24 je c0106b19 +c0106af5: c7 44 24 0c b8 a3 10 movl $0xc010a3b8,0xc(%esp) +c0106afc: c0 +c0106afd: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106b04: c0 +c0106b05: c7 44 24 04 ea 00 00 movl $0xea,0x4(%esp) +c0106b0c: 00 +c0106b0d: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106b14: e8 29 a1 ff ff call c0100c42 <__panic> + + cprintf("set up init env for check_swap begin!\n"); +c0106b19: c7 04 24 dc a3 10 c0 movl $0xc010a3dc,(%esp) +c0106b20: e8 50 98 ff ff call c0100375 + //setup initial vir_page<->phy_page environment for page relpacement algorithm + + + pgfault_num=0; +c0106b25: c7 05 70 61 12 c0 00 movl $0x0,0xc0126170 +c0106b2c: 00 00 00 + + check_content_set(); +c0106b2f: e8 26 fa ff ff call c010655a + assert( nr_free == 0); +c0106b34: a1 ec 5f 12 c0 mov 0xc0125fec,%eax +c0106b39: 85 c0 test %eax,%eax +c0106b3b: 74 24 je c0106b61 +c0106b3d: c7 44 24 0c 03 a4 10 movl $0xc010a403,0xc(%esp) +c0106b44: c0 +c0106b45: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106b4c: c0 +c0106b4d: c7 44 24 04 f3 00 00 movl $0xf3,0x4(%esp) +c0106b54: 00 +c0106b55: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106b5c: e8 e1 a0 ff ff call c0100c42 <__panic> + for(i = 0; i + swap_out_seq_no[i]=swap_in_seq_no[i]=-1; +c0106b6a: 8b 45 ec mov -0x14(%ebp),%eax +c0106b6d: c7 04 85 c0 60 12 c0 movl $0xffffffff,-0x3fed9f40(,%eax,4) +c0106b74: ff ff ff ff +c0106b78: 8b 45 ec mov -0x14(%ebp),%eax +c0106b7b: 8b 14 85 c0 60 12 c0 mov -0x3fed9f40(,%eax,4),%edx +c0106b82: 8b 45 ec mov -0x14(%ebp),%eax +c0106b85: 89 14 85 00 61 12 c0 mov %edx,-0x3fed9f00(,%eax,4) + for(i = 0; i + + for (i= 0;i + check_ptep[i]=0; +c0106ba1: 8b 45 ec mov -0x14(%ebp),%eax +c0106ba4: c7 04 85 3c 61 12 c0 movl $0x0,-0x3fed9ec4(,%eax,4) +c0106bab: 00 00 00 00 + check_ptep[i] = get_pte(pgdir, (i+1)*0x1000, 0); +c0106baf: 8b 45 ec mov -0x14(%ebp),%eax +c0106bb2: 40 inc %eax +c0106bb3: c1 e0 0c shl $0xc,%eax +c0106bb6: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0106bbd: 00 +c0106bbe: 89 44 24 04 mov %eax,0x4(%esp) +c0106bc2: 8b 45 e0 mov -0x20(%ebp),%eax +c0106bc5: 89 04 24 mov %eax,(%esp) +c0106bc8: e8 90 e3 ff ff call c0104f5d +c0106bcd: 8b 55 ec mov -0x14(%ebp),%edx +c0106bd0: 89 04 95 3c 61 12 c0 mov %eax,-0x3fed9ec4(,%edx,4) + //cprintf("i %d, check_ptep addr %x, value %x\n", i, check_ptep[i], *check_ptep[i]); + assert(check_ptep[i] != NULL); +c0106bd7: 8b 45 ec mov -0x14(%ebp),%eax +c0106bda: 8b 04 85 3c 61 12 c0 mov -0x3fed9ec4(,%eax,4),%eax +c0106be1: 85 c0 test %eax,%eax +c0106be3: 75 24 jne c0106c09 +c0106be5: c7 44 24 0c 10 a4 10 movl $0xc010a410,0xc(%esp) +c0106bec: c0 +c0106bed: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106bf4: c0 +c0106bf5: c7 44 24 04 fb 00 00 movl $0xfb,0x4(%esp) +c0106bfc: 00 +c0106bfd: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106c04: e8 39 a0 ff ff call c0100c42 <__panic> + assert(pte2page(*check_ptep[i]) == check_rp[i]); +c0106c09: 8b 45 ec mov -0x14(%ebp),%eax +c0106c0c: 8b 04 85 3c 61 12 c0 mov -0x3fed9ec4(,%eax,4),%eax +c0106c13: 8b 00 mov (%eax),%eax +c0106c15: 89 04 24 mov %eax,(%esp) +c0106c18: e8 97 f5 ff ff call c01061b4 +c0106c1d: 8b 55 ec mov -0x14(%ebp),%edx +c0106c20: 8b 14 95 2c 61 12 c0 mov -0x3fed9ed4(,%edx,4),%edx +c0106c27: 39 d0 cmp %edx,%eax +c0106c29: 74 24 je c0106c4f +c0106c2b: c7 44 24 0c 28 a4 10 movl $0xc010a428,0xc(%esp) +c0106c32: c0 +c0106c33: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106c3a: c0 +c0106c3b: c7 44 24 04 fc 00 00 movl $0xfc,0x4(%esp) +c0106c42: 00 +c0106c43: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106c4a: e8 f3 9f ff ff call c0100c42 <__panic> + assert((*check_ptep[i] & PTE_P)); +c0106c4f: 8b 45 ec mov -0x14(%ebp),%eax +c0106c52: 8b 04 85 3c 61 12 c0 mov -0x3fed9ec4(,%eax,4),%eax +c0106c59: 8b 00 mov (%eax),%eax +c0106c5b: 83 e0 01 and $0x1,%eax +c0106c5e: 85 c0 test %eax,%eax +c0106c60: 75 24 jne c0106c86 +c0106c62: c7 44 24 0c 50 a4 10 movl $0xc010a450,0xc(%esp) +c0106c69: c0 +c0106c6a: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106c71: c0 +c0106c72: c7 44 24 04 fd 00 00 movl $0xfd,0x4(%esp) +c0106c79: 00 +c0106c7a: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106c81: e8 bc 9f ff ff call c0100c42 <__panic> + for (i= 0;i + } + cprintf("set up init env for check_swap over!\n"); +c0106c93: c7 04 24 6c a4 10 c0 movl $0xc010a46c,(%esp) +c0106c9a: e8 d6 96 ff ff call c0100375 + // now access the virt pages to test page relpacement algorithm + ret=check_content_access(); +c0106c9f: e8 71 fa ff ff call c0106715 +c0106ca4: 89 45 d0 mov %eax,-0x30(%ebp) + assert(ret==0); +c0106ca7: 83 7d d0 00 cmpl $0x0,-0x30(%ebp) +c0106cab: 74 24 je c0106cd1 +c0106cad: c7 44 24 0c 92 a4 10 movl $0xc010a492,0xc(%esp) +c0106cb4: c0 +c0106cb5: c7 44 24 08 7a a1 10 movl $0xc010a17a,0x8(%esp) +c0106cbc: c0 +c0106cbd: c7 44 24 04 02 01 00 movl $0x102,0x4(%esp) +c0106cc4: 00 +c0106cc5: c7 04 24 14 a1 10 c0 movl $0xc010a114,(%esp) +c0106ccc: e8 71 9f ff ff call c0100c42 <__panic> + + //restore kernel mem env + for (i=0;i + free_pages(check_rp[i],1); +c0106cda: 8b 45 ec mov -0x14(%ebp),%eax +c0106cdd: 8b 04 85 2c 61 12 c0 mov -0x3fed9ed4(,%eax,4),%eax +c0106ce4: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0106ceb: 00 +c0106cec: 89 04 24 mov %eax,(%esp) +c0106cef: e8 20 dc ff ff call c0104914 + for (i=0;i + } + + //free_page(pte2page(*temp_ptep)); + + mm_destroy(mm); +c0106cfd: 8b 45 e4 mov -0x1c(%ebp),%eax +c0106d00: 89 04 24 mov %eax,(%esp) +c0106d03: e8 92 08 00 00 call c010759a + + nr_free = nr_free_store; +c0106d08: 8b 45 d4 mov -0x2c(%ebp),%eax +c0106d0b: a3 ec 5f 12 c0 mov %eax,0xc0125fec + free_list = free_list_store; +c0106d10: 8b 45 98 mov -0x68(%ebp),%eax +c0106d13: 8b 55 9c mov -0x64(%ebp),%edx +c0106d16: a3 e4 5f 12 c0 mov %eax,0xc0125fe4 +c0106d1b: 89 15 e8 5f 12 c0 mov %edx,0xc0125fe8 + + + le = &free_list; +c0106d21: c7 45 e8 e4 5f 12 c0 movl $0xc0125fe4,-0x18(%ebp) + while ((le = list_next(le)) != &free_list) { +c0106d28: eb 1c jmp c0106d46 + struct Page *p = le2page(le, page_link); +c0106d2a: 8b 45 e8 mov -0x18(%ebp),%eax +c0106d2d: 83 e8 0c sub $0xc,%eax +c0106d30: 89 45 cc mov %eax,-0x34(%ebp) + count --, total -= p->property; +c0106d33: ff 4d f4 decl -0xc(%ebp) +c0106d36: 8b 55 f0 mov -0x10(%ebp),%edx +c0106d39: 8b 45 cc mov -0x34(%ebp),%eax +c0106d3c: 8b 48 08 mov 0x8(%eax),%ecx +c0106d3f: 89 d0 mov %edx,%eax +c0106d41: 29 c8 sub %ecx,%eax +c0106d43: 89 45 f0 mov %eax,-0x10(%ebp) +c0106d46: 8b 45 e8 mov -0x18(%ebp),%eax +c0106d49: 89 45 a0 mov %eax,-0x60(%ebp) + return listelm->next; +c0106d4c: 8b 45 a0 mov -0x60(%ebp),%eax +c0106d4f: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0106d52: 89 45 e8 mov %eax,-0x18(%ebp) +c0106d55: 81 7d e8 e4 5f 12 c0 cmpl $0xc0125fe4,-0x18(%ebp) +c0106d5c: 75 cc jne c0106d2a + } + cprintf("count is %d, total is %d\n",count,total); +c0106d5e: 8b 45 f0 mov -0x10(%ebp),%eax +c0106d61: 89 44 24 08 mov %eax,0x8(%esp) +c0106d65: 8b 45 f4 mov -0xc(%ebp),%eax +c0106d68: 89 44 24 04 mov %eax,0x4(%esp) +c0106d6c: c7 04 24 99 a4 10 c0 movl $0xc010a499,(%esp) +c0106d73: e8 fd 95 ff ff call c0100375 + //assert(count == 0); + + cprintf("check_swap() succeeded!\n"); +c0106d78: c7 04 24 b3 a4 10 c0 movl $0xc010a4b3,(%esp) +c0106d7f: e8 f1 95 ff ff call c0100375 +} +c0106d84: 90 nop +c0106d85: 89 ec mov %ebp,%esp +c0106d87: 5d pop %ebp +c0106d88: c3 ret + +c0106d89 <_fifo_init_mm>: + * (2) _fifo_init_mm: init pra_list_head and let mm->sm_priv point to the addr of pra_list_head. + * Now, From the memory control struct mm_struct, we can access FIFO PRA + */ +static int +_fifo_init_mm(struct mm_struct *mm) +{ +c0106d89: 55 push %ebp +c0106d8a: 89 e5 mov %esp,%ebp +c0106d8c: 83 ec 10 sub $0x10,%esp +c0106d8f: c7 45 fc 64 61 12 c0 movl $0xc0126164,-0x4(%ebp) + elm->prev = elm->next = elm; +c0106d96: 8b 45 fc mov -0x4(%ebp),%eax +c0106d99: 8b 55 fc mov -0x4(%ebp),%edx +c0106d9c: 89 50 04 mov %edx,0x4(%eax) +c0106d9f: 8b 45 fc mov -0x4(%ebp),%eax +c0106da2: 8b 50 04 mov 0x4(%eax),%edx +c0106da5: 8b 45 fc mov -0x4(%ebp),%eax +c0106da8: 89 10 mov %edx,(%eax) +} +c0106daa: 90 nop + list_init(&pra_list_head); + mm->sm_priv = &pra_list_head; +c0106dab: 8b 45 08 mov 0x8(%ebp),%eax +c0106dae: c7 40 14 64 61 12 c0 movl $0xc0126164,0x14(%eax) + //cprintf(" mm->sm_priv %x in fifo_init_mm\n",mm->sm_priv); + return 0; +c0106db5: b8 00 00 00 00 mov $0x0,%eax +} +c0106dba: 89 ec mov %ebp,%esp +c0106dbc: 5d pop %ebp +c0106dbd: c3 ret + +c0106dbe <_fifo_map_swappable>: +/* + * (3)_fifo_map_swappable: According FIFO PRA, we should link the most recent arrival page at the back of pra_list_head qeueue + */ +static int +_fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in) +{ +c0106dbe: 55 push %ebp +c0106dbf: 89 e5 mov %esp,%ebp +c0106dc1: 83 ec 28 sub $0x28,%esp + list_entry_t *head=(list_entry_t*) mm->sm_priv; +c0106dc4: 8b 45 08 mov 0x8(%ebp),%eax +c0106dc7: 8b 40 14 mov 0x14(%eax),%eax +c0106dca: 89 45 f4 mov %eax,-0xc(%ebp) + list_entry_t *entry=&(page->pra_page_link); +c0106dcd: 8b 45 10 mov 0x10(%ebp),%eax +c0106dd0: 83 c0 14 add $0x14,%eax +c0106dd3: 89 45 f0 mov %eax,-0x10(%ebp) + + assert(entry != NULL && head != NULL); +c0106dd6: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0106dda: 74 06 je c0106de2 <_fifo_map_swappable+0x24> +c0106ddc: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0106de0: 75 24 jne c0106e06 <_fifo_map_swappable+0x48> +c0106de2: c7 44 24 0c cc a4 10 movl $0xc010a4cc,0xc(%esp) +c0106de9: c0 +c0106dea: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106df1: c0 +c0106df2: c7 44 24 04 32 00 00 movl $0x32,0x4(%esp) +c0106df9: 00 +c0106dfa: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106e01: e8 3c 9e ff ff call c0100c42 <__panic> + //record the page access situlation + /*LAB3 EXERCISE 2: YOUR CODE*/ + //(1)link the most recent arrival page at the back of the pra_list_head qeueue. + return 0; +c0106e06: b8 00 00 00 00 mov $0x0,%eax +} +c0106e0b: 89 ec mov %ebp,%esp +c0106e0d: 5d pop %ebp +c0106e0e: c3 ret + +c0106e0f <_fifo_swap_out_victim>: + * (4)_fifo_swap_out_victim: According FIFO PRA, we should unlink the earliest arrival page in front of pra_list_head qeueue, + * then assign the value of *ptr_page to the addr of this page. + */ +static int +_fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick) +{ +c0106e0f: 55 push %ebp +c0106e10: 89 e5 mov %esp,%ebp +c0106e12: 83 ec 28 sub $0x28,%esp + list_entry_t *head=(list_entry_t*) mm->sm_priv; +c0106e15: 8b 45 08 mov 0x8(%ebp),%eax +c0106e18: 8b 40 14 mov 0x14(%eax),%eax +c0106e1b: 89 45 f4 mov %eax,-0xc(%ebp) + assert(head != NULL); +c0106e1e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0106e22: 75 24 jne c0106e48 <_fifo_swap_out_victim+0x39> +c0106e24: c7 44 24 0c 13 a5 10 movl $0xc010a513,0xc(%esp) +c0106e2b: c0 +c0106e2c: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106e33: c0 +c0106e34: c7 44 24 04 40 00 00 movl $0x40,0x4(%esp) +c0106e3b: 00 +c0106e3c: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106e43: e8 fa 9d ff ff call c0100c42 <__panic> + assert(in_tick==0); +c0106e48: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0106e4c: 74 24 je c0106e72 <_fifo_swap_out_victim+0x63> +c0106e4e: c7 44 24 0c 20 a5 10 movl $0xc010a520,0xc(%esp) +c0106e55: c0 +c0106e56: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106e5d: c0 +c0106e5e: c7 44 24 04 41 00 00 movl $0x41,0x4(%esp) +c0106e65: 00 +c0106e66: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106e6d: e8 d0 9d ff ff call c0100c42 <__panic> + /* Select the victim */ + /*LAB3 EXERCISE 2: YOUR CODE*/ + //(1) unlink the earliest arrival page in front of pra_list_head qeueue + //(2) assign the value of *ptr_page to the addr of this page + return 0; +c0106e72: b8 00 00 00 00 mov $0x0,%eax +} +c0106e77: 89 ec mov %ebp,%esp +c0106e79: 5d pop %ebp +c0106e7a: c3 ret + +c0106e7b <_fifo_check_swap>: + +static int +_fifo_check_swap(void) { +c0106e7b: 55 push %ebp +c0106e7c: 89 e5 mov %esp,%ebp +c0106e7e: 83 ec 18 sub $0x18,%esp + cprintf("write Virt Page c in fifo_check_swap\n"); +c0106e81: c7 04 24 2c a5 10 c0 movl $0xc010a52c,(%esp) +c0106e88: e8 e8 94 ff ff call c0100375 + *(unsigned char *)0x3000 = 0x0c; +c0106e8d: b8 00 30 00 00 mov $0x3000,%eax +c0106e92: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==4); +c0106e95: a1 70 61 12 c0 mov 0xc0126170,%eax +c0106e9a: 83 f8 04 cmp $0x4,%eax +c0106e9d: 74 24 je c0106ec3 <_fifo_check_swap+0x48> +c0106e9f: c7 44 24 0c 52 a5 10 movl $0xc010a552,0xc(%esp) +c0106ea6: c0 +c0106ea7: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106eae: c0 +c0106eaf: c7 44 24 04 4d 00 00 movl $0x4d,0x4(%esp) +c0106eb6: 00 +c0106eb7: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106ebe: e8 7f 9d ff ff call c0100c42 <__panic> + cprintf("write Virt Page a in fifo_check_swap\n"); +c0106ec3: c7 04 24 64 a5 10 c0 movl $0xc010a564,(%esp) +c0106eca: e8 a6 94 ff ff call c0100375 + *(unsigned char *)0x1000 = 0x0a; +c0106ecf: b8 00 10 00 00 mov $0x1000,%eax +c0106ed4: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==4); +c0106ed7: a1 70 61 12 c0 mov 0xc0126170,%eax +c0106edc: 83 f8 04 cmp $0x4,%eax +c0106edf: 74 24 je c0106f05 <_fifo_check_swap+0x8a> +c0106ee1: c7 44 24 0c 52 a5 10 movl $0xc010a552,0xc(%esp) +c0106ee8: c0 +c0106ee9: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106ef0: c0 +c0106ef1: c7 44 24 04 50 00 00 movl $0x50,0x4(%esp) +c0106ef8: 00 +c0106ef9: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106f00: e8 3d 9d ff ff call c0100c42 <__panic> + cprintf("write Virt Page d in fifo_check_swap\n"); +c0106f05: c7 04 24 8c a5 10 c0 movl $0xc010a58c,(%esp) +c0106f0c: e8 64 94 ff ff call c0100375 + *(unsigned char *)0x4000 = 0x0d; +c0106f11: b8 00 40 00 00 mov $0x4000,%eax +c0106f16: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==4); +c0106f19: a1 70 61 12 c0 mov 0xc0126170,%eax +c0106f1e: 83 f8 04 cmp $0x4,%eax +c0106f21: 74 24 je c0106f47 <_fifo_check_swap+0xcc> +c0106f23: c7 44 24 0c 52 a5 10 movl $0xc010a552,0xc(%esp) +c0106f2a: c0 +c0106f2b: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106f32: c0 +c0106f33: c7 44 24 04 53 00 00 movl $0x53,0x4(%esp) +c0106f3a: 00 +c0106f3b: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106f42: e8 fb 9c ff ff call c0100c42 <__panic> + cprintf("write Virt Page b in fifo_check_swap\n"); +c0106f47: c7 04 24 b4 a5 10 c0 movl $0xc010a5b4,(%esp) +c0106f4e: e8 22 94 ff ff call c0100375 + *(unsigned char *)0x2000 = 0x0b; +c0106f53: b8 00 20 00 00 mov $0x2000,%eax +c0106f58: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==4); +c0106f5b: a1 70 61 12 c0 mov 0xc0126170,%eax +c0106f60: 83 f8 04 cmp $0x4,%eax +c0106f63: 74 24 je c0106f89 <_fifo_check_swap+0x10e> +c0106f65: c7 44 24 0c 52 a5 10 movl $0xc010a552,0xc(%esp) +c0106f6c: c0 +c0106f6d: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106f74: c0 +c0106f75: c7 44 24 04 56 00 00 movl $0x56,0x4(%esp) +c0106f7c: 00 +c0106f7d: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106f84: e8 b9 9c ff ff call c0100c42 <__panic> + cprintf("write Virt Page e in fifo_check_swap\n"); +c0106f89: c7 04 24 dc a5 10 c0 movl $0xc010a5dc,(%esp) +c0106f90: e8 e0 93 ff ff call c0100375 + *(unsigned char *)0x5000 = 0x0e; +c0106f95: b8 00 50 00 00 mov $0x5000,%eax +c0106f9a: c6 00 0e movb $0xe,(%eax) + assert(pgfault_num==5); +c0106f9d: a1 70 61 12 c0 mov 0xc0126170,%eax +c0106fa2: 83 f8 05 cmp $0x5,%eax +c0106fa5: 74 24 je c0106fcb <_fifo_check_swap+0x150> +c0106fa7: c7 44 24 0c 02 a6 10 movl $0xc010a602,0xc(%esp) +c0106fae: c0 +c0106faf: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106fb6: c0 +c0106fb7: c7 44 24 04 59 00 00 movl $0x59,0x4(%esp) +c0106fbe: 00 +c0106fbf: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0106fc6: e8 77 9c ff ff call c0100c42 <__panic> + cprintf("write Virt Page b in fifo_check_swap\n"); +c0106fcb: c7 04 24 b4 a5 10 c0 movl $0xc010a5b4,(%esp) +c0106fd2: e8 9e 93 ff ff call c0100375 + *(unsigned char *)0x2000 = 0x0b; +c0106fd7: b8 00 20 00 00 mov $0x2000,%eax +c0106fdc: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==5); +c0106fdf: a1 70 61 12 c0 mov 0xc0126170,%eax +c0106fe4: 83 f8 05 cmp $0x5,%eax +c0106fe7: 74 24 je c010700d <_fifo_check_swap+0x192> +c0106fe9: c7 44 24 0c 02 a6 10 movl $0xc010a602,0xc(%esp) +c0106ff0: c0 +c0106ff1: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0106ff8: c0 +c0106ff9: c7 44 24 04 5c 00 00 movl $0x5c,0x4(%esp) +c0107000: 00 +c0107001: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0107008: e8 35 9c ff ff call c0100c42 <__panic> + cprintf("write Virt Page a in fifo_check_swap\n"); +c010700d: c7 04 24 64 a5 10 c0 movl $0xc010a564,(%esp) +c0107014: e8 5c 93 ff ff call c0100375 + *(unsigned char *)0x1000 = 0x0a; +c0107019: b8 00 10 00 00 mov $0x1000,%eax +c010701e: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==6); +c0107021: a1 70 61 12 c0 mov 0xc0126170,%eax +c0107026: 83 f8 06 cmp $0x6,%eax +c0107029: 74 24 je c010704f <_fifo_check_swap+0x1d4> +c010702b: c7 44 24 0c 11 a6 10 movl $0xc010a611,0xc(%esp) +c0107032: c0 +c0107033: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c010703a: c0 +c010703b: c7 44 24 04 5f 00 00 movl $0x5f,0x4(%esp) +c0107042: 00 +c0107043: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c010704a: e8 f3 9b ff ff call c0100c42 <__panic> + cprintf("write Virt Page b in fifo_check_swap\n"); +c010704f: c7 04 24 b4 a5 10 c0 movl $0xc010a5b4,(%esp) +c0107056: e8 1a 93 ff ff call c0100375 + *(unsigned char *)0x2000 = 0x0b; +c010705b: b8 00 20 00 00 mov $0x2000,%eax +c0107060: c6 00 0b movb $0xb,(%eax) + assert(pgfault_num==7); +c0107063: a1 70 61 12 c0 mov 0xc0126170,%eax +c0107068: 83 f8 07 cmp $0x7,%eax +c010706b: 74 24 je c0107091 <_fifo_check_swap+0x216> +c010706d: c7 44 24 0c 20 a6 10 movl $0xc010a620,0xc(%esp) +c0107074: c0 +c0107075: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c010707c: c0 +c010707d: c7 44 24 04 62 00 00 movl $0x62,0x4(%esp) +c0107084: 00 +c0107085: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c010708c: e8 b1 9b ff ff call c0100c42 <__panic> + cprintf("write Virt Page c in fifo_check_swap\n"); +c0107091: c7 04 24 2c a5 10 c0 movl $0xc010a52c,(%esp) +c0107098: e8 d8 92 ff ff call c0100375 + *(unsigned char *)0x3000 = 0x0c; +c010709d: b8 00 30 00 00 mov $0x3000,%eax +c01070a2: c6 00 0c movb $0xc,(%eax) + assert(pgfault_num==8); +c01070a5: a1 70 61 12 c0 mov 0xc0126170,%eax +c01070aa: 83 f8 08 cmp $0x8,%eax +c01070ad: 74 24 je c01070d3 <_fifo_check_swap+0x258> +c01070af: c7 44 24 0c 2f a6 10 movl $0xc010a62f,0xc(%esp) +c01070b6: c0 +c01070b7: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c01070be: c0 +c01070bf: c7 44 24 04 65 00 00 movl $0x65,0x4(%esp) +c01070c6: 00 +c01070c7: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c01070ce: e8 6f 9b ff ff call c0100c42 <__panic> + cprintf("write Virt Page d in fifo_check_swap\n"); +c01070d3: c7 04 24 8c a5 10 c0 movl $0xc010a58c,(%esp) +c01070da: e8 96 92 ff ff call c0100375 + *(unsigned char *)0x4000 = 0x0d; +c01070df: b8 00 40 00 00 mov $0x4000,%eax +c01070e4: c6 00 0d movb $0xd,(%eax) + assert(pgfault_num==9); +c01070e7: a1 70 61 12 c0 mov 0xc0126170,%eax +c01070ec: 83 f8 09 cmp $0x9,%eax +c01070ef: 74 24 je c0107115 <_fifo_check_swap+0x29a> +c01070f1: c7 44 24 0c 3e a6 10 movl $0xc010a63e,0xc(%esp) +c01070f8: c0 +c01070f9: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0107100: c0 +c0107101: c7 44 24 04 68 00 00 movl $0x68,0x4(%esp) +c0107108: 00 +c0107109: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0107110: e8 2d 9b ff ff call c0100c42 <__panic> + cprintf("write Virt Page e in fifo_check_swap\n"); +c0107115: c7 04 24 dc a5 10 c0 movl $0xc010a5dc,(%esp) +c010711c: e8 54 92 ff ff call c0100375 + *(unsigned char *)0x5000 = 0x0e; +c0107121: b8 00 50 00 00 mov $0x5000,%eax +c0107126: c6 00 0e movb $0xe,(%eax) + assert(pgfault_num==10); +c0107129: a1 70 61 12 c0 mov 0xc0126170,%eax +c010712e: 83 f8 0a cmp $0xa,%eax +c0107131: 74 24 je c0107157 <_fifo_check_swap+0x2dc> +c0107133: c7 44 24 0c 4d a6 10 movl $0xc010a64d,0xc(%esp) +c010713a: c0 +c010713b: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c0107142: c0 +c0107143: c7 44 24 04 6b 00 00 movl $0x6b,0x4(%esp) +c010714a: 00 +c010714b: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c0107152: e8 eb 9a ff ff call c0100c42 <__panic> + cprintf("write Virt Page a in fifo_check_swap\n"); +c0107157: c7 04 24 64 a5 10 c0 movl $0xc010a564,(%esp) +c010715e: e8 12 92 ff ff call c0100375 + assert(*(unsigned char *)0x1000 == 0x0a); +c0107163: b8 00 10 00 00 mov $0x1000,%eax +c0107168: 0f b6 00 movzbl (%eax),%eax +c010716b: 3c 0a cmp $0xa,%al +c010716d: 74 24 je c0107193 <_fifo_check_swap+0x318> +c010716f: c7 44 24 0c 60 a6 10 movl $0xc010a660,0xc(%esp) +c0107176: c0 +c0107177: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c010717e: c0 +c010717f: c7 44 24 04 6d 00 00 movl $0x6d,0x4(%esp) +c0107186: 00 +c0107187: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c010718e: e8 af 9a ff ff call c0100c42 <__panic> + *(unsigned char *)0x1000 = 0x0a; +c0107193: b8 00 10 00 00 mov $0x1000,%eax +c0107198: c6 00 0a movb $0xa,(%eax) + assert(pgfault_num==11); +c010719b: a1 70 61 12 c0 mov 0xc0126170,%eax +c01071a0: 83 f8 0b cmp $0xb,%eax +c01071a3: 74 24 je c01071c9 <_fifo_check_swap+0x34e> +c01071a5: c7 44 24 0c 81 a6 10 movl $0xc010a681,0xc(%esp) +c01071ac: c0 +c01071ad: c7 44 24 08 ea a4 10 movl $0xc010a4ea,0x8(%esp) +c01071b4: c0 +c01071b5: c7 44 24 04 6f 00 00 movl $0x6f,0x4(%esp) +c01071bc: 00 +c01071bd: c7 04 24 ff a4 10 c0 movl $0xc010a4ff,(%esp) +c01071c4: e8 79 9a ff ff call c0100c42 <__panic> + return 0; +c01071c9: b8 00 00 00 00 mov $0x0,%eax +} +c01071ce: 89 ec mov %ebp,%esp +c01071d0: 5d pop %ebp +c01071d1: c3 ret + +c01071d2 <_fifo_init>: + + +static int +_fifo_init(void) +{ +c01071d2: 55 push %ebp +c01071d3: 89 e5 mov %esp,%ebp + return 0; +c01071d5: b8 00 00 00 00 mov $0x0,%eax +} +c01071da: 5d pop %ebp +c01071db: c3 ret + +c01071dc <_fifo_set_unswappable>: + +static int +_fifo_set_unswappable(struct mm_struct *mm, uintptr_t addr) +{ +c01071dc: 55 push %ebp +c01071dd: 89 e5 mov %esp,%ebp + return 0; +c01071df: b8 00 00 00 00 mov $0x0,%eax +} +c01071e4: 5d pop %ebp +c01071e5: c3 ret + +c01071e6 <_fifo_tick_event>: + +static int +_fifo_tick_event(struct mm_struct *mm) +{ return 0; } +c01071e6: 55 push %ebp +c01071e7: 89 e5 mov %esp,%ebp +c01071e9: b8 00 00 00 00 mov $0x0,%eax +c01071ee: 5d pop %ebp +c01071ef: c3 ret + +c01071f0 : +pa2page(uintptr_t pa) { +c01071f0: 55 push %ebp +c01071f1: 89 e5 mov %esp,%ebp +c01071f3: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c01071f6: 8b 45 08 mov 0x8(%ebp),%eax +c01071f9: c1 e8 0c shr $0xc,%eax +c01071fc: 89 c2 mov %eax,%edx +c01071fe: a1 04 60 12 c0 mov 0xc0126004,%eax +c0107203: 39 c2 cmp %eax,%edx +c0107205: 72 1c jb c0107223 + panic("pa2page called with invalid pa"); +c0107207: c7 44 24 08 a4 a6 10 movl $0xc010a6a4,0x8(%esp) +c010720e: c0 +c010720f: c7 44 24 04 5b 00 00 movl $0x5b,0x4(%esp) +c0107216: 00 +c0107217: c7 04 24 c3 a6 10 c0 movl $0xc010a6c3,(%esp) +c010721e: e8 1f 9a ff ff call c0100c42 <__panic> + return &pages[PPN(pa)]; +c0107223: 8b 15 00 60 12 c0 mov 0xc0126000,%edx +c0107229: 8b 45 08 mov 0x8(%ebp),%eax +c010722c: c1 e8 0c shr $0xc,%eax +c010722f: c1 e0 05 shl $0x5,%eax +c0107232: 01 d0 add %edx,%eax +} +c0107234: 89 ec mov %ebp,%esp +c0107236: 5d pop %ebp +c0107237: c3 ret + +c0107238 : +pde2page(pde_t pde) { +c0107238: 55 push %ebp +c0107239: 89 e5 mov %esp,%ebp +c010723b: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); +c010723e: 8b 45 08 mov 0x8(%ebp),%eax +c0107241: 25 00 f0 ff ff and $0xfffff000,%eax +c0107246: 89 04 24 mov %eax,(%esp) +c0107249: e8 a2 ff ff ff call c01071f0 +} +c010724e: 89 ec mov %ebp,%esp +c0107250: 5d pop %ebp +c0107251: c3 ret + +c0107252 : + * 它包括内存映射列表、页目录、映射缓存等重要信息 + * + * @return 分配并初始化后的`mm_struct`结构体指针,如果分配失败则返回NULL + */ +struct mm_struct * +mm_create(void) { +c0107252: 55 push %ebp +c0107253: 89 e5 mov %esp,%ebp +c0107255: 83 ec 28 sub $0x28,%esp + // 分配一个mm_struct结构体的空间 + struct mm_struct *mm = kmalloc(sizeof(struct mm_struct)); +c0107258: c7 04 24 18 00 00 00 movl $0x18,(%esp) +c010725f: e8 c9 ed ff ff call c010602d +c0107264: 89 45 f4 mov %eax,-0xc(%ebp) + // 检查是否成功分配了内存 + if (mm != NULL) { +c0107267: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010726b: 74 59 je c01072c6 + // 初始化内存映射列表 + list_init(&(mm->mmap_list)); +c010726d: 8b 45 f4 mov -0xc(%ebp),%eax +c0107270: 89 45 f0 mov %eax,-0x10(%ebp) + elm->prev = elm->next = elm; +c0107273: 8b 45 f0 mov -0x10(%ebp),%eax +c0107276: 8b 55 f0 mov -0x10(%ebp),%edx +c0107279: 89 50 04 mov %edx,0x4(%eax) +c010727c: 8b 45 f0 mov -0x10(%ebp),%eax +c010727f: 8b 50 04 mov 0x4(%eax),%edx +c0107282: 8b 45 f0 mov -0x10(%ebp),%eax +c0107285: 89 10 mov %edx,(%eax) +} +c0107287: 90 nop + // 设置映射缓存为NULL,表示尚未缓存任何映射 + mm->mmap_cache = NULL; +c0107288: 8b 45 f4 mov -0xc(%ebp),%eax +c010728b: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) + // 设置页目录为NULL,表示尚未分配页目录 + mm->pgdir = NULL; +c0107292: 8b 45 f4 mov -0xc(%ebp),%eax +c0107295: c7 40 0c 00 00 00 00 movl $0x0,0xc(%eax) + // 初始化映射计数为0,表示尚未创建任何内存映射 + mm->map_count = 0; +c010729c: 8b 45 f4 mov -0xc(%ebp),%eax +c010729f: c7 40 10 00 00 00 00 movl $0x0,0x10(%eax) + // 如果交换空间初始化成功,则为当前内存管理结构体进行交换空间初始化 + if (swap_init_ok) swap_init_mm(mm); +c01072a6: a1 a4 60 12 c0 mov 0xc01260a4,%eax +c01072ab: 85 c0 test %eax,%eax +c01072ad: 74 0d je c01072bc +c01072af: 8b 45 f4 mov -0xc(%ebp),%eax +c01072b2: 89 04 24 mov %eax,(%esp) +c01072b5: e8 cc ef ff ff call c0106286 +c01072ba: eb 0a jmp c01072c6 + else mm->sm_priv = NULL; +c01072bc: 8b 45 f4 mov -0xc(%ebp),%eax +c01072bf: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + } + // 返回分配并初始化后的内存管理结构体指针 + return mm; +c01072c6: 8b 45 f4 mov -0xc(%ebp),%eax +} +c01072c9: 89 ec mov %ebp,%esp +c01072cb: 5d pop %ebp +c01072cc: c3 ret + +c01072cd : + * @param vm_flags 虚拟内存区域的标志,表示内存区域的权限和特性。 + * + * @return 返回指向新创建的vma_struct结构体的指针,如果内存分配失败,则返回NULL。 + */ +struct vma_struct * +vma_create(uintptr_t vm_start, uintptr_t vm_end, uint32_t vm_flags) { +c01072cd: 55 push %ebp +c01072ce: 89 e5 mov %esp,%ebp +c01072d0: 83 ec 28 sub $0x28,%esp + // 分配vma_struct结构体所需的内存空间 + struct vma_struct *vma = kmalloc(sizeof(struct vma_struct)); +c01072d3: c7 04 24 18 00 00 00 movl $0x18,(%esp) +c01072da: e8 4e ed ff ff call c010602d +c01072df: 89 45 f4 mov %eax,-0xc(%ebp) + // 检查内存是否成功分配 + if (vma != NULL) { +c01072e2: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01072e6: 74 1b je c0107303 + // 初始化vma_struct的成员变量 + vma->vm_start = vm_start; +c01072e8: 8b 45 f4 mov -0xc(%ebp),%eax +c01072eb: 8b 55 08 mov 0x8(%ebp),%edx +c01072ee: 89 50 04 mov %edx,0x4(%eax) + vma->vm_end = vm_end; +c01072f1: 8b 45 f4 mov -0xc(%ebp),%eax +c01072f4: 8b 55 0c mov 0xc(%ebp),%edx +c01072f7: 89 50 08 mov %edx,0x8(%eax) + vma->vm_flags = vm_flags; +c01072fa: 8b 45 f4 mov -0xc(%ebp),%eax +c01072fd: 8b 55 10 mov 0x10(%ebp),%edx +c0107300: 89 50 0c mov %edx,0xc(%eax) + } + // 返回指向新创建的vma_struct结构体的指针,或在内存分配失败时返回NULL + return vma; +c0107303: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0107306: 89 ec mov %ebp,%esp +c0107308: 5d pop %ebp +c0107309: c3 ret + +c010730a : + * 此函数首先检查mmap_cache是否包含所需的VMA,以加速查找过程 + * 如果mmap_cache未命中,则遍历VMA列表,直到找到包含给定地址的VMA或确定不存在这样的VMA + * 如果找到了合适的VMA,它将更新mmap_cache以供后续查找使用 + */ +struct vma_struct * +find_vma(struct mm_struct *mm, uintptr_t addr) { +c010730a: 55 push %ebp +c010730b: 89 e5 mov %esp,%ebp +c010730d: 83 ec 20 sub $0x20,%esp + struct vma_struct *vma = NULL;// 初始化VMA指针为NULL +c0107310: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + if (mm != NULL) {// 检查传入的内存描述符是否有效 +c0107317: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010731b: 0f 84 95 00 00 00 je c01073b6 + // 检查mmap_cache是否包含所需的VMA + vma = mm->mmap_cache; +c0107321: 8b 45 08 mov 0x8(%ebp),%eax +c0107324: 8b 40 08 mov 0x8(%eax),%eax +c0107327: 89 45 fc mov %eax,-0x4(%ebp) + if (!(vma != NULL && vma->vm_start <= addr && vma->vm_end > addr)) { +c010732a: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c010732e: 74 16 je c0107346 +c0107330: 8b 45 fc mov -0x4(%ebp),%eax +c0107333: 8b 40 04 mov 0x4(%eax),%eax +c0107336: 39 45 0c cmp %eax,0xc(%ebp) +c0107339: 72 0b jb c0107346 +c010733b: 8b 45 fc mov -0x4(%ebp),%eax +c010733e: 8b 40 08 mov 0x8(%eax),%eax +c0107341: 39 45 0c cmp %eax,0xc(%ebp) +c0107344: 72 61 jb c01073a7 + // 如果mmap_cache未命中,则开始遍历VMA列表 + bool found = 0;// 初始化找到标志为0 +c0107346: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + // 获取VMA列表的头指针 + list_entry_t *list = &(mm->mmap_list), *le = list; +c010734d: 8b 45 08 mov 0x8(%ebp),%eax +c0107350: 89 45 f0 mov %eax,-0x10(%ebp) +c0107353: 8b 45 f0 mov -0x10(%ebp),%eax +c0107356: 89 45 f4 mov %eax,-0xc(%ebp) + while ((le = list_next(le)) != list) { // 遍历VMA列表 +c0107359: eb 28 jmp c0107383 + vma = le2vma(le, list_link);// 将链表项转换为VMA结构 +c010735b: 8b 45 f4 mov -0xc(%ebp),%eax +c010735e: 83 e8 10 sub $0x10,%eax +c0107361: 89 45 fc mov %eax,-0x4(%ebp) + // 检查当前VMA是否包含给定地址 + if (vma->vm_start<=addr && addr < vma->vm_end) { +c0107364: 8b 45 fc mov -0x4(%ebp),%eax +c0107367: 8b 40 04 mov 0x4(%eax),%eax +c010736a: 39 45 0c cmp %eax,0xc(%ebp) +c010736d: 72 14 jb c0107383 +c010736f: 8b 45 fc mov -0x4(%ebp),%eax +c0107372: 8b 40 08 mov 0x8(%eax),%eax +c0107375: 39 45 0c cmp %eax,0xc(%ebp) +c0107378: 73 09 jae c0107383 + found = 1;// 找到合适的VMA +c010737a: c7 45 f8 01 00 00 00 movl $0x1,-0x8(%ebp) + break;// 结束循环 +c0107381: eb 17 jmp c010739a +c0107383: 8b 45 f4 mov -0xc(%ebp),%eax +c0107386: 89 45 ec mov %eax,-0x14(%ebp) + return listelm->next; +c0107389: 8b 45 ec mov -0x14(%ebp),%eax +c010738c: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { // 遍历VMA列表 +c010738f: 89 45 f4 mov %eax,-0xc(%ebp) +c0107392: 8b 45 f4 mov -0xc(%ebp),%eax +c0107395: 3b 45 f0 cmp -0x10(%ebp),%eax +c0107398: 75 c1 jne c010735b + } + } + if (!found) {// 如果未找到合适的VMA +c010739a: 83 7d f8 00 cmpl $0x0,-0x8(%ebp) +c010739e: 75 07 jne c01073a7 + vma = NULL;// 将VMA指针设置为NULL +c01073a0: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + } + } + // 如果找到了合适的VMA,更新mmap_cache + if (vma != NULL) { +c01073a7: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c01073ab: 74 09 je c01073b6 + mm->mmap_cache = vma;// 更新mmap_cache以加速后续查找 +c01073ad: 8b 45 08 mov 0x8(%ebp),%eax +c01073b0: 8b 55 fc mov -0x4(%ebp),%edx +c01073b3: 89 50 08 mov %edx,0x8(%eax) + } + } + return vma; +c01073b6: 8b 45 fc mov -0x4(%ebp),%eax +} +c01073b9: 89 ec mov %ebp,%esp +c01073bb: 5d pop %ebp +c01073bc: c3 ret + +c01073bd : + * + * @param prev 指向前一个虚拟内存区域(VMA)的结构体指针 + * @param next 指向后一个虚拟内存区域(VMA)的结构体指针 + */ +static inline void +check_vma_overlap(struct vma_struct *prev, struct vma_struct *next) { +c01073bd: 55 push %ebp +c01073be: 89 e5 mov %esp,%ebp +c01073c0: 83 ec 18 sub $0x18,%esp + assert(prev->vm_start < prev->vm_end);// 确保前一个VMA的地址范围是有效的 +c01073c3: 8b 45 08 mov 0x8(%ebp),%eax +c01073c6: 8b 50 04 mov 0x4(%eax),%edx +c01073c9: 8b 45 08 mov 0x8(%ebp),%eax +c01073cc: 8b 40 08 mov 0x8(%eax),%eax +c01073cf: 39 c2 cmp %eax,%edx +c01073d1: 72 24 jb c01073f7 +c01073d3: c7 44 24 0c d1 a6 10 movl $0xc010a6d1,0xc(%esp) +c01073da: c0 +c01073db: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c01073e2: c0 +c01073e3: c7 44 24 04 a0 00 00 movl $0xa0,0x4(%esp) +c01073ea: 00 +c01073eb: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c01073f2: e8 4b 98 ff ff call c0100c42 <__panic> + assert(prev->vm_end <= next->vm_start);// 确保两个VMA之间没有重叠 +c01073f7: 8b 45 08 mov 0x8(%ebp),%eax +c01073fa: 8b 50 08 mov 0x8(%eax),%edx +c01073fd: 8b 45 0c mov 0xc(%ebp),%eax +c0107400: 8b 40 04 mov 0x4(%eax),%eax +c0107403: 39 c2 cmp %eax,%edx +c0107405: 76 24 jbe c010742b +c0107407: c7 44 24 0c 14 a7 10 movl $0xc010a714,0xc(%esp) +c010740e: c0 +c010740f: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107416: c0 +c0107417: c7 44 24 04 a1 00 00 movl $0xa1,0x4(%esp) +c010741e: 00 +c010741f: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107426: e8 17 98 ff ff call c0100c42 <__panic> + assert(next->vm_start < next->vm_end);// 确保后一个VMA的地址范围是有效的 +c010742b: 8b 45 0c mov 0xc(%ebp),%eax +c010742e: 8b 50 04 mov 0x4(%eax),%edx +c0107431: 8b 45 0c mov 0xc(%ebp),%eax +c0107434: 8b 40 08 mov 0x8(%eax),%eax +c0107437: 39 c2 cmp %eax,%edx +c0107439: 72 24 jb c010745f +c010743b: c7 44 24 0c 33 a7 10 movl $0xc010a733,0xc(%esp) +c0107442: c0 +c0107443: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c010744a: c0 +c010744b: c7 44 24 04 a2 00 00 movl $0xa2,0x4(%esp) +c0107452: 00 +c0107453: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c010745a: e8 e3 97 ff ff call c0100c42 <__panic> +} +c010745f: 90 nop +c0107460: 89 ec mov %ebp,%esp +c0107462: 5d pop %ebp +c0107463: c3 ret + +c0107464 : + * + * @param mm 指向内存描述符结构 `struct mm_struct` 的指针,表示一个进程的内存空间。 + * @param vma 指向要插入的VMA结构 `struct vma_struct` 的指针,描述一个内存区域。 + */ +void +insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) { +c0107464: 55 push %ebp +c0107465: 89 e5 mov %esp,%ebp +c0107467: 83 ec 48 sub $0x48,%esp + // 断言VMA结构的起始地址小于结束地址,确保VMA结构的有效性。 + assert(vma->vm_start < vma->vm_end); +c010746a: 8b 45 0c mov 0xc(%ebp),%eax +c010746d: 8b 50 04 mov 0x4(%eax),%edx +c0107470: 8b 45 0c mov 0xc(%ebp),%eax +c0107473: 8b 40 08 mov 0x8(%eax),%eax +c0107476: 39 c2 cmp %eax,%edx +c0107478: 72 24 jb c010749e +c010747a: c7 44 24 0c 51 a7 10 movl $0xc010a751,0xc(%esp) +c0107481: c0 +c0107482: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107489: c0 +c010748a: c7 44 24 04 b3 00 00 movl $0xb3,0x4(%esp) +c0107491: 00 +c0107492: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107499: e8 a4 97 ff ff call c0100c42 <__panic> + // 指向内存描述符中的VMA链表。 + list_entry_t *list = &(mm->mmap_list); +c010749e: 8b 45 08 mov 0x8(%ebp),%eax +c01074a1: 89 45 ec mov %eax,-0x14(%ebp) + // 遍历链表以找到新VMA结构的正确插入位置。 + list_entry_t *le_prev = list, *le_next; +c01074a4: 8b 45 ec mov -0x14(%ebp),%eax +c01074a7: 89 45 f4 mov %eax,-0xc(%ebp) + + list_entry_t *le = list; +c01074aa: 8b 45 ec mov -0x14(%ebp),%eax +c01074ad: 89 45 f0 mov %eax,-0x10(%ebp) + // 遍历链表以找到新VMA结构的正确插入位置 + while ((le = list_next(le)) != list) { +c01074b0: eb 1f jmp c01074d1 + struct vma_struct *mmap_prev = le2vma(le, list_link); +c01074b2: 8b 45 f0 mov -0x10(%ebp),%eax +c01074b5: 83 e8 10 sub $0x10,%eax +c01074b8: 89 45 e8 mov %eax,-0x18(%ebp) + // 如果当前VMA的起始地址大于新VMA的起始地址,则跳出循环 + if (mmap_prev->vm_start > vma->vm_start) { +c01074bb: 8b 45 e8 mov -0x18(%ebp),%eax +c01074be: 8b 50 04 mov 0x4(%eax),%edx +c01074c1: 8b 45 0c mov 0xc(%ebp),%eax +c01074c4: 8b 40 04 mov 0x4(%eax),%eax +c01074c7: 39 c2 cmp %eax,%edx +c01074c9: 77 1f ja c01074ea + break; + } + le_prev = le; +c01074cb: 8b 45 f0 mov -0x10(%ebp),%eax +c01074ce: 89 45 f4 mov %eax,-0xc(%ebp) +c01074d1: 8b 45 f0 mov -0x10(%ebp),%eax +c01074d4: 89 45 e0 mov %eax,-0x20(%ebp) +c01074d7: 8b 45 e0 mov -0x20(%ebp),%eax +c01074da: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != list) { +c01074dd: 89 45 f0 mov %eax,-0x10(%ebp) +c01074e0: 8b 45 f0 mov -0x10(%ebp),%eax +c01074e3: 3b 45 ec cmp -0x14(%ebp),%eax +c01074e6: 75 ca jne c01074b2 +c01074e8: eb 01 jmp c01074eb + break; +c01074ea: 90 nop +c01074eb: 8b 45 f4 mov -0xc(%ebp),%eax +c01074ee: 89 45 dc mov %eax,-0x24(%ebp) +c01074f1: 8b 45 dc mov -0x24(%ebp),%eax +c01074f4: 8b 40 04 mov 0x4(%eax),%eax + } + // 获取下一个链表项 + le_next = list_next(le_prev); +c01074f7: 89 45 e4 mov %eax,-0x1c(%ebp) + + /* check overlap */ + // 检查前一个VMA结构是否与新VMA结构重叠 + if (le_prev != list) { +c01074fa: 8b 45 f4 mov -0xc(%ebp),%eax +c01074fd: 3b 45 ec cmp -0x14(%ebp),%eax +c0107500: 74 15 je c0107517 + check_vma_overlap(le2vma(le_prev, list_link), vma); +c0107502: 8b 45 f4 mov -0xc(%ebp),%eax +c0107505: 8d 50 f0 lea -0x10(%eax),%edx +c0107508: 8b 45 0c mov 0xc(%ebp),%eax +c010750b: 89 44 24 04 mov %eax,0x4(%esp) +c010750f: 89 14 24 mov %edx,(%esp) +c0107512: e8 a6 fe ff ff call c01073bd + } + // 检查下一个VMA结构是否与新VMA结构重叠 + if (le_next != list) { +c0107517: 8b 45 e4 mov -0x1c(%ebp),%eax +c010751a: 3b 45 ec cmp -0x14(%ebp),%eax +c010751d: 74 15 je c0107534 + check_vma_overlap(vma, le2vma(le_next, list_link)); +c010751f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107522: 83 e8 10 sub $0x10,%eax +c0107525: 89 44 24 04 mov %eax,0x4(%esp) +c0107529: 8b 45 0c mov 0xc(%ebp),%eax +c010752c: 89 04 24 mov %eax,(%esp) +c010752f: e8 89 fe ff ff call c01073bd + } + // 设置VMA结构所属的内存描述符 + vma->vm_mm = mm; +c0107534: 8b 45 0c mov 0xc(%ebp),%eax +c0107537: 8b 55 08 mov 0x8(%ebp),%edx +c010753a: 89 10 mov %edx,(%eax) + // 将新VMA结构插入链表 + list_add_after(le_prev, &(vma->list_link)); +c010753c: 8b 45 0c mov 0xc(%ebp),%eax +c010753f: 8d 50 10 lea 0x10(%eax),%edx +c0107542: 8b 45 f4 mov -0xc(%ebp),%eax +c0107545: 89 45 d8 mov %eax,-0x28(%ebp) +c0107548: 89 55 d4 mov %edx,-0x2c(%ebp) + __list_add(elm, listelm, listelm->next); +c010754b: 8b 45 d8 mov -0x28(%ebp),%eax +c010754e: 8b 40 04 mov 0x4(%eax),%eax +c0107551: 8b 55 d4 mov -0x2c(%ebp),%edx +c0107554: 89 55 d0 mov %edx,-0x30(%ebp) +c0107557: 8b 55 d8 mov -0x28(%ebp),%edx +c010755a: 89 55 cc mov %edx,-0x34(%ebp) +c010755d: 89 45 c8 mov %eax,-0x38(%ebp) + prev->next = next->prev = elm; +c0107560: 8b 45 c8 mov -0x38(%ebp),%eax +c0107563: 8b 55 d0 mov -0x30(%ebp),%edx +c0107566: 89 10 mov %edx,(%eax) +c0107568: 8b 45 c8 mov -0x38(%ebp),%eax +c010756b: 8b 10 mov (%eax),%edx +c010756d: 8b 45 cc mov -0x34(%ebp),%eax +c0107570: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0107573: 8b 45 d0 mov -0x30(%ebp),%eax +c0107576: 8b 55 c8 mov -0x38(%ebp),%edx +c0107579: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c010757c: 8b 45 d0 mov -0x30(%ebp),%eax +c010757f: 8b 55 cc mov -0x34(%ebp),%edx +c0107582: 89 10 mov %edx,(%eax) +} +c0107584: 90 nop +} +c0107585: 90 nop + // 增加内存描述符中的映射计数 + mm->map_count ++; +c0107586: 8b 45 08 mov 0x8(%ebp),%eax +c0107589: 8b 40 10 mov 0x10(%eax),%eax +c010758c: 8d 50 01 lea 0x1(%eax),%edx +c010758f: 8b 45 08 mov 0x8(%ebp),%eax +c0107592: 89 50 10 mov %edx,0x10(%eax) +} +c0107595: 90 nop +c0107596: 89 ec mov %ebp,%esp +c0107598: 5d pop %ebp +c0107599: c3 ret + +c010759a : + * 此函数遍历并销毁与内存管理结构(mm_struct)关联的所有虚拟内存区域(VMA), + * 然后释放内存管理结构本身所占用的内存。这样做是为了确保在销毁内存管理结构之前, + * 所有相关的资源都被正确地释放。 + */ +void +mm_destroy(struct mm_struct *mm) { +c010759a: 55 push %ebp +c010759b: 89 e5 mov %esp,%ebp +c010759d: 83 ec 38 sub $0x38,%esp + // 获取内存映射列表的头指针 + list_entry_t *list = &(mm->mmap_list), *le; +c01075a0: 8b 45 08 mov 0x8(%ebp),%eax +c01075a3: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历内存映射列表,直到回到起点 + while ((le = list_next(list)) != list) { +c01075a6: eb 40 jmp c01075e8 +c01075a8: 8b 45 f0 mov -0x10(%ebp),%eax +c01075ab: 89 45 ec mov %eax,-0x14(%ebp) + __list_del(listelm->prev, listelm->next); +c01075ae: 8b 45 ec mov -0x14(%ebp),%eax +c01075b1: 8b 40 04 mov 0x4(%eax),%eax +c01075b4: 8b 55 ec mov -0x14(%ebp),%edx +c01075b7: 8b 12 mov (%edx),%edx +c01075b9: 89 55 e8 mov %edx,-0x18(%ebp) +c01075bc: 89 45 e4 mov %eax,-0x1c(%ebp) + prev->next = next; +c01075bf: 8b 45 e8 mov -0x18(%ebp),%eax +c01075c2: 8b 55 e4 mov -0x1c(%ebp),%edx +c01075c5: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c01075c8: 8b 45 e4 mov -0x1c(%ebp),%eax +c01075cb: 8b 55 e8 mov -0x18(%ebp),%edx +c01075ce: 89 10 mov %edx,(%eax) +} +c01075d0: 90 nop +} +c01075d1: 90 nop + // 从列表中删除当前虚拟内存区域的项 + list_del(le); + // 释放虚拟内存区域结构的内存 + kfree(le2vma(le, list_link),sizeof(struct vma_struct)); //kfree vma +c01075d2: 8b 45 f0 mov -0x10(%ebp),%eax +c01075d5: 83 e8 10 sub $0x10,%eax +c01075d8: c7 44 24 04 18 00 00 movl $0x18,0x4(%esp) +c01075df: 00 +c01075e0: 89 04 24 mov %eax,(%esp) +c01075e3: e8 e7 ea ff ff call c01060cf +c01075e8: 8b 45 f4 mov -0xc(%ebp),%eax +c01075eb: 89 45 e0 mov %eax,-0x20(%ebp) + return listelm->next; +c01075ee: 8b 45 e0 mov -0x20(%ebp),%eax +c01075f1: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(list)) != list) { +c01075f4: 89 45 f0 mov %eax,-0x10(%ebp) +c01075f7: 8b 45 f0 mov -0x10(%ebp),%eax +c01075fa: 3b 45 f4 cmp -0xc(%ebp),%eax +c01075fd: 75 a9 jne c01075a8 + } + // 释放内存管理结构本身的内存 + kfree(mm, sizeof(struct mm_struct)); //kfree mm +c01075ff: c7 44 24 04 18 00 00 movl $0x18,0x4(%esp) +c0107606: 00 +c0107607: 8b 45 08 mov 0x8(%ebp),%eax +c010760a: 89 04 24 mov %eax,(%esp) +c010760d: e8 bd ea ff ff call c01060cf + // 将指针设置为NULL,表示该结构已被销毁 + mm=NULL; +c0107612: c7 45 08 00 00 00 00 movl $0x0,0x8(%ebp) +} +c0107619: 90 nop +c010761a: 89 ec mov %ebp,%esp +c010761c: 5d pop %ebp +c010761d: c3 ret + +c010761e : +/** + * 初始化虚拟内存管理(VMM)系统。 + * 此函数通过执行一系列检查来确保VMM系统可以正确初始化和运行。 + */ +void +vmm_init(void) { +c010761e: 55 push %ebp +c010761f: 89 e5 mov %esp,%ebp +c0107621: 83 ec 08 sub $0x8,%esp + // 检查VMM系统的状态和环境,以确保其能够正常工作。 + check_vmm(); +c0107624: e8 05 00 00 00 call c010762e +} +c0107629: 90 nop +c010762a: 89 ec mov %ebp,%esp +c010762c: 5d pop %ebp +c010762d: c3 ret + +c010762e : + * 此函数的目的是确保虚拟内存管理系统的正确性通过检查内存区域结构(VMA)、页面故障处理以及免费页面计数的 consistency 来实现 + * 它首先保存当前的免费页面数量,然后执行与 VMA 和页面故障相关的检查,最后确认免费页面数量未发生变化 + * 这是为了确保在检查过程中,内存状态没有因为错误或意外的修改而改变,从而验证内存管理的正确性 + */ +static void +check_vmm(void) { +c010762e: 55 push %ebp +c010762f: 89 e5 mov %esp,%ebp +c0107631: 83 ec 28 sub $0x28,%esp + // 保存当前的免费页面数量,用于后续的 consistency 检查 + size_t nr_free_pages_store = nr_free_pages(); +c0107634: e8 10 d3 ff ff call c0104949 +c0107639: 89 45 f4 mov %eax,-0xc(%ebp) + // 检查虚拟内存区域(VMA)结构的正确性 + check_vma_struct(); +c010763c: e8 44 00 00 00 call c0107685 + // 检查页面故障处理的正确性 + check_pgfault(); +c0107641: e8 01 05 00 00 call c0107b47 + // 确保在检查过程中免费页面数量未发生变化,表明内存管理操作是正确的 + assert(nr_free_pages_store == nr_free_pages()); +c0107646: e8 fe d2 ff ff call c0104949 +c010764b: 39 45 f4 cmp %eax,-0xc(%ebp) +c010764e: 74 24 je c0107674 +c0107650: c7 44 24 0c 70 a7 10 movl $0xc010a770,0xc(%esp) +c0107657: c0 +c0107658: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c010765f: c0 +c0107660: c7 44 24 04 0e 01 00 movl $0x10e,0x4(%esp) +c0107667: 00 +c0107668: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c010766f: e8 ce 95 ff ff call c0100c42 <__panic> + // 如果所有检查都通过,输出成功信息 + cprintf("check_vmm() succeeded.\n"); +c0107674: c7 04 24 97 a7 10 c0 movl $0xc010a797,(%esp) +c010767b: e8 f5 8c ff ff call c0100375 +} +c0107680: 90 nop +c0107681: 89 ec mov %ebp,%esp +c0107683: 5d pop %ebp +c0107684: c3 ret + +c0107685 : + +//测试虚拟内存区域(VMA)结构的创建、插入和查找功能。 +static void +check_vma_struct(void) { +c0107685: 55 push %ebp +c0107686: 89 e5 mov %esp,%ebp +c0107688: 83 ec 68 sub $0x68,%esp + // 记录当前空闲页面数量 + size_t nr_free_pages_store = nr_free_pages(); +c010768b: e8 b9 d2 ff ff call c0104949 +c0107690: 89 45 ec mov %eax,-0x14(%ebp) + + struct mm_struct *mm = mm_create();// 创建内存管理结构 mm +c0107693: e8 ba fb ff ff call c0107252 +c0107698: 89 45 e8 mov %eax,-0x18(%ebp) + assert(mm != NULL);// 确保 mm 不为 NULL +c010769b: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010769f: 75 24 jne c01076c5 +c01076a1: c7 44 24 0c af a7 10 movl $0xc010a7af,0xc(%esp) +c01076a8: c0 +c01076a9: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c01076b0: c0 +c01076b1: c7 44 24 04 1a 01 00 movl $0x11a,0x4(%esp) +c01076b8: 00 +c01076b9: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c01076c0: e8 7d 95 ff ff call c0100c42 <__panic> + + int step1 = 10, step2 = step1 * 10;// 定义两个步骤的步数 +c01076c5: c7 45 e4 0a 00 00 00 movl $0xa,-0x1c(%ebp) +c01076cc: 8b 55 e4 mov -0x1c(%ebp),%edx +c01076cf: 89 d0 mov %edx,%eax +c01076d1: c1 e0 02 shl $0x2,%eax +c01076d4: 01 d0 add %edx,%eax +c01076d6: 01 c0 add %eax,%eax +c01076d8: 89 45 e0 mov %eax,-0x20(%ebp) + + int i; + for (i = step1; i >= 1; i --) {// 第一步:创建并插入10个VMA +c01076db: 8b 45 e4 mov -0x1c(%ebp),%eax +c01076de: 89 45 f4 mov %eax,-0xc(%ebp) +c01076e1: eb 6f jmp c0107752 + // 创建 VMA 结构 + struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); +c01076e3: 8b 55 f4 mov -0xc(%ebp),%edx +c01076e6: 89 d0 mov %edx,%eax +c01076e8: c1 e0 02 shl $0x2,%eax +c01076eb: 01 d0 add %edx,%eax +c01076ed: 83 c0 02 add $0x2,%eax +c01076f0: 89 c1 mov %eax,%ecx +c01076f2: 8b 55 f4 mov -0xc(%ebp),%edx +c01076f5: 89 d0 mov %edx,%eax +c01076f7: c1 e0 02 shl $0x2,%eax +c01076fa: 01 d0 add %edx,%eax +c01076fc: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0107703: 00 +c0107704: 89 4c 24 04 mov %ecx,0x4(%esp) +c0107708: 89 04 24 mov %eax,(%esp) +c010770b: e8 bd fb ff ff call c01072cd +c0107710: 89 45 bc mov %eax,-0x44(%ebp) + assert(vma != NULL);// 确保 VMA 不为 NULL +c0107713: 83 7d bc 00 cmpl $0x0,-0x44(%ebp) +c0107717: 75 24 jne c010773d +c0107719: c7 44 24 0c ba a7 10 movl $0xc010a7ba,0xc(%esp) +c0107720: c0 +c0107721: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107728: c0 +c0107729: c7 44 24 04 22 01 00 movl $0x122,0x4(%esp) +c0107730: 00 +c0107731: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107738: e8 05 95 ff ff call c0100c42 <__panic> + insert_vma_struct(mm, vma); //将 VMA 插入到 mm 中 +c010773d: 8b 45 bc mov -0x44(%ebp),%eax +c0107740: 89 44 24 04 mov %eax,0x4(%esp) +c0107744: 8b 45 e8 mov -0x18(%ebp),%eax +c0107747: 89 04 24 mov %eax,(%esp) +c010774a: e8 15 fd ff ff call c0107464 + for (i = step1; i >= 1; i --) {// 第一步:创建并插入10个VMA +c010774f: ff 4d f4 decl -0xc(%ebp) +c0107752: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0107756: 7f 8b jg c01076e3 + } + + for (i = step1 + 1; i <= step2; i ++) {// 第二步:创建并插入90个VMA +c0107758: 8b 45 e4 mov -0x1c(%ebp),%eax +c010775b: 40 inc %eax +c010775c: 89 45 f4 mov %eax,-0xc(%ebp) +c010775f: eb 6f jmp c01077d0 + // 创建 VMA 结构 + struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); +c0107761: 8b 55 f4 mov -0xc(%ebp),%edx +c0107764: 89 d0 mov %edx,%eax +c0107766: c1 e0 02 shl $0x2,%eax +c0107769: 01 d0 add %edx,%eax +c010776b: 83 c0 02 add $0x2,%eax +c010776e: 89 c1 mov %eax,%ecx +c0107770: 8b 55 f4 mov -0xc(%ebp),%edx +c0107773: 89 d0 mov %edx,%eax +c0107775: c1 e0 02 shl $0x2,%eax +c0107778: 01 d0 add %edx,%eax +c010777a: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0107781: 00 +c0107782: 89 4c 24 04 mov %ecx,0x4(%esp) +c0107786: 89 04 24 mov %eax,(%esp) +c0107789: e8 3f fb ff ff call c01072cd +c010778e: 89 45 c0 mov %eax,-0x40(%ebp) + assert(vma != NULL);// 确保 VMA 不为 NULL +c0107791: 83 7d c0 00 cmpl $0x0,-0x40(%ebp) +c0107795: 75 24 jne c01077bb +c0107797: c7 44 24 0c ba a7 10 movl $0xc010a7ba,0xc(%esp) +c010779e: c0 +c010779f: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c01077a6: c0 +c01077a7: c7 44 24 04 29 01 00 movl $0x129,0x4(%esp) +c01077ae: 00 +c01077af: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c01077b6: e8 87 94 ff ff call c0100c42 <__panic> + insert_vma_struct(mm, vma);// 将 VMA 插入到 mm 中 +c01077bb: 8b 45 c0 mov -0x40(%ebp),%eax +c01077be: 89 44 24 04 mov %eax,0x4(%esp) +c01077c2: 8b 45 e8 mov -0x18(%ebp),%eax +c01077c5: 89 04 24 mov %eax,(%esp) +c01077c8: e8 97 fc ff ff call c0107464 + for (i = step1 + 1; i <= step2; i ++) {// 第二步:创建并插入90个VMA +c01077cd: ff 45 f4 incl -0xc(%ebp) +c01077d0: 8b 45 f4 mov -0xc(%ebp),%eax +c01077d3: 3b 45 e0 cmp -0x20(%ebp),%eax +c01077d6: 7e 89 jle c0107761 + } + // 获取 VMA 链表的第一个节点 + list_entry_t *le = list_next(&(mm->mmap_list)); +c01077d8: 8b 45 e8 mov -0x18(%ebp),%eax +c01077db: 89 45 b8 mov %eax,-0x48(%ebp) +c01077de: 8b 45 b8 mov -0x48(%ebp),%eax +c01077e1: 8b 40 04 mov 0x4(%eax),%eax +c01077e4: 89 45 f0 mov %eax,-0x10(%ebp) + + for (i = 1; i <= step2; i ++) {// 验证插入顺序 +c01077e7: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) +c01077ee: e9 96 00 00 00 jmp c0107889 + assert(le != &(mm->mmap_list));// 确保节点不为空 +c01077f3: 8b 45 e8 mov -0x18(%ebp),%eax +c01077f6: 39 45 f0 cmp %eax,-0x10(%ebp) +c01077f9: 75 24 jne c010781f +c01077fb: c7 44 24 0c c6 a7 10 movl $0xc010a7c6,0xc(%esp) +c0107802: c0 +c0107803: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c010780a: c0 +c010780b: c7 44 24 04 30 01 00 movl $0x130,0x4(%esp) +c0107812: 00 +c0107813: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c010781a: e8 23 94 ff ff call c0100c42 <__panic> + struct vma_struct *mmap = le2vma(le, list_link);// 将链表节点转换为 VMA 结构 +c010781f: 8b 45 f0 mov -0x10(%ebp),%eax +c0107822: 83 e8 10 sub $0x10,%eax +c0107825: 89 45 c4 mov %eax,-0x3c(%ebp) + // 确认 VMA 的起始和结束地址 + assert(mmap->vm_start == i * 5 && mmap->vm_end == i * 5 + 2); +c0107828: 8b 45 c4 mov -0x3c(%ebp),%eax +c010782b: 8b 48 04 mov 0x4(%eax),%ecx +c010782e: 8b 55 f4 mov -0xc(%ebp),%edx +c0107831: 89 d0 mov %edx,%eax +c0107833: c1 e0 02 shl $0x2,%eax +c0107836: 01 d0 add %edx,%eax +c0107838: 39 c1 cmp %eax,%ecx +c010783a: 75 17 jne c0107853 +c010783c: 8b 45 c4 mov -0x3c(%ebp),%eax +c010783f: 8b 48 08 mov 0x8(%eax),%ecx +c0107842: 8b 55 f4 mov -0xc(%ebp),%edx +c0107845: 89 d0 mov %edx,%eax +c0107847: c1 e0 02 shl $0x2,%eax +c010784a: 01 d0 add %edx,%eax +c010784c: 83 c0 02 add $0x2,%eax +c010784f: 39 c1 cmp %eax,%ecx +c0107851: 74 24 je c0107877 +c0107853: c7 44 24 0c e0 a7 10 movl $0xc010a7e0,0xc(%esp) +c010785a: c0 +c010785b: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107862: c0 +c0107863: c7 44 24 04 33 01 00 movl $0x133,0x4(%esp) +c010786a: 00 +c010786b: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107872: e8 cb 93 ff ff call c0100c42 <__panic> +c0107877: 8b 45 f0 mov -0x10(%ebp),%eax +c010787a: 89 45 b4 mov %eax,-0x4c(%ebp) +c010787d: 8b 45 b4 mov -0x4c(%ebp),%eax +c0107880: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le);// 移动到下一个节点 +c0107883: 89 45 f0 mov %eax,-0x10(%ebp) + for (i = 1; i <= step2; i ++) {// 验证插入顺序 +c0107886: ff 45 f4 incl -0xc(%ebp) +c0107889: 8b 45 f4 mov -0xc(%ebp),%eax +c010788c: 3b 45 e0 cmp -0x20(%ebp),%eax +c010788f: 0f 8e 5e ff ff ff jle c01077f3 + } + + for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA +c0107895: c7 45 f4 05 00 00 00 movl $0x5,-0xc(%ebp) +c010789c: e9 cb 01 00 00 jmp c0107a6c + struct vma_struct *vma1 = find_vma(mm, i);// 查找地址 i 处的 VMA +c01078a1: 8b 45 f4 mov -0xc(%ebp),%eax +c01078a4: 89 44 24 04 mov %eax,0x4(%esp) +c01078a8: 8b 45 e8 mov -0x18(%ebp),%eax +c01078ab: 89 04 24 mov %eax,(%esp) +c01078ae: e8 57 fa ff ff call c010730a +c01078b3: 89 45 d8 mov %eax,-0x28(%ebp) + assert(vma1 != NULL);// 确保找到 VMA +c01078b6: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c01078ba: 75 24 jne c01078e0 +c01078bc: c7 44 24 0c 15 a8 10 movl $0xc010a815,0xc(%esp) +c01078c3: c0 +c01078c4: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c01078cb: c0 +c01078cc: c7 44 24 04 39 01 00 movl $0x139,0x4(%esp) +c01078d3: 00 +c01078d4: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c01078db: e8 62 93 ff ff call c0100c42 <__panic> + // 查找地址 i + 1 处的 VMA + struct vma_struct *vma2 = find_vma(mm, i+1); +c01078e0: 8b 45 f4 mov -0xc(%ebp),%eax +c01078e3: 40 inc %eax +c01078e4: 89 44 24 04 mov %eax,0x4(%esp) +c01078e8: 8b 45 e8 mov -0x18(%ebp),%eax +c01078eb: 89 04 24 mov %eax,(%esp) +c01078ee: e8 17 fa ff ff call c010730a +c01078f3: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(vma2 != NULL);// 确保找到 VMA +c01078f6: 83 7d d4 00 cmpl $0x0,-0x2c(%ebp) +c01078fa: 75 24 jne c0107920 +c01078fc: c7 44 24 0c 22 a8 10 movl $0xc010a822,0xc(%esp) +c0107903: c0 +c0107904: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c010790b: c0 +c010790c: c7 44 24 04 3c 01 00 movl $0x13c,0x4(%esp) +c0107913: 00 +c0107914: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c010791b: e8 22 93 ff ff call c0100c42 <__panic> + // 查找地址 i + 2 处的 VMA + struct vma_struct *vma3 = find_vma(mm, i+2); +c0107920: 8b 45 f4 mov -0xc(%ebp),%eax +c0107923: 83 c0 02 add $0x2,%eax +c0107926: 89 44 24 04 mov %eax,0x4(%esp) +c010792a: 8b 45 e8 mov -0x18(%ebp),%eax +c010792d: 89 04 24 mov %eax,(%esp) +c0107930: e8 d5 f9 ff ff call c010730a +c0107935: 89 45 d0 mov %eax,-0x30(%ebp) + assert(vma3 == NULL);// 确保未找到 VMA +c0107938: 83 7d d0 00 cmpl $0x0,-0x30(%ebp) +c010793c: 74 24 je c0107962 +c010793e: c7 44 24 0c 2f a8 10 movl $0xc010a82f,0xc(%esp) +c0107945: c0 +c0107946: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c010794d: c0 +c010794e: c7 44 24 04 3f 01 00 movl $0x13f,0x4(%esp) +c0107955: 00 +c0107956: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c010795d: e8 e0 92 ff ff call c0100c42 <__panic> + // 查找地址 i + 3 处的 VMA + struct vma_struct *vma4 = find_vma(mm, i+3); +c0107962: 8b 45 f4 mov -0xc(%ebp),%eax +c0107965: 83 c0 03 add $0x3,%eax +c0107968: 89 44 24 04 mov %eax,0x4(%esp) +c010796c: 8b 45 e8 mov -0x18(%ebp),%eax +c010796f: 89 04 24 mov %eax,(%esp) +c0107972: e8 93 f9 ff ff call c010730a +c0107977: 89 45 cc mov %eax,-0x34(%ebp) + assert(vma4 == NULL);// 确保未找到 VMA +c010797a: 83 7d cc 00 cmpl $0x0,-0x34(%ebp) +c010797e: 74 24 je c01079a4 +c0107980: c7 44 24 0c 3c a8 10 movl $0xc010a83c,0xc(%esp) +c0107987: c0 +c0107988: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c010798f: c0 +c0107990: c7 44 24 04 42 01 00 movl $0x142,0x4(%esp) +c0107997: 00 +c0107998: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c010799f: e8 9e 92 ff ff call c0100c42 <__panic> + // 查找地址 i + 4 处的 VMA + struct vma_struct *vma5 = find_vma(mm, i+4); +c01079a4: 8b 45 f4 mov -0xc(%ebp),%eax +c01079a7: 83 c0 04 add $0x4,%eax +c01079aa: 89 44 24 04 mov %eax,0x4(%esp) +c01079ae: 8b 45 e8 mov -0x18(%ebp),%eax +c01079b1: 89 04 24 mov %eax,(%esp) +c01079b4: e8 51 f9 ff ff call c010730a +c01079b9: 89 45 c8 mov %eax,-0x38(%ebp) + assert(vma5 == NULL);// 确保未找到 VMA +c01079bc: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) +c01079c0: 74 24 je c01079e6 +c01079c2: c7 44 24 0c 49 a8 10 movl $0xc010a849,0xc(%esp) +c01079c9: c0 +c01079ca: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c01079d1: c0 +c01079d2: c7 44 24 04 45 01 00 movl $0x145,0x4(%esp) +c01079d9: 00 +c01079da: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c01079e1: e8 5c 92 ff ff call c0100c42 <__panic> + // 确认 VMA1 的起始和结束地址 + assert(vma1->vm_start == i && vma1->vm_end == i + 2); +c01079e6: 8b 45 d8 mov -0x28(%ebp),%eax +c01079e9: 8b 50 04 mov 0x4(%eax),%edx +c01079ec: 8b 45 f4 mov -0xc(%ebp),%eax +c01079ef: 39 c2 cmp %eax,%edx +c01079f1: 75 10 jne c0107a03 +c01079f3: 8b 45 d8 mov -0x28(%ebp),%eax +c01079f6: 8b 40 08 mov 0x8(%eax),%eax +c01079f9: 8b 55 f4 mov -0xc(%ebp),%edx +c01079fc: 83 c2 02 add $0x2,%edx +c01079ff: 39 d0 cmp %edx,%eax +c0107a01: 74 24 je c0107a27 +c0107a03: c7 44 24 0c 58 a8 10 movl $0xc010a858,0xc(%esp) +c0107a0a: c0 +c0107a0b: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107a12: c0 +c0107a13: c7 44 24 04 47 01 00 movl $0x147,0x4(%esp) +c0107a1a: 00 +c0107a1b: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107a22: e8 1b 92 ff ff call c0100c42 <__panic> + // 确认 VMA2 的起始和结束地址 + assert(vma2->vm_start == i && vma2->vm_end == i + 2); +c0107a27: 8b 45 d4 mov -0x2c(%ebp),%eax +c0107a2a: 8b 50 04 mov 0x4(%eax),%edx +c0107a2d: 8b 45 f4 mov -0xc(%ebp),%eax +c0107a30: 39 c2 cmp %eax,%edx +c0107a32: 75 10 jne c0107a44 +c0107a34: 8b 45 d4 mov -0x2c(%ebp),%eax +c0107a37: 8b 40 08 mov 0x8(%eax),%eax +c0107a3a: 8b 55 f4 mov -0xc(%ebp),%edx +c0107a3d: 83 c2 02 add $0x2,%edx +c0107a40: 39 d0 cmp %edx,%eax +c0107a42: 74 24 je c0107a68 +c0107a44: c7 44 24 0c 88 a8 10 movl $0xc010a888,0xc(%esp) +c0107a4b: c0 +c0107a4c: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107a53: c0 +c0107a54: c7 44 24 04 49 01 00 movl $0x149,0x4(%esp) +c0107a5b: 00 +c0107a5c: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107a63: e8 da 91 ff ff call c0100c42 <__panic> + for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA +c0107a68: 83 45 f4 05 addl $0x5,-0xc(%ebp) +c0107a6c: 8b 55 e0 mov -0x20(%ebp),%edx +c0107a6f: 89 d0 mov %edx,%eax +c0107a71: c1 e0 02 shl $0x2,%eax +c0107a74: 01 d0 add %edx,%eax +c0107a76: 39 45 f4 cmp %eax,-0xc(%ebp) +c0107a79: 0f 8e 22 fe ff ff jle c01078a1 + } + // 检查小于5的地址范围内是否存在 VMA + for (i =4; i>=0; i--) { +c0107a7f: c7 45 f4 04 00 00 00 movl $0x4,-0xc(%ebp) +c0107a86: eb 6f jmp c0107af7 + // 查找地址 i 处的 VMA + struct vma_struct *vma_below_5= find_vma(mm,i); +c0107a88: 8b 45 f4 mov -0xc(%ebp),%eax +c0107a8b: 89 44 24 04 mov %eax,0x4(%esp) +c0107a8f: 8b 45 e8 mov -0x18(%ebp),%eax +c0107a92: 89 04 24 mov %eax,(%esp) +c0107a95: e8 70 f8 ff ff call c010730a +c0107a9a: 89 45 dc mov %eax,-0x24(%ebp) + if (vma_below_5 != NULL ) {// 如果找到 VMA +c0107a9d: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0107aa1: 74 27 je c0107aca + cprintf("vma_below_5: i %x, start %x, end %x\n",i, vma_below_5->vm_start, vma_below_5->vm_end); +c0107aa3: 8b 45 dc mov -0x24(%ebp),%eax +c0107aa6: 8b 50 08 mov 0x8(%eax),%edx +c0107aa9: 8b 45 dc mov -0x24(%ebp),%eax +c0107aac: 8b 40 04 mov 0x4(%eax),%eax +c0107aaf: 89 54 24 0c mov %edx,0xc(%esp) +c0107ab3: 89 44 24 08 mov %eax,0x8(%esp) +c0107ab7: 8b 45 f4 mov -0xc(%ebp),%eax +c0107aba: 89 44 24 04 mov %eax,0x4(%esp) +c0107abe: c7 04 24 b8 a8 10 c0 movl $0xc010a8b8,(%esp) +c0107ac5: e8 ab 88 ff ff call c0100375 + } + assert(vma_below_5 == NULL);// 确保未找到 VMA +c0107aca: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0107ace: 74 24 je c0107af4 +c0107ad0: c7 44 24 0c dd a8 10 movl $0xc010a8dd,0xc(%esp) +c0107ad7: c0 +c0107ad8: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107adf: c0 +c0107ae0: c7 44 24 04 52 01 00 movl $0x152,0x4(%esp) +c0107ae7: 00 +c0107ae8: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107aef: e8 4e 91 ff ff call c0100c42 <__panic> + for (i =4; i>=0; i--) { +c0107af4: ff 4d f4 decl -0xc(%ebp) +c0107af7: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0107afb: 79 8b jns c0107a88 + } + + mm_destroy(mm);// 销毁 mm 结构 +c0107afd: 8b 45 e8 mov -0x18(%ebp),%eax +c0107b00: 89 04 24 mov %eax,(%esp) +c0107b03: e8 92 fa ff ff call c010759a + + // 确保释放的页面数量与初始记录一致 + assert(nr_free_pages_store == nr_free_pages()); +c0107b08: e8 3c ce ff ff call c0104949 +c0107b0d: 39 45 ec cmp %eax,-0x14(%ebp) +c0107b10: 74 24 je c0107b36 +c0107b12: c7 44 24 0c 70 a7 10 movl $0xc010a770,0xc(%esp) +c0107b19: c0 +c0107b1a: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107b21: c0 +c0107b22: c7 44 24 04 58 01 00 movl $0x158,0x4(%esp) +c0107b29: 00 +c0107b2a: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107b31: e8 0c 91 ff ff call c0100c42 <__panic> + // 输出成功信息 + cprintf("check_vma_struct() succeeded!\n"); +c0107b36: c7 04 24 f4 a8 10 c0 movl $0xc010a8f4,(%esp) +c0107b3d: e8 33 88 ff ff call c0100375 +} +c0107b42: 90 nop +c0107b43: 89 ec mov %ebp,%esp +c0107b45: 5d pop %ebp +c0107b46: c3 ret + +c0107b47 : +struct mm_struct *check_mm_struct; + +// check_pgfault - check correctness of pgfault handler +// 检查页故障处理的正确性 +static void +check_pgfault(void) { +c0107b47: 55 push %ebp +c0107b48: 89 e5 mov %esp,%ebp +c0107b4a: 83 ec 38 sub $0x38,%esp + // 保存当前空闲页面的数量,用于后续检查 + size_t nr_free_pages_store = nr_free_pages(); +c0107b4d: e8 f7 cd ff ff call c0104949 +c0107b52: 89 45 ec mov %eax,-0x14(%ebp) + // 创建内存管理结构体 + check_mm_struct = mm_create(); +c0107b55: e8 f8 f6 ff ff call c0107252 +c0107b5a: a3 6c 61 12 c0 mov %eax,0xc012616c + // 确保内存管理结构体创建成功 + assert(check_mm_struct != NULL); +c0107b5f: a1 6c 61 12 c0 mov 0xc012616c,%eax +c0107b64: 85 c0 test %eax,%eax +c0107b66: 75 24 jne c0107b8c +c0107b68: c7 44 24 0c 13 a9 10 movl $0xc010a913,0xc(%esp) +c0107b6f: c0 +c0107b70: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107b77: c0 +c0107b78: c7 44 24 04 68 01 00 movl $0x168,0x4(%esp) +c0107b7f: 00 +c0107b80: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107b87: e8 b6 90 ff ff call c0100c42 <__panic> + // 将新创建的内存管理结构体赋值给局部变量mm + struct mm_struct *mm = check_mm_struct; +c0107b8c: a1 6c 61 12 c0 mov 0xc012616c,%eax +c0107b91: 89 45 e8 mov %eax,-0x18(%ebp) + // 将引导程序的页目录复制到新创建的内存管理结构体中 + pde_t *pgdir = mm->pgdir = boot_pgdir; +c0107b94: 8b 15 e0 29 12 c0 mov 0xc01229e0,%edx +c0107b9a: 8b 45 e8 mov -0x18(%ebp),%eax +c0107b9d: 89 50 0c mov %edx,0xc(%eax) +c0107ba0: 8b 45 e8 mov -0x18(%ebp),%eax +c0107ba3: 8b 40 0c mov 0xc(%eax),%eax +c0107ba6: 89 45 e4 mov %eax,-0x1c(%ebp) + // 确保页目录的第0项是空的 + assert(pgdir[0] == 0); +c0107ba9: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107bac: 8b 00 mov (%eax),%eax +c0107bae: 85 c0 test %eax,%eax +c0107bb0: 74 24 je c0107bd6 +c0107bb2: c7 44 24 0c 2b a9 10 movl $0xc010a92b,0xc(%esp) +c0107bb9: c0 +c0107bba: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107bc1: c0 +c0107bc2: c7 44 24 04 6e 01 00 movl $0x16e,0x4(%esp) +c0107bc9: 00 +c0107bca: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107bd1: e8 6c 90 ff ff call c0100c42 <__panic> + // 创建一个虚拟内存区域结构体,具有写权限 + struct vma_struct *vma = vma_create(0, PTSIZE, VM_WRITE); +c0107bd6: c7 44 24 08 02 00 00 movl $0x2,0x8(%esp) +c0107bdd: 00 +c0107bde: c7 44 24 04 00 00 40 movl $0x400000,0x4(%esp) +c0107be5: 00 +c0107be6: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0107bed: e8 db f6 ff ff call c01072cd +c0107bf2: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保虚拟内存区域结构体创建成功 + assert(vma != NULL); +c0107bf5: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c0107bf9: 75 24 jne c0107c1f +c0107bfb: c7 44 24 0c ba a7 10 movl $0xc010a7ba,0xc(%esp) +c0107c02: c0 +c0107c03: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107c0a: c0 +c0107c0b: c7 44 24 04 72 01 00 movl $0x172,0x4(%esp) +c0107c12: 00 +c0107c13: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107c1a: e8 23 90 ff ff call c0100c42 <__panic> + // 将虚拟内存区域结构体插入到内存管理结构体中 + insert_vma_struct(mm, vma); +c0107c1f: 8b 45 e0 mov -0x20(%ebp),%eax +c0107c22: 89 44 24 04 mov %eax,0x4(%esp) +c0107c26: 8b 45 e8 mov -0x18(%ebp),%eax +c0107c29: 89 04 24 mov %eax,(%esp) +c0107c2c: e8 33 f8 ff ff call c0107464 + // 定义一个地址,用于访问虚拟内存 + uintptr_t addr = 0x100; +c0107c31: c7 45 dc 00 01 00 00 movl $0x100,-0x24(%ebp) + // 确保通过该地址可以找到之前插入的虚拟内存区域 + assert(find_vma(mm, addr) == vma); +c0107c38: 8b 45 dc mov -0x24(%ebp),%eax +c0107c3b: 89 44 24 04 mov %eax,0x4(%esp) +c0107c3f: 8b 45 e8 mov -0x18(%ebp),%eax +c0107c42: 89 04 24 mov %eax,(%esp) +c0107c45: e8 c0 f6 ff ff call c010730a +c0107c4a: 39 45 e0 cmp %eax,-0x20(%ebp) +c0107c4d: 74 24 je c0107c73 +c0107c4f: c7 44 24 0c 39 a9 10 movl $0xc010a939,0xc(%esp) +c0107c56: c0 +c0107c57: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107c5e: c0 +c0107c5f: c7 44 24 04 78 01 00 movl $0x178,0x4(%esp) +c0107c66: 00 +c0107c67: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107c6e: e8 cf 8f ff ff call c0100c42 <__panic> + // 初始化一个累加器,用于校验写入的数据 + int i, sum = 0; +c0107c73: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + // 写入数据到虚拟内存,并累加 + for (i = 0; i < 100; i ++) { +c0107c7a: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0107c81: eb 16 jmp c0107c99 + *(char *)(addr + i) = i; +c0107c83: 8b 55 f4 mov -0xc(%ebp),%edx +c0107c86: 8b 45 dc mov -0x24(%ebp),%eax +c0107c89: 01 d0 add %edx,%eax +c0107c8b: 8b 55 f4 mov -0xc(%ebp),%edx +c0107c8e: 88 10 mov %dl,(%eax) + sum += i; +c0107c90: 8b 45 f4 mov -0xc(%ebp),%eax +c0107c93: 01 45 f0 add %eax,-0x10(%ebp) + for (i = 0; i < 100; i ++) { +c0107c96: ff 45 f4 incl -0xc(%ebp) +c0107c99: 83 7d f4 63 cmpl $0x63,-0xc(%ebp) +c0107c9d: 7e e4 jle c0107c83 + } + // 读取虚拟内存中的数据,并减去,最终结果应为0 + for (i = 0; i < 100; i ++) { +c0107c9f: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0107ca6: eb 14 jmp c0107cbc + sum -= *(char *)(addr + i); +c0107ca8: 8b 55 f4 mov -0xc(%ebp),%edx +c0107cab: 8b 45 dc mov -0x24(%ebp),%eax +c0107cae: 01 d0 add %edx,%eax +c0107cb0: 0f b6 00 movzbl (%eax),%eax +c0107cb3: 0f be c0 movsbl %al,%eax +c0107cb6: 29 45 f0 sub %eax,-0x10(%ebp) + for (i = 0; i < 100; i ++) { +c0107cb9: ff 45 f4 incl -0xc(%ebp) +c0107cbc: 83 7d f4 63 cmpl $0x63,-0xc(%ebp) +c0107cc0: 7e e6 jle c0107ca8 + } + // 确保累加器的值为0,证明数据读写正确 + assert(sum == 0); +c0107cc2: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0107cc6: 74 24 je c0107cec +c0107cc8: c7 44 24 0c 53 a9 10 movl $0xc010a953,0xc(%esp) +c0107ccf: c0 +c0107cd0: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107cd7: c0 +c0107cd8: c7 44 24 04 85 01 00 movl $0x185,0x4(%esp) +c0107cdf: 00 +c0107ce0: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107ce7: e8 56 8f ff ff call c0100c42 <__panic> + // 移除页目录中的相应页面 + page_remove(pgdir, ROUNDDOWN(addr, PGSIZE)); +c0107cec: 8b 45 dc mov -0x24(%ebp),%eax +c0107cef: 89 45 d8 mov %eax,-0x28(%ebp) +c0107cf2: 8b 45 d8 mov -0x28(%ebp),%eax +c0107cf5: 25 00 f0 ff ff and $0xfffff000,%eax +c0107cfa: 89 44 24 04 mov %eax,0x4(%esp) +c0107cfe: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107d01: 89 04 24 mov %eax,(%esp) +c0107d04: e8 4e d4 ff ff call c0105157 + // 释放第0项页目录对应的页面 + free_page(pde2page(pgdir[0])); +c0107d09: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107d0c: 8b 00 mov (%eax),%eax +c0107d0e: 89 04 24 mov %eax,(%esp) +c0107d11: e8 22 f5 ff ff call c0107238 +c0107d16: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0107d1d: 00 +c0107d1e: 89 04 24 mov %eax,(%esp) +c0107d21: e8 ee cb ff ff call c0104914 + // 将页目录的第0项设置为空 + pgdir[0] = 0; +c0107d26: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107d29: c7 00 00 00 00 00 movl $0x0,(%eax) + // 将内存管理结构体中的页目录设置为空 + mm->pgdir = NULL; +c0107d2f: 8b 45 e8 mov -0x18(%ebp),%eax +c0107d32: c7 40 0c 00 00 00 00 movl $0x0,0xc(%eax) + // 销毁内存管理结构体 + mm_destroy(mm); +c0107d39: 8b 45 e8 mov -0x18(%ebp),%eax +c0107d3c: 89 04 24 mov %eax,(%esp) +c0107d3f: e8 56 f8 ff ff call c010759a + // 将检查用的内存管理结构体设置为空 + check_mm_struct = NULL; +c0107d44: c7 05 6c 61 12 c0 00 movl $0x0,0xc012616c +c0107d4b: 00 00 00 + // 确保空闲页面的数量没有变化,证明内存管理正确 + assert(nr_free_pages_store == nr_free_pages()); +c0107d4e: e8 f6 cb ff ff call c0104949 +c0107d53: 39 45 ec cmp %eax,-0x14(%ebp) +c0107d56: 74 24 je c0107d7c +c0107d58: c7 44 24 0c 70 a7 10 movl $0xc010a770,0xc(%esp) +c0107d5f: c0 +c0107d60: c7 44 24 08 ef a6 10 movl $0xc010a6ef,0x8(%esp) +c0107d67: c0 +c0107d68: c7 44 24 04 93 01 00 movl $0x193,0x4(%esp) +c0107d6f: 00 +c0107d70: c7 04 24 04 a7 10 c0 movl $0xc010a704,(%esp) +c0107d77: e8 c6 8e ff ff call c0100c42 <__panic> + // 打印成功信息 + cprintf("check_pgfault() succeeded!\n"); +c0107d7c: c7 04 24 5c a9 10 c0 movl $0xc010a95c,(%esp) +c0107d83: e8 ed 85 ff ff call c0100375 +} +c0107d88: 90 nop +c0107d89: 89 ec mov %ebp,%esp +c0107d8b: 5d pop %ebp +c0107d8c: c3 ret + +c0107d8d : + * @param addr 引发页面错误的线性地址。 + * + * @return 成功返回0,失败返回负错误码。 + */ +int +do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) { +c0107d8d: 55 push %ebp +c0107d8e: 89 e5 mov %esp,%ebp +c0107d90: 83 ec 38 sub $0x38,%esp + int ret = -E_INVAL;// 初始化返回值为无效错误 +c0107d93: c7 45 f4 fd ff ff ff movl $0xfffffffd,-0xc(%ebp) + //try to find a vma which include addr + // 尝试找到包含 addr 的 vma + struct vma_struct *vma = find_vma(mm, addr); +c0107d9a: 8b 45 10 mov 0x10(%ebp),%eax +c0107d9d: 89 44 24 04 mov %eax,0x4(%esp) +c0107da1: 8b 45 08 mov 0x8(%ebp),%eax +c0107da4: 89 04 24 mov %eax,(%esp) +c0107da7: e8 5e f5 ff ff call c010730a +c0107dac: 89 45 ec mov %eax,-0x14(%ebp) + + pgfault_num++;// 增加页面错误计数 +c0107daf: a1 70 61 12 c0 mov 0xc0126170,%eax +c0107db4: 40 inc %eax +c0107db5: a3 70 61 12 c0 mov %eax,0xc0126170 + // 检查 addr 是否在 mm 的 vma 范围内 + //If the addr is in the range of a mm's vma? + if (vma == NULL || vma->vm_start > addr) { +c0107dba: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0107dbe: 74 0b je c0107dcb +c0107dc0: 8b 45 ec mov -0x14(%ebp),%eax +c0107dc3: 8b 40 04 mov 0x4(%eax),%eax +c0107dc6: 39 45 10 cmp %eax,0x10(%ebp) +c0107dc9: 73 18 jae c0107de3 + cprintf("not valid addr %x, and can not find it in vma\n", addr); +c0107dcb: 8b 45 10 mov 0x10(%ebp),%eax +c0107dce: 89 44 24 04 mov %eax,0x4(%esp) +c0107dd2: c7 04 24 78 a9 10 c0 movl $0xc010a978,(%esp) +c0107dd9: e8 97 85 ff ff call c0100375 + goto failed;// 跳转到错误处理部分 +c0107dde: e9 ba 01 00 00 jmp c0107f9d + } + //check the error_code + // 检查错误代码 + switch (error_code & 3) { +c0107de3: 8b 45 0c mov 0xc(%ebp),%eax +c0107de6: 83 e0 03 and $0x3,%eax +c0107de9: 85 c0 test %eax,%eax +c0107deb: 74 34 je c0107e21 +c0107ded: 83 f8 01 cmp $0x1,%eax +c0107df0: 74 1e je c0107e10 + default: + /* 默认错误代码标志:3 (W/R=1, P=1): 写操作,存在 */ + /* error code flag : default is 3 ( W/R=1, P=1): write, present */ + case 2: /* error code flag : (W/R=1, P=0): write, not present */ + /* 错误代码标志:(W/R=1, P=0): 写操作,不存在 */ + if (!(vma->vm_flags & VM_WRITE)) { +c0107df2: 8b 45 ec mov -0x14(%ebp),%eax +c0107df5: 8b 40 0c mov 0xc(%eax),%eax +c0107df8: 83 e0 02 and $0x2,%eax +c0107dfb: 85 c0 test %eax,%eax +c0107dfd: 75 40 jne c0107e3f + cprintf("do_pgfault failed: error code flag = write AND not present, but the addr's vma cannot write\n"); +c0107dff: c7 04 24 a8 a9 10 c0 movl $0xc010a9a8,(%esp) +c0107e06: e8 6a 85 ff ff call c0100375 + goto failed;// 跳转到错误处理部分 +c0107e0b: e9 8d 01 00 00 jmp c0107f9d + } + break; + case 1: /* error code flag : (W/R=0, P=1): read, present */ + /* 错误代码标志:(W/R=0, P=1): 读操作,存在 */ + cprintf("do_pgfault failed: error code flag = read AND present\n"); +c0107e10: c7 04 24 08 aa 10 c0 movl $0xc010aa08,(%esp) +c0107e17: e8 59 85 ff ff call c0100375 + goto failed;// 跳转到错误处理部分 +c0107e1c: e9 7c 01 00 00 jmp c0107f9d + case 0: /* error code flag : (W/R=0, P=0): read, not present */ + /* 错误代码标志:(W/R=0, P=0): 读操作,不存在 */ + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) { +c0107e21: 8b 45 ec mov -0x14(%ebp),%eax +c0107e24: 8b 40 0c mov 0xc(%eax),%eax +c0107e27: 83 e0 05 and $0x5,%eax +c0107e2a: 85 c0 test %eax,%eax +c0107e2c: 75 12 jne c0107e40 + cprintf("do_pgfault failed: error code flag = read AND not present, but the addr's vma cannot read or exec\n"); +c0107e2e: c7 04 24 40 aa 10 c0 movl $0xc010aa40,(%esp) +c0107e35: e8 3b 85 ff ff call c0100375 + goto failed;// 跳转到错误处理部分 +c0107e3a: e9 5e 01 00 00 jmp c0107f9d + break; +c0107e3f: 90 nop + /* 如果 (写入已存在的地址) 或 + * (写入不存在的地址且地址可写) 或 + * (读取不存在的地址且地址可读) + * 则继续处理 + */ + uint32_t perm = PTE_U;// 初始化权限标志为用户可访问 +c0107e40: c7 45 f0 04 00 00 00 movl $0x4,-0x10(%ebp) + if (vma->vm_flags & VM_WRITE) { +c0107e47: 8b 45 ec mov -0x14(%ebp),%eax +c0107e4a: 8b 40 0c mov 0xc(%eax),%eax +c0107e4d: 83 e0 02 and $0x2,%eax +c0107e50: 85 c0 test %eax,%eax +c0107e52: 74 04 je c0107e58 + perm |= PTE_W;// 如果 vma 可写,则设置写权限 +c0107e54: 83 4d f0 02 orl $0x2,-0x10(%ebp) + } + addr = ROUNDDOWN(addr, PGSIZE);// 将地址对齐到页边界 +c0107e58: 8b 45 10 mov 0x10(%ebp),%eax +c0107e5b: 89 45 e8 mov %eax,-0x18(%ebp) +c0107e5e: 8b 45 e8 mov -0x18(%ebp),%eax +c0107e61: 25 00 f0 ff ff and $0xfffff000,%eax +c0107e66: 89 45 10 mov %eax,0x10(%ebp) + + ret = -E_NO_MEM;// 初始化返回值为内存不足错误 +c0107e69: c7 45 f4 fc ff ff ff movl $0xfffffffc,-0xc(%ebp) + + pte_t *ptep=NULL; +c0107e70: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +#endif + // try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT. + // (notice the 3th parameter '1') + // 尝试找到一个页表项 pte,如果包含该 pte 的页表不存在,则创建一个页表。 + // 注意第三个参数 '1' 表示如果需要,可以创建新的页表。 + if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) { +c0107e77: 8b 45 08 mov 0x8(%ebp),%eax +c0107e7a: 8b 40 0c mov 0xc(%eax),%eax +c0107e7d: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c0107e84: 00 +c0107e85: 8b 55 10 mov 0x10(%ebp),%edx +c0107e88: 89 54 24 04 mov %edx,0x4(%esp) +c0107e8c: 89 04 24 mov %eax,(%esp) +c0107e8f: e8 c9 d0 ff ff call c0104f5d +c0107e94: 89 45 e4 mov %eax,-0x1c(%ebp) +c0107e97: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0107e9b: 75 11 jne c0107eae + cprintf("get_pte in do_pgfault failed\n");// 输出错误信息 +c0107e9d: c7 04 24 a3 aa 10 c0 movl $0xc010aaa3,(%esp) +c0107ea4: e8 cc 84 ff ff call c0100375 + goto failed;// 跳转到错误处理部分 +c0107ea9: e9 ef 00 00 00 jmp c0107f9d + } + // 如果页表项 pte 的物理地址不存在,则分配一页内存并映射物理地址与逻辑地址 + if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr +c0107eae: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107eb1: 8b 00 mov (%eax),%eax +c0107eb3: 85 c0 test %eax,%eax +c0107eb5: 75 35 jne c0107eec + if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) { +c0107eb7: 8b 45 08 mov 0x8(%ebp),%eax +c0107eba: 8b 40 0c mov 0xc(%eax),%eax +c0107ebd: 8b 55 f0 mov -0x10(%ebp),%edx +c0107ec0: 89 54 24 08 mov %edx,0x8(%esp) +c0107ec4: 8b 55 10 mov 0x10(%ebp),%edx +c0107ec7: 89 54 24 04 mov %edx,0x4(%esp) +c0107ecb: 89 04 24 mov %eax,(%esp) +c0107ece: e8 e5 d3 ff ff call c01052b8 +c0107ed3: 85 c0 test %eax,%eax +c0107ed5: 0f 85 bb 00 00 00 jne c0107f96 + cprintf("pgdir_alloc_page in do_pgfault failed\n");// 输出错误信息 +c0107edb: c7 04 24 c4 aa 10 c0 movl $0xc010aac4,(%esp) +c0107ee2: e8 8e 84 ff ff call c0100375 + goto failed;// 跳转到错误处理部分 +c0107ee7: e9 b1 00 00 00 jmp c0107f9d + } + else { // if this pte is a swap entry, then load data from disk to a page with phy addr + // and call page_insert to map the phy addr with logical addr + // 如果页表项 pte 是一个交换项,则从磁盘加载数据到 + //一个具有物理地址的页面,并映射物理地址与逻辑地址 + if(swap_init_ok) {// 检查交换初始化是否成功 +c0107eec: a1 a4 60 12 c0 mov 0xc01260a4,%eax +c0107ef1: 85 c0 test %eax,%eax +c0107ef3: 0f 84 86 00 00 00 je c0107f7f + struct Page *page=NULL;// 声明一个页面指针 +c0107ef9: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) + if ((ret = swap_in(mm, addr, &page)) != 0) { +c0107f00: 8d 45 e0 lea -0x20(%ebp),%eax +c0107f03: 89 44 24 08 mov %eax,0x8(%esp) +c0107f07: 8b 45 10 mov 0x10(%ebp),%eax +c0107f0a: 89 44 24 04 mov %eax,0x4(%esp) +c0107f0e: 8b 45 08 mov 0x8(%ebp),%eax +c0107f11: 89 04 24 mov %eax,(%esp) +c0107f14: e8 69 e5 ff ff call c0106482 +c0107f19: 89 45 f4 mov %eax,-0xc(%ebp) +c0107f1c: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0107f20: 74 0e je c0107f30 + cprintf("swap_in in do_pgfault failed\n"); +c0107f22: c7 04 24 eb aa 10 c0 movl $0xc010aaeb,(%esp) +c0107f29: e8 47 84 ff ff call c0100375 +c0107f2e: eb 6d jmp c0107f9d + goto failed; + } + page_insert(mm->pgdir, page, addr, perm);// 设置物理地址与逻辑地址的映射 +c0107f30: 8b 55 e0 mov -0x20(%ebp),%edx +c0107f33: 8b 45 08 mov 0x8(%ebp),%eax +c0107f36: 8b 40 0c mov 0xc(%eax),%eax +c0107f39: 8b 4d f0 mov -0x10(%ebp),%ecx +c0107f3c: 89 4c 24 0c mov %ecx,0xc(%esp) +c0107f40: 8b 4d 10 mov 0x10(%ebp),%ecx +c0107f43: 89 4c 24 08 mov %ecx,0x8(%esp) +c0107f47: 89 54 24 04 mov %edx,0x4(%esp) +c0107f4b: 89 04 24 mov %eax,(%esp) +c0107f4e: e8 4b d2 ff ff call c010519e + swap_map_swappable(mm, addr, page, 1);// 设置页面可交换 +c0107f53: 8b 45 e0 mov -0x20(%ebp),%eax +c0107f56: c7 44 24 0c 01 00 00 movl $0x1,0xc(%esp) +c0107f5d: 00 +c0107f5e: 89 44 24 08 mov %eax,0x8(%esp) +c0107f62: 8b 45 10 mov 0x10(%ebp),%eax +c0107f65: 89 44 24 04 mov %eax,0x4(%esp) +c0107f69: 8b 45 08 mov 0x8(%ebp),%eax +c0107f6c: 89 04 24 mov %eax,(%esp) +c0107f6f: e8 46 e3 ff ff call c01062ba + page->pra_vaddr = addr;// 记录页面的虚拟地址 +c0107f74: 8b 45 e0 mov -0x20(%ebp),%eax +c0107f77: 8b 55 10 mov 0x10(%ebp),%edx +c0107f7a: 89 50 1c mov %edx,0x1c(%eax) +c0107f7d: eb 17 jmp c0107f96 + } + else { + cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep); +c0107f7f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0107f82: 8b 00 mov (%eax),%eax +c0107f84: 89 44 24 04 mov %eax,0x4(%esp) +c0107f88: c7 04 24 0c ab 10 c0 movl $0xc010ab0c,(%esp) +c0107f8f: e8 e1 83 ff ff call c0100375 + goto failed;// 跳转到错误处理部分 +c0107f94: eb 07 jmp c0107f9d + } + } + ret = 0;// 设置返回值为成功 +c0107f96: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +failed: + return ret;// 返回结果 +c0107f9d: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0107fa0: 89 ec mov %ebp,%esp +c0107fa2: 5d pop %ebp +c0107fa3: c3 ret + +c0107fa4 : +page2ppn(struct Page *page) { +c0107fa4: 55 push %ebp +c0107fa5: 89 e5 mov %esp,%ebp + return page - pages; +c0107fa7: 8b 15 00 60 12 c0 mov 0xc0126000,%edx +c0107fad: 8b 45 08 mov 0x8(%ebp),%eax +c0107fb0: 29 d0 sub %edx,%eax +c0107fb2: c1 f8 05 sar $0x5,%eax +} +c0107fb5: 5d pop %ebp +c0107fb6: c3 ret + +c0107fb7 : +page2pa(struct Page *page) { +c0107fb7: 55 push %ebp +c0107fb8: 89 e5 mov %esp,%ebp +c0107fba: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0107fbd: 8b 45 08 mov 0x8(%ebp),%eax +c0107fc0: 89 04 24 mov %eax,(%esp) +c0107fc3: e8 dc ff ff ff call c0107fa4 +c0107fc8: c1 e0 0c shl $0xc,%eax +} +c0107fcb: 89 ec mov %ebp,%esp +c0107fcd: 5d pop %ebp +c0107fce: c3 ret + +c0107fcf : +page2kva(struct Page *page) { +c0107fcf: 55 push %ebp +c0107fd0: 89 e5 mov %esp,%ebp +c0107fd2: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c0107fd5: 8b 45 08 mov 0x8(%ebp),%eax +c0107fd8: 89 04 24 mov %eax,(%esp) +c0107fdb: e8 d7 ff ff ff call c0107fb7 +c0107fe0: 89 45 f4 mov %eax,-0xc(%ebp) +c0107fe3: 8b 45 f4 mov -0xc(%ebp),%eax +c0107fe6: c1 e8 0c shr $0xc,%eax +c0107fe9: 89 45 f0 mov %eax,-0x10(%ebp) +c0107fec: a1 04 60 12 c0 mov 0xc0126004,%eax +c0107ff1: 39 45 f0 cmp %eax,-0x10(%ebp) +c0107ff4: 72 23 jb c0108019 +c0107ff6: 8b 45 f4 mov -0xc(%ebp),%eax +c0107ff9: 89 44 24 0c mov %eax,0xc(%esp) +c0107ffd: c7 44 24 08 34 ab 10 movl $0xc010ab34,0x8(%esp) +c0108004: c0 +c0108005: c7 44 24 04 62 00 00 movl $0x62,0x4(%esp) +c010800c: 00 +c010800d: c7 04 24 57 ab 10 c0 movl $0xc010ab57,(%esp) +c0108014: e8 29 8c ff ff call c0100c42 <__panic> +c0108019: 8b 45 f4 mov -0xc(%ebp),%eax +c010801c: 2d 00 00 00 40 sub $0x40000000,%eax +} +c0108021: 89 ec mov %ebp,%esp +c0108023: 5d pop %ebp +c0108024: c3 ret + +c0108025 : +#include +#include +#include + +void +swapfs_init(void) { +c0108025: 55 push %ebp +c0108026: 89 e5 mov %esp,%ebp +c0108028: 83 ec 18 sub $0x18,%esp + static_assert((PGSIZE % SECTSIZE) == 0); + if (!ide_device_valid(SWAP_DEV_NO)) { +c010802b: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0108032: e8 ba 99 ff ff call c01019f1 +c0108037: 85 c0 test %eax,%eax +c0108039: 75 1c jne c0108057 + panic("swap fs isn't available.\n"); +c010803b: c7 44 24 08 65 ab 10 movl $0xc010ab65,0x8(%esp) +c0108042: c0 +c0108043: c7 44 24 04 0d 00 00 movl $0xd,0x4(%esp) +c010804a: 00 +c010804b: c7 04 24 7f ab 10 c0 movl $0xc010ab7f,(%esp) +c0108052: e8 eb 8b ff ff call c0100c42 <__panic> + } + max_swap_offset = ide_device_size(SWAP_DEV_NO) / (PGSIZE / SECTSIZE); +c0108057: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010805e: e8 ce 99 ff ff call c0101a31 +c0108063: c1 e8 03 shr $0x3,%eax +c0108066: a3 a0 60 12 c0 mov %eax,0xc01260a0 +} +c010806b: 90 nop +c010806c: 89 ec mov %ebp,%esp +c010806e: 5d pop %ebp +c010806f: c3 ret + +c0108070 : +//entry:表示要读取的交换条目。page:指向要填充的内存页的指针。 +//函数返回 ide_read_secs 的结果,表示读取操作是否成功 +//计算交换条目的偏移量 swap_offset(entry)。 +//使用 ide_read_secs 函数从交换设备 SWAP_DEV_NO 中读取指定数量的扇区(PAGE_NSECT)到内存页 page2kva(page) 中。 +int +swapfs_read(swap_entry_t entry, struct Page *page) { +c0108070: 55 push %ebp +c0108071: 89 e5 mov %esp,%ebp +c0108073: 83 ec 28 sub $0x28,%esp + return ide_read_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT); +c0108076: 8b 45 0c mov 0xc(%ebp),%eax +c0108079: 89 04 24 mov %eax,(%esp) +c010807c: e8 4e ff ff ff call c0107fcf +c0108081: 8b 55 08 mov 0x8(%ebp),%edx +c0108084: c1 ea 08 shr $0x8,%edx +c0108087: 89 55 f4 mov %edx,-0xc(%ebp) +c010808a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010808e: 74 0b je c010809b +c0108090: 8b 15 a0 60 12 c0 mov 0xc01260a0,%edx +c0108096: 39 55 f4 cmp %edx,-0xc(%ebp) +c0108099: 72 23 jb c01080be +c010809b: 8b 45 08 mov 0x8(%ebp),%eax +c010809e: 89 44 24 0c mov %eax,0xc(%esp) +c01080a2: c7 44 24 08 90 ab 10 movl $0xc010ab90,0x8(%esp) +c01080a9: c0 +c01080aa: c7 44 24 04 18 00 00 movl $0x18,0x4(%esp) +c01080b1: 00 +c01080b2: c7 04 24 7f ab 10 c0 movl $0xc010ab7f,(%esp) +c01080b9: e8 84 8b ff ff call c0100c42 <__panic> +c01080be: 8b 55 f4 mov -0xc(%ebp),%edx +c01080c1: c1 e2 03 shl $0x3,%edx +c01080c4: c7 44 24 0c 08 00 00 movl $0x8,0xc(%esp) +c01080cb: 00 +c01080cc: 89 44 24 08 mov %eax,0x8(%esp) +c01080d0: 89 54 24 04 mov %edx,0x4(%esp) +c01080d4: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01080db: e8 8e 99 ff ff call c0101a6e +} +c01080e0: 89 ec mov %ebp,%esp +c01080e2: 5d pop %ebp +c01080e3: c3 ret + +c01080e4 : + +int +swapfs_write(swap_entry_t entry, struct Page *page) { +c01080e4: 55 push %ebp +c01080e5: 89 e5 mov %esp,%ebp +c01080e7: 83 ec 28 sub $0x28,%esp + return ide_write_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT); +c01080ea: 8b 45 0c mov 0xc(%ebp),%eax +c01080ed: 89 04 24 mov %eax,(%esp) +c01080f0: e8 da fe ff ff call c0107fcf +c01080f5: 8b 55 08 mov 0x8(%ebp),%edx +c01080f8: c1 ea 08 shr $0x8,%edx +c01080fb: 89 55 f4 mov %edx,-0xc(%ebp) +c01080fe: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0108102: 74 0b je c010810f +c0108104: 8b 15 a0 60 12 c0 mov 0xc01260a0,%edx +c010810a: 39 55 f4 cmp %edx,-0xc(%ebp) +c010810d: 72 23 jb c0108132 +c010810f: 8b 45 08 mov 0x8(%ebp),%eax +c0108112: 89 44 24 0c mov %eax,0xc(%esp) +c0108116: c7 44 24 08 90 ab 10 movl $0xc010ab90,0x8(%esp) +c010811d: c0 +c010811e: c7 44 24 04 1d 00 00 movl $0x1d,0x4(%esp) +c0108125: 00 +c0108126: c7 04 24 7f ab 10 c0 movl $0xc010ab7f,(%esp) +c010812d: e8 10 8b ff ff call c0100c42 <__panic> +c0108132: 8b 55 f4 mov -0xc(%ebp),%edx +c0108135: c1 e2 03 shl $0x3,%edx +c0108138: c7 44 24 0c 08 00 00 movl $0x8,0xc(%esp) +c010813f: 00 +c0108140: 89 44 24 08 mov %eax,0x8(%esp) +c0108144: 89 54 24 04 mov %edx,0x4(%esp) +c0108148: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010814f: e8 5b 9b ff ff call c0101caf +} +c0108154: 89 ec mov %ebp,%esp +c0108156: 5d pop %ebp +c0108157: c3 ret + +c0108158 : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { +c0108158: 55 push %ebp +c0108159: 89 e5 mov %esp,%ebp +c010815b: 83 ec 58 sub $0x58,%esp +c010815e: 8b 45 10 mov 0x10(%ebp),%eax +c0108161: 89 45 d0 mov %eax,-0x30(%ebp) +c0108164: 8b 45 14 mov 0x14(%ebp),%eax +c0108167: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; +c010816a: 8b 45 d0 mov -0x30(%ebp),%eax +c010816d: 8b 55 d4 mov -0x2c(%ebp),%edx +c0108170: 89 45 e8 mov %eax,-0x18(%ebp) +c0108173: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); +c0108176: 8b 45 18 mov 0x18(%ebp),%eax +c0108179: 89 45 e4 mov %eax,-0x1c(%ebp) +c010817c: 8b 45 e8 mov -0x18(%ebp),%eax +c010817f: 8b 55 ec mov -0x14(%ebp),%edx +c0108182: 89 45 e0 mov %eax,-0x20(%ebp) +c0108185: 89 55 f0 mov %edx,-0x10(%ebp) +c0108188: 8b 45 f0 mov -0x10(%ebp),%eax +c010818b: 89 45 f4 mov %eax,-0xc(%ebp) +c010818e: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0108192: 74 1c je c01081b0 +c0108194: 8b 45 f0 mov -0x10(%ebp),%eax +c0108197: ba 00 00 00 00 mov $0x0,%edx +c010819c: f7 75 e4 divl -0x1c(%ebp) +c010819f: 89 55 f4 mov %edx,-0xc(%ebp) +c01081a2: 8b 45 f0 mov -0x10(%ebp),%eax +c01081a5: ba 00 00 00 00 mov $0x0,%edx +c01081aa: f7 75 e4 divl -0x1c(%ebp) +c01081ad: 89 45 f0 mov %eax,-0x10(%ebp) +c01081b0: 8b 45 e0 mov -0x20(%ebp),%eax +c01081b3: 8b 55 f4 mov -0xc(%ebp),%edx +c01081b6: f7 75 e4 divl -0x1c(%ebp) +c01081b9: 89 45 e0 mov %eax,-0x20(%ebp) +c01081bc: 89 55 dc mov %edx,-0x24(%ebp) +c01081bf: 8b 45 e0 mov -0x20(%ebp),%eax +c01081c2: 8b 55 f0 mov -0x10(%ebp),%edx +c01081c5: 89 45 e8 mov %eax,-0x18(%ebp) +c01081c8: 89 55 ec mov %edx,-0x14(%ebp) +c01081cb: 8b 45 dc mov -0x24(%ebp),%eax +c01081ce: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { +c01081d1: 8b 45 18 mov 0x18(%ebp),%eax +c01081d4: ba 00 00 00 00 mov $0x0,%edx +c01081d9: 8b 4d d4 mov -0x2c(%ebp),%ecx +c01081dc: 39 45 d0 cmp %eax,-0x30(%ebp) +c01081df: 19 d1 sbb %edx,%ecx +c01081e1: 72 4c jb c010822f + printnum(putch, putdat, result, base, width - 1, padc); +c01081e3: 8b 45 1c mov 0x1c(%ebp),%eax +c01081e6: 8d 50 ff lea -0x1(%eax),%edx +c01081e9: 8b 45 20 mov 0x20(%ebp),%eax +c01081ec: 89 44 24 18 mov %eax,0x18(%esp) +c01081f0: 89 54 24 14 mov %edx,0x14(%esp) +c01081f4: 8b 45 18 mov 0x18(%ebp),%eax +c01081f7: 89 44 24 10 mov %eax,0x10(%esp) +c01081fb: 8b 45 e8 mov -0x18(%ebp),%eax +c01081fe: 8b 55 ec mov -0x14(%ebp),%edx +c0108201: 89 44 24 08 mov %eax,0x8(%esp) +c0108205: 89 54 24 0c mov %edx,0xc(%esp) +c0108209: 8b 45 0c mov 0xc(%ebp),%eax +c010820c: 89 44 24 04 mov %eax,0x4(%esp) +c0108210: 8b 45 08 mov 0x8(%ebp),%eax +c0108213: 89 04 24 mov %eax,(%esp) +c0108216: e8 3d ff ff ff call c0108158 +c010821b: eb 1b jmp c0108238 + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); +c010821d: 8b 45 0c mov 0xc(%ebp),%eax +c0108220: 89 44 24 04 mov %eax,0x4(%esp) +c0108224: 8b 45 20 mov 0x20(%ebp),%eax +c0108227: 89 04 24 mov %eax,(%esp) +c010822a: 8b 45 08 mov 0x8(%ebp),%eax +c010822d: ff d0 call *%eax + while (-- width > 0) +c010822f: ff 4d 1c decl 0x1c(%ebp) +c0108232: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c0108236: 7f e5 jg c010821d + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); +c0108238: 8b 45 d8 mov -0x28(%ebp),%eax +c010823b: 05 30 ac 10 c0 add $0xc010ac30,%eax +c0108240: 0f b6 00 movzbl (%eax),%eax +c0108243: 0f be c0 movsbl %al,%eax +c0108246: 8b 55 0c mov 0xc(%ebp),%edx +c0108249: 89 54 24 04 mov %edx,0x4(%esp) +c010824d: 89 04 24 mov %eax,(%esp) +c0108250: 8b 45 08 mov 0x8(%ebp),%eax +c0108253: ff d0 call *%eax +} +c0108255: 90 nop +c0108256: 89 ec mov %ebp,%esp +c0108258: 5d pop %ebp +c0108259: c3 ret + +c010825a : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { +c010825a: 55 push %ebp +c010825b: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c010825d: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c0108261: 7e 14 jle c0108277 + return va_arg(*ap, unsigned long long); +c0108263: 8b 45 08 mov 0x8(%ebp),%eax +c0108266: 8b 00 mov (%eax),%eax +c0108268: 8d 48 08 lea 0x8(%eax),%ecx +c010826b: 8b 55 08 mov 0x8(%ebp),%edx +c010826e: 89 0a mov %ecx,(%edx) +c0108270: 8b 50 04 mov 0x4(%eax),%edx +c0108273: 8b 00 mov (%eax),%eax +c0108275: eb 30 jmp c01082a7 + } + else if (lflag) { +c0108277: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010827b: 74 16 je c0108293 + return va_arg(*ap, unsigned long); +c010827d: 8b 45 08 mov 0x8(%ebp),%eax +c0108280: 8b 00 mov (%eax),%eax +c0108282: 8d 48 04 lea 0x4(%eax),%ecx +c0108285: 8b 55 08 mov 0x8(%ebp),%edx +c0108288: 89 0a mov %ecx,(%edx) +c010828a: 8b 00 mov (%eax),%eax +c010828c: ba 00 00 00 00 mov $0x0,%edx +c0108291: eb 14 jmp c01082a7 + } + else { + return va_arg(*ap, unsigned int); +c0108293: 8b 45 08 mov 0x8(%ebp),%eax +c0108296: 8b 00 mov (%eax),%eax +c0108298: 8d 48 04 lea 0x4(%eax),%ecx +c010829b: 8b 55 08 mov 0x8(%ebp),%edx +c010829e: 89 0a mov %ecx,(%edx) +c01082a0: 8b 00 mov (%eax),%eax +c01082a2: ba 00 00 00 00 mov $0x0,%edx + } +} +c01082a7: 5d pop %ebp +c01082a8: c3 ret + +c01082a9 : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { +c01082a9: 55 push %ebp +c01082aa: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c01082ac: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c01082b0: 7e 14 jle c01082c6 + return va_arg(*ap, long long); +c01082b2: 8b 45 08 mov 0x8(%ebp),%eax +c01082b5: 8b 00 mov (%eax),%eax +c01082b7: 8d 48 08 lea 0x8(%eax),%ecx +c01082ba: 8b 55 08 mov 0x8(%ebp),%edx +c01082bd: 89 0a mov %ecx,(%edx) +c01082bf: 8b 50 04 mov 0x4(%eax),%edx +c01082c2: 8b 00 mov (%eax),%eax +c01082c4: eb 28 jmp c01082ee + } + else if (lflag) { +c01082c6: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01082ca: 74 12 je c01082de + return va_arg(*ap, long); +c01082cc: 8b 45 08 mov 0x8(%ebp),%eax +c01082cf: 8b 00 mov (%eax),%eax +c01082d1: 8d 48 04 lea 0x4(%eax),%ecx +c01082d4: 8b 55 08 mov 0x8(%ebp),%edx +c01082d7: 89 0a mov %ecx,(%edx) +c01082d9: 8b 00 mov (%eax),%eax +c01082db: 99 cltd +c01082dc: eb 10 jmp c01082ee + } + else { + return va_arg(*ap, int); +c01082de: 8b 45 08 mov 0x8(%ebp),%eax +c01082e1: 8b 00 mov (%eax),%eax +c01082e3: 8d 48 04 lea 0x4(%eax),%ecx +c01082e6: 8b 55 08 mov 0x8(%ebp),%edx +c01082e9: 89 0a mov %ecx,(%edx) +c01082eb: 8b 00 mov (%eax),%eax +c01082ed: 99 cltd + } +} +c01082ee: 5d pop %ebp +c01082ef: c3 ret + +c01082f0 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { +c01082f0: 55 push %ebp +c01082f1: 89 e5 mov %esp,%ebp +c01082f3: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); +c01082f6: 8d 45 14 lea 0x14(%ebp),%eax +c01082f9: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); +c01082fc: 8b 45 f4 mov -0xc(%ebp),%eax +c01082ff: 89 44 24 0c mov %eax,0xc(%esp) +c0108303: 8b 45 10 mov 0x10(%ebp),%eax +c0108306: 89 44 24 08 mov %eax,0x8(%esp) +c010830a: 8b 45 0c mov 0xc(%ebp),%eax +c010830d: 89 44 24 04 mov %eax,0x4(%esp) +c0108311: 8b 45 08 mov 0x8(%ebp),%eax +c0108314: 89 04 24 mov %eax,(%esp) +c0108317: e8 05 00 00 00 call c0108321 + va_end(ap); +} +c010831c: 90 nop +c010831d: 89 ec mov %ebp,%esp +c010831f: 5d pop %ebp +c0108320: c3 ret + +c0108321 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { +c0108321: 55 push %ebp +c0108322: 89 e5 mov %esp,%ebp +c0108324: 56 push %esi +c0108325: 53 push %ebx +c0108326: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { +c0108329: eb 17 jmp c0108342 + if (ch == '\0') { +c010832b: 85 db test %ebx,%ebx +c010832d: 0f 84 bf 03 00 00 je c01086f2 + return; + } + putch(ch, putdat); +c0108333: 8b 45 0c mov 0xc(%ebp),%eax +c0108336: 89 44 24 04 mov %eax,0x4(%esp) +c010833a: 89 1c 24 mov %ebx,(%esp) +c010833d: 8b 45 08 mov 0x8(%ebp),%eax +c0108340: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { +c0108342: 8b 45 10 mov 0x10(%ebp),%eax +c0108345: 8d 50 01 lea 0x1(%eax),%edx +c0108348: 89 55 10 mov %edx,0x10(%ebp) +c010834b: 0f b6 00 movzbl (%eax),%eax +c010834e: 0f b6 d8 movzbl %al,%ebx +c0108351: 83 fb 25 cmp $0x25,%ebx +c0108354: 75 d5 jne c010832b + } + + // Process a %-escape sequence + char padc = ' '; +c0108356: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; +c010835a: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) +c0108361: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108364: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; +c0108367: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c010836e: 8b 45 dc mov -0x24(%ebp),%eax +c0108371: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { +c0108374: 8b 45 10 mov 0x10(%ebp),%eax +c0108377: 8d 50 01 lea 0x1(%eax),%edx +c010837a: 89 55 10 mov %edx,0x10(%ebp) +c010837d: 0f b6 00 movzbl (%eax),%eax +c0108380: 0f b6 d8 movzbl %al,%ebx +c0108383: 8d 43 dd lea -0x23(%ebx),%eax +c0108386: 83 f8 55 cmp $0x55,%eax +c0108389: 0f 87 37 03 00 00 ja c01086c6 +c010838f: 8b 04 85 54 ac 10 c0 mov -0x3fef53ac(,%eax,4),%eax +c0108396: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; +c0108398: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; +c010839c: eb d6 jmp c0108374 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; +c010839e: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; +c01083a2: eb d0 jmp c0108374 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { +c01083a4: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; +c01083ab: 8b 55 e4 mov -0x1c(%ebp),%edx +c01083ae: 89 d0 mov %edx,%eax +c01083b0: c1 e0 02 shl $0x2,%eax +c01083b3: 01 d0 add %edx,%eax +c01083b5: 01 c0 add %eax,%eax +c01083b7: 01 d8 add %ebx,%eax +c01083b9: 83 e8 30 sub $0x30,%eax +c01083bc: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; +c01083bf: 8b 45 10 mov 0x10(%ebp),%eax +c01083c2: 0f b6 00 movzbl (%eax),%eax +c01083c5: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { +c01083c8: 83 fb 2f cmp $0x2f,%ebx +c01083cb: 7e 38 jle c0108405 +c01083cd: 83 fb 39 cmp $0x39,%ebx +c01083d0: 7f 33 jg c0108405 + for (precision = 0; ; ++ fmt) { +c01083d2: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; +c01083d5: eb d4 jmp c01083ab + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); +c01083d7: 8b 45 14 mov 0x14(%ebp),%eax +c01083da: 8d 50 04 lea 0x4(%eax),%edx +c01083dd: 89 55 14 mov %edx,0x14(%ebp) +c01083e0: 8b 00 mov (%eax),%eax +c01083e2: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; +c01083e5: eb 1f jmp c0108406 + + case '.': + if (width < 0) +c01083e7: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01083eb: 79 87 jns c0108374 + width = 0; +c01083ed: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; +c01083f4: e9 7b ff ff ff jmp c0108374 + + case '#': + altflag = 1; +c01083f9: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; +c0108400: e9 6f ff ff ff jmp c0108374 + goto process_precision; +c0108405: 90 nop + + process_precision: + if (width < 0) +c0108406: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010840a: 0f 89 64 ff ff ff jns c0108374 + width = precision, precision = -1; +c0108410: 8b 45 e4 mov -0x1c(%ebp),%eax +c0108413: 89 45 e8 mov %eax,-0x18(%ebp) +c0108416: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; +c010841d: e9 52 ff ff ff jmp c0108374 + + // long flag (doubled for long long) + case 'l': + lflag ++; +c0108422: ff 45 e0 incl -0x20(%ebp) + goto reswitch; +c0108425: e9 4a ff ff ff jmp c0108374 + + // character + case 'c': + putch(va_arg(ap, int), putdat); +c010842a: 8b 45 14 mov 0x14(%ebp),%eax +c010842d: 8d 50 04 lea 0x4(%eax),%edx +c0108430: 89 55 14 mov %edx,0x14(%ebp) +c0108433: 8b 00 mov (%eax),%eax +c0108435: 8b 55 0c mov 0xc(%ebp),%edx +c0108438: 89 54 24 04 mov %edx,0x4(%esp) +c010843c: 89 04 24 mov %eax,(%esp) +c010843f: 8b 45 08 mov 0x8(%ebp),%eax +c0108442: ff d0 call *%eax + break; +c0108444: e9 a4 02 00 00 jmp c01086ed + + // error message + case 'e': + err = va_arg(ap, int); +c0108449: 8b 45 14 mov 0x14(%ebp),%eax +c010844c: 8d 50 04 lea 0x4(%eax),%edx +c010844f: 89 55 14 mov %edx,0x14(%ebp) +c0108452: 8b 18 mov (%eax),%ebx + if (err < 0) { +c0108454: 85 db test %ebx,%ebx +c0108456: 79 02 jns c010845a + err = -err; +c0108458: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { +c010845a: 83 fb 06 cmp $0x6,%ebx +c010845d: 7f 0b jg c010846a +c010845f: 8b 34 9d 14 ac 10 c0 mov -0x3fef53ec(,%ebx,4),%esi +c0108466: 85 f6 test %esi,%esi +c0108468: 75 23 jne c010848d + printfmt(putch, putdat, "error %d", err); +c010846a: 89 5c 24 0c mov %ebx,0xc(%esp) +c010846e: c7 44 24 08 41 ac 10 movl $0xc010ac41,0x8(%esp) +c0108475: c0 +c0108476: 8b 45 0c mov 0xc(%ebp),%eax +c0108479: 89 44 24 04 mov %eax,0x4(%esp) +c010847d: 8b 45 08 mov 0x8(%ebp),%eax +c0108480: 89 04 24 mov %eax,(%esp) +c0108483: e8 68 fe ff ff call c01082f0 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; +c0108488: e9 60 02 00 00 jmp c01086ed + printfmt(putch, putdat, "%s", p); +c010848d: 89 74 24 0c mov %esi,0xc(%esp) +c0108491: c7 44 24 08 4a ac 10 movl $0xc010ac4a,0x8(%esp) +c0108498: c0 +c0108499: 8b 45 0c mov 0xc(%ebp),%eax +c010849c: 89 44 24 04 mov %eax,0x4(%esp) +c01084a0: 8b 45 08 mov 0x8(%ebp),%eax +c01084a3: 89 04 24 mov %eax,(%esp) +c01084a6: e8 45 fe ff ff call c01082f0 + break; +c01084ab: e9 3d 02 00 00 jmp c01086ed + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { +c01084b0: 8b 45 14 mov 0x14(%ebp),%eax +c01084b3: 8d 50 04 lea 0x4(%eax),%edx +c01084b6: 89 55 14 mov %edx,0x14(%ebp) +c01084b9: 8b 30 mov (%eax),%esi +c01084bb: 85 f6 test %esi,%esi +c01084bd: 75 05 jne c01084c4 + p = "(null)"; +c01084bf: be 4d ac 10 c0 mov $0xc010ac4d,%esi + } + if (width > 0 && padc != '-') { +c01084c4: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01084c8: 7e 76 jle c0108540 +c01084ca: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) +c01084ce: 74 70 je c0108540 + for (width -= strnlen(p, precision); width > 0; width --) { +c01084d0: 8b 45 e4 mov -0x1c(%ebp),%eax +c01084d3: 89 44 24 04 mov %eax,0x4(%esp) +c01084d7: 89 34 24 mov %esi,(%esp) +c01084da: e8 ee 03 00 00 call c01088cd +c01084df: 89 c2 mov %eax,%edx +c01084e1: 8b 45 e8 mov -0x18(%ebp),%eax +c01084e4: 29 d0 sub %edx,%eax +c01084e6: 89 45 e8 mov %eax,-0x18(%ebp) +c01084e9: eb 16 jmp c0108501 + putch(padc, putdat); +c01084eb: 0f be 45 db movsbl -0x25(%ebp),%eax +c01084ef: 8b 55 0c mov 0xc(%ebp),%edx +c01084f2: 89 54 24 04 mov %edx,0x4(%esp) +c01084f6: 89 04 24 mov %eax,(%esp) +c01084f9: 8b 45 08 mov 0x8(%ebp),%eax +c01084fc: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { +c01084fe: ff 4d e8 decl -0x18(%ebp) +c0108501: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0108505: 7f e4 jg c01084eb + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c0108507: eb 37 jmp c0108540 + if (altflag && (ch < ' ' || ch > '~')) { +c0108509: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c010850d: 74 1f je c010852e +c010850f: 83 fb 1f cmp $0x1f,%ebx +c0108512: 7e 05 jle c0108519 +c0108514: 83 fb 7e cmp $0x7e,%ebx +c0108517: 7e 15 jle c010852e + putch('?', putdat); +c0108519: 8b 45 0c mov 0xc(%ebp),%eax +c010851c: 89 44 24 04 mov %eax,0x4(%esp) +c0108520: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) +c0108527: 8b 45 08 mov 0x8(%ebp),%eax +c010852a: ff d0 call *%eax +c010852c: eb 0f jmp c010853d + } + else { + putch(ch, putdat); +c010852e: 8b 45 0c mov 0xc(%ebp),%eax +c0108531: 89 44 24 04 mov %eax,0x4(%esp) +c0108535: 89 1c 24 mov %ebx,(%esp) +c0108538: 8b 45 08 mov 0x8(%ebp),%eax +c010853b: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c010853d: ff 4d e8 decl -0x18(%ebp) +c0108540: 89 f0 mov %esi,%eax +c0108542: 8d 70 01 lea 0x1(%eax),%esi +c0108545: 0f b6 00 movzbl (%eax),%eax +c0108548: 0f be d8 movsbl %al,%ebx +c010854b: 85 db test %ebx,%ebx +c010854d: 74 27 je c0108576 +c010854f: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0108553: 78 b4 js c0108509 +c0108555: ff 4d e4 decl -0x1c(%ebp) +c0108558: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010855c: 79 ab jns c0108509 + } + } + for (; width > 0; width --) { +c010855e: eb 16 jmp c0108576 + putch(' ', putdat); +c0108560: 8b 45 0c mov 0xc(%ebp),%eax +c0108563: 89 44 24 04 mov %eax,0x4(%esp) +c0108567: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c010856e: 8b 45 08 mov 0x8(%ebp),%eax +c0108571: ff d0 call *%eax + for (; width > 0; width --) { +c0108573: ff 4d e8 decl -0x18(%ebp) +c0108576: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010857a: 7f e4 jg c0108560 + } + break; +c010857c: e9 6c 01 00 00 jmp c01086ed + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); +c0108581: 8b 45 e0 mov -0x20(%ebp),%eax +c0108584: 89 44 24 04 mov %eax,0x4(%esp) +c0108588: 8d 45 14 lea 0x14(%ebp),%eax +c010858b: 89 04 24 mov %eax,(%esp) +c010858e: e8 16 fd ff ff call c01082a9 +c0108593: 89 45 f0 mov %eax,-0x10(%ebp) +c0108596: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { +c0108599: 8b 45 f0 mov -0x10(%ebp),%eax +c010859c: 8b 55 f4 mov -0xc(%ebp),%edx +c010859f: 85 d2 test %edx,%edx +c01085a1: 79 26 jns c01085c9 + putch('-', putdat); +c01085a3: 8b 45 0c mov 0xc(%ebp),%eax +c01085a6: 89 44 24 04 mov %eax,0x4(%esp) +c01085aa: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) +c01085b1: 8b 45 08 mov 0x8(%ebp),%eax +c01085b4: ff d0 call *%eax + num = -(long long)num; +c01085b6: 8b 45 f0 mov -0x10(%ebp),%eax +c01085b9: 8b 55 f4 mov -0xc(%ebp),%edx +c01085bc: f7 d8 neg %eax +c01085be: 83 d2 00 adc $0x0,%edx +c01085c1: f7 da neg %edx +c01085c3: 89 45 f0 mov %eax,-0x10(%ebp) +c01085c6: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; +c01085c9: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c01085d0: e9 a8 00 00 00 jmp c010867d + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); +c01085d5: 8b 45 e0 mov -0x20(%ebp),%eax +c01085d8: 89 44 24 04 mov %eax,0x4(%esp) +c01085dc: 8d 45 14 lea 0x14(%ebp),%eax +c01085df: 89 04 24 mov %eax,(%esp) +c01085e2: e8 73 fc ff ff call c010825a +c01085e7: 89 45 f0 mov %eax,-0x10(%ebp) +c01085ea: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; +c01085ed: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c01085f4: e9 84 00 00 00 jmp c010867d + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); +c01085f9: 8b 45 e0 mov -0x20(%ebp),%eax +c01085fc: 89 44 24 04 mov %eax,0x4(%esp) +c0108600: 8d 45 14 lea 0x14(%ebp),%eax +c0108603: 89 04 24 mov %eax,(%esp) +c0108606: e8 4f fc ff ff call c010825a +c010860b: 89 45 f0 mov %eax,-0x10(%ebp) +c010860e: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; +c0108611: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; +c0108618: eb 63 jmp c010867d + + // pointer + case 'p': + putch('0', putdat); +c010861a: 8b 45 0c mov 0xc(%ebp),%eax +c010861d: 89 44 24 04 mov %eax,0x4(%esp) +c0108621: c7 04 24 30 00 00 00 movl $0x30,(%esp) +c0108628: 8b 45 08 mov 0x8(%ebp),%eax +c010862b: ff d0 call *%eax + putch('x', putdat); +c010862d: 8b 45 0c mov 0xc(%ebp),%eax +c0108630: 89 44 24 04 mov %eax,0x4(%esp) +c0108634: c7 04 24 78 00 00 00 movl $0x78,(%esp) +c010863b: 8b 45 08 mov 0x8(%ebp),%eax +c010863e: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); +c0108640: 8b 45 14 mov 0x14(%ebp),%eax +c0108643: 8d 50 04 lea 0x4(%eax),%edx +c0108646: 89 55 14 mov %edx,0x14(%ebp) +c0108649: 8b 00 mov (%eax),%eax +c010864b: 89 45 f0 mov %eax,-0x10(%ebp) +c010864e: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; +c0108655: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; +c010865c: eb 1f jmp c010867d + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); +c010865e: 8b 45 e0 mov -0x20(%ebp),%eax +c0108661: 89 44 24 04 mov %eax,0x4(%esp) +c0108665: 8d 45 14 lea 0x14(%ebp),%eax +c0108668: 89 04 24 mov %eax,(%esp) +c010866b: e8 ea fb ff ff call c010825a +c0108670: 89 45 f0 mov %eax,-0x10(%ebp) +c0108673: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; +c0108676: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); +c010867d: 0f be 55 db movsbl -0x25(%ebp),%edx +c0108681: 8b 45 ec mov -0x14(%ebp),%eax +c0108684: 89 54 24 18 mov %edx,0x18(%esp) +c0108688: 8b 55 e8 mov -0x18(%ebp),%edx +c010868b: 89 54 24 14 mov %edx,0x14(%esp) +c010868f: 89 44 24 10 mov %eax,0x10(%esp) +c0108693: 8b 45 f0 mov -0x10(%ebp),%eax +c0108696: 8b 55 f4 mov -0xc(%ebp),%edx +c0108699: 89 44 24 08 mov %eax,0x8(%esp) +c010869d: 89 54 24 0c mov %edx,0xc(%esp) +c01086a1: 8b 45 0c mov 0xc(%ebp),%eax +c01086a4: 89 44 24 04 mov %eax,0x4(%esp) +c01086a8: 8b 45 08 mov 0x8(%ebp),%eax +c01086ab: 89 04 24 mov %eax,(%esp) +c01086ae: e8 a5 fa ff ff call c0108158 + break; +c01086b3: eb 38 jmp c01086ed + + // escaped '%' character + case '%': + putch(ch, putdat); +c01086b5: 8b 45 0c mov 0xc(%ebp),%eax +c01086b8: 89 44 24 04 mov %eax,0x4(%esp) +c01086bc: 89 1c 24 mov %ebx,(%esp) +c01086bf: 8b 45 08 mov 0x8(%ebp),%eax +c01086c2: ff d0 call *%eax + break; +c01086c4: eb 27 jmp c01086ed + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); +c01086c6: 8b 45 0c mov 0xc(%ebp),%eax +c01086c9: 89 44 24 04 mov %eax,0x4(%esp) +c01086cd: c7 04 24 25 00 00 00 movl $0x25,(%esp) +c01086d4: 8b 45 08 mov 0x8(%ebp),%eax +c01086d7: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) +c01086d9: ff 4d 10 decl 0x10(%ebp) +c01086dc: eb 03 jmp c01086e1 +c01086de: ff 4d 10 decl 0x10(%ebp) +c01086e1: 8b 45 10 mov 0x10(%ebp),%eax +c01086e4: 48 dec %eax +c01086e5: 0f b6 00 movzbl (%eax),%eax +c01086e8: 3c 25 cmp $0x25,%al +c01086ea: 75 f2 jne c01086de + /* do nothing */; + break; +c01086ec: 90 nop + while (1) { +c01086ed: e9 37 fc ff ff jmp c0108329 + return; +c01086f2: 90 nop + } + } +} +c01086f3: 83 c4 40 add $0x40,%esp +c01086f6: 5b pop %ebx +c01086f7: 5e pop %esi +c01086f8: 5d pop %ebp +c01086f9: c3 ret + +c01086fa : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { +c01086fa: 55 push %ebp +c01086fb: 89 e5 mov %esp,%ebp + b->cnt ++; +c01086fd: 8b 45 0c mov 0xc(%ebp),%eax +c0108700: 8b 40 08 mov 0x8(%eax),%eax +c0108703: 8d 50 01 lea 0x1(%eax),%edx +c0108706: 8b 45 0c mov 0xc(%ebp),%eax +c0108709: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { +c010870c: 8b 45 0c mov 0xc(%ebp),%eax +c010870f: 8b 10 mov (%eax),%edx +c0108711: 8b 45 0c mov 0xc(%ebp),%eax +c0108714: 8b 40 04 mov 0x4(%eax),%eax +c0108717: 39 c2 cmp %eax,%edx +c0108719: 73 12 jae c010872d + *b->buf ++ = ch; +c010871b: 8b 45 0c mov 0xc(%ebp),%eax +c010871e: 8b 00 mov (%eax),%eax +c0108720: 8d 48 01 lea 0x1(%eax),%ecx +c0108723: 8b 55 0c mov 0xc(%ebp),%edx +c0108726: 89 0a mov %ecx,(%edx) +c0108728: 8b 55 08 mov 0x8(%ebp),%edx +c010872b: 88 10 mov %dl,(%eax) + } +} +c010872d: 90 nop +c010872e: 5d pop %ebp +c010872f: c3 ret + +c0108730 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { +c0108730: 55 push %ebp +c0108731: 89 e5 mov %esp,%ebp +c0108733: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c0108736: 8d 45 14 lea 0x14(%ebp),%eax +c0108739: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); +c010873c: 8b 45 f0 mov -0x10(%ebp),%eax +c010873f: 89 44 24 0c mov %eax,0xc(%esp) +c0108743: 8b 45 10 mov 0x10(%ebp),%eax +c0108746: 89 44 24 08 mov %eax,0x8(%esp) +c010874a: 8b 45 0c mov 0xc(%ebp),%eax +c010874d: 89 44 24 04 mov %eax,0x4(%esp) +c0108751: 8b 45 08 mov 0x8(%ebp),%eax +c0108754: 89 04 24 mov %eax,(%esp) +c0108757: e8 0a 00 00 00 call c0108766 +c010875c: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c010875f: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0108762: 89 ec mov %ebp,%esp +c0108764: 5d pop %ebp +c0108765: c3 ret + +c0108766 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { +c0108766: 55 push %ebp +c0108767: 89 e5 mov %esp,%ebp +c0108769: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; +c010876c: 8b 45 08 mov 0x8(%ebp),%eax +c010876f: 89 45 ec mov %eax,-0x14(%ebp) +c0108772: 8b 45 0c mov 0xc(%ebp),%eax +c0108775: 8d 50 ff lea -0x1(%eax),%edx +c0108778: 8b 45 08 mov 0x8(%ebp),%eax +c010877b: 01 d0 add %edx,%eax +c010877d: 89 45 f0 mov %eax,-0x10(%ebp) +c0108780: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { +c0108787: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c010878b: 74 0a je c0108797 +c010878d: 8b 55 ec mov -0x14(%ebp),%edx +c0108790: 8b 45 f0 mov -0x10(%ebp),%eax +c0108793: 39 c2 cmp %eax,%edx +c0108795: 76 07 jbe c010879e + return -E_INVAL; +c0108797: b8 fd ff ff ff mov $0xfffffffd,%eax +c010879c: eb 2a jmp c01087c8 + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); +c010879e: 8b 45 14 mov 0x14(%ebp),%eax +c01087a1: 89 44 24 0c mov %eax,0xc(%esp) +c01087a5: 8b 45 10 mov 0x10(%ebp),%eax +c01087a8: 89 44 24 08 mov %eax,0x8(%esp) +c01087ac: 8d 45 ec lea -0x14(%ebp),%eax +c01087af: 89 44 24 04 mov %eax,0x4(%esp) +c01087b3: c7 04 24 fa 86 10 c0 movl $0xc01086fa,(%esp) +c01087ba: e8 62 fb ff ff call c0108321 + // null terminate the buffer + *b.buf = '\0'; +c01087bf: 8b 45 ec mov -0x14(%ebp),%eax +c01087c2: c6 00 00 movb $0x0,(%eax) + return b.cnt; +c01087c5: 8b 45 f4 mov -0xc(%ebp),%eax +} +c01087c8: 89 ec mov %ebp,%esp +c01087ca: 5d pop %ebp +c01087cb: c3 ret + +c01087cc : + * rand - returns a pseudo-random integer + * + * The rand() function return a value in the range [0, RAND_MAX]. + * */ +int +rand(void) { +c01087cc: 55 push %ebp +c01087cd: 89 e5 mov %esp,%ebp +c01087cf: 57 push %edi +c01087d0: 56 push %esi +c01087d1: 53 push %ebx +c01087d2: 83 ec 24 sub $0x24,%esp + next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); +c01087d5: a1 60 2a 12 c0 mov 0xc0122a60,%eax +c01087da: 8b 15 64 2a 12 c0 mov 0xc0122a64,%edx +c01087e0: 69 fa 6d e6 ec de imul $0xdeece66d,%edx,%edi +c01087e6: 6b f0 05 imul $0x5,%eax,%esi +c01087e9: 01 fe add %edi,%esi +c01087eb: bf 6d e6 ec de mov $0xdeece66d,%edi +c01087f0: f7 e7 mul %edi +c01087f2: 01 d6 add %edx,%esi +c01087f4: 89 f2 mov %esi,%edx +c01087f6: 83 c0 0b add $0xb,%eax +c01087f9: 83 d2 00 adc $0x0,%edx +c01087fc: 89 c7 mov %eax,%edi +c01087fe: 83 e7 ff and $0xffffffff,%edi +c0108801: 89 f9 mov %edi,%ecx +c0108803: 0f b7 da movzwl %dx,%ebx +c0108806: 89 0d 60 2a 12 c0 mov %ecx,0xc0122a60 +c010880c: 89 1d 64 2a 12 c0 mov %ebx,0xc0122a64 + unsigned long long result = (next >> 12); +c0108812: a1 60 2a 12 c0 mov 0xc0122a60,%eax +c0108817: 8b 15 64 2a 12 c0 mov 0xc0122a64,%edx +c010881d: 0f ac d0 0c shrd $0xc,%edx,%eax +c0108821: c1 ea 0c shr $0xc,%edx +c0108824: 89 45 e0 mov %eax,-0x20(%ebp) +c0108827: 89 55 e4 mov %edx,-0x1c(%ebp) + return (int)do_div(result, RAND_MAX + 1); +c010882a: c7 45 dc 00 00 00 80 movl $0x80000000,-0x24(%ebp) +c0108831: 8b 45 e0 mov -0x20(%ebp),%eax +c0108834: 8b 55 e4 mov -0x1c(%ebp),%edx +c0108837: 89 45 d8 mov %eax,-0x28(%ebp) +c010883a: 89 55 e8 mov %edx,-0x18(%ebp) +c010883d: 8b 45 e8 mov -0x18(%ebp),%eax +c0108840: 89 45 ec mov %eax,-0x14(%ebp) +c0108843: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0108847: 74 1c je c0108865 +c0108849: 8b 45 e8 mov -0x18(%ebp),%eax +c010884c: ba 00 00 00 00 mov $0x0,%edx +c0108851: f7 75 dc divl -0x24(%ebp) +c0108854: 89 55 ec mov %edx,-0x14(%ebp) +c0108857: 8b 45 e8 mov -0x18(%ebp),%eax +c010885a: ba 00 00 00 00 mov $0x0,%edx +c010885f: f7 75 dc divl -0x24(%ebp) +c0108862: 89 45 e8 mov %eax,-0x18(%ebp) +c0108865: 8b 45 d8 mov -0x28(%ebp),%eax +c0108868: 8b 55 ec mov -0x14(%ebp),%edx +c010886b: f7 75 dc divl -0x24(%ebp) +c010886e: 89 45 d8 mov %eax,-0x28(%ebp) +c0108871: 89 55 d4 mov %edx,-0x2c(%ebp) +c0108874: 8b 45 d8 mov -0x28(%ebp),%eax +c0108877: 8b 55 e8 mov -0x18(%ebp),%edx +c010887a: 89 45 e0 mov %eax,-0x20(%ebp) +c010887d: 89 55 e4 mov %edx,-0x1c(%ebp) +c0108880: 8b 45 d4 mov -0x2c(%ebp),%eax +} +c0108883: 83 c4 24 add $0x24,%esp +c0108886: 5b pop %ebx +c0108887: 5e pop %esi +c0108888: 5f pop %edi +c0108889: 5d pop %ebp +c010888a: c3 ret + +c010888b : +/* * + * srand - seed the random number generator with the given number + * @seed: the required seed number + * */ +void +srand(unsigned int seed) { +c010888b: 55 push %ebp +c010888c: 89 e5 mov %esp,%ebp + next = seed; +c010888e: 8b 45 08 mov 0x8(%ebp),%eax +c0108891: ba 00 00 00 00 mov $0x0,%edx +c0108896: a3 60 2a 12 c0 mov %eax,0xc0122a60 +c010889b: 89 15 64 2a 12 c0 mov %edx,0xc0122a64 +} +c01088a1: 90 nop +c01088a2: 5d pop %ebp +c01088a3: c3 ret + +c01088a4 : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { +c01088a4: 55 push %ebp +c01088a5: 89 e5 mov %esp,%ebp +c01088a7: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c01088aa: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { +c01088b1: eb 03 jmp c01088b6 + cnt ++; +c01088b3: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { +c01088b6: 8b 45 08 mov 0x8(%ebp),%eax +c01088b9: 8d 50 01 lea 0x1(%eax),%edx +c01088bc: 89 55 08 mov %edx,0x8(%ebp) +c01088bf: 0f b6 00 movzbl (%eax),%eax +c01088c2: 84 c0 test %al,%al +c01088c4: 75 ed jne c01088b3 + } + return cnt; +c01088c6: 8b 45 fc mov -0x4(%ebp),%eax +} +c01088c9: 89 ec mov %ebp,%esp +c01088cb: 5d pop %ebp +c01088cc: c3 ret + +c01088cd : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { +c01088cd: 55 push %ebp +c01088ce: 89 e5 mov %esp,%ebp +c01088d0: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c01088d3: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c01088da: eb 03 jmp c01088df + cnt ++; +c01088dc: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c01088df: 8b 45 fc mov -0x4(%ebp),%eax +c01088e2: 3b 45 0c cmp 0xc(%ebp),%eax +c01088e5: 73 10 jae c01088f7 +c01088e7: 8b 45 08 mov 0x8(%ebp),%eax +c01088ea: 8d 50 01 lea 0x1(%eax),%edx +c01088ed: 89 55 08 mov %edx,0x8(%ebp) +c01088f0: 0f b6 00 movzbl (%eax),%eax +c01088f3: 84 c0 test %al,%al +c01088f5: 75 e5 jne c01088dc + } + return cnt; +c01088f7: 8b 45 fc mov -0x4(%ebp),%eax +} +c01088fa: 89 ec mov %ebp,%esp +c01088fc: 5d pop %ebp +c01088fd: c3 ret + +c01088fe : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { +c01088fe: 55 push %ebp +c01088ff: 89 e5 mov %esp,%ebp +c0108901: 57 push %edi +c0108902: 56 push %esi +c0108903: 83 ec 20 sub $0x20,%esp +c0108906: 8b 45 08 mov 0x8(%ebp),%eax +c0108909: 89 45 f4 mov %eax,-0xc(%ebp) +c010890c: 8b 45 0c mov 0xc(%ebp),%eax +c010890f: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( +c0108912: 8b 55 f0 mov -0x10(%ebp),%edx +c0108915: 8b 45 f4 mov -0xc(%ebp),%eax +c0108918: 89 d1 mov %edx,%ecx +c010891a: 89 c2 mov %eax,%edx +c010891c: 89 ce mov %ecx,%esi +c010891e: 89 d7 mov %edx,%edi +c0108920: ac lods %ds:(%esi),%al +c0108921: aa stos %al,%es:(%edi) +c0108922: 84 c0 test %al,%al +c0108924: 75 fa jne c0108920 +c0108926: 89 fa mov %edi,%edx +c0108928: 89 f1 mov %esi,%ecx +c010892a: 89 4d ec mov %ecx,-0x14(%ebp) +c010892d: 89 55 e8 mov %edx,-0x18(%ebp) +c0108930: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; +c0108933: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} +c0108936: 83 c4 20 add $0x20,%esp +c0108939: 5e pop %esi +c010893a: 5f pop %edi +c010893b: 5d pop %ebp +c010893c: c3 ret + +c010893d : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { +c010893d: 55 push %ebp +c010893e: 89 e5 mov %esp,%ebp +c0108940: 83 ec 10 sub $0x10,%esp + char *p = dst; +c0108943: 8b 45 08 mov 0x8(%ebp),%eax +c0108946: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { +c0108949: eb 1e jmp c0108969 + if ((*p = *src) != '\0') { +c010894b: 8b 45 0c mov 0xc(%ebp),%eax +c010894e: 0f b6 10 movzbl (%eax),%edx +c0108951: 8b 45 fc mov -0x4(%ebp),%eax +c0108954: 88 10 mov %dl,(%eax) +c0108956: 8b 45 fc mov -0x4(%ebp),%eax +c0108959: 0f b6 00 movzbl (%eax),%eax +c010895c: 84 c0 test %al,%al +c010895e: 74 03 je c0108963 + src ++; +c0108960: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; +c0108963: ff 45 fc incl -0x4(%ebp) +c0108966: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { +c0108969: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c010896d: 75 dc jne c010894b + } + return dst; +c010896f: 8b 45 08 mov 0x8(%ebp),%eax +} +c0108972: 89 ec mov %ebp,%esp +c0108974: 5d pop %ebp +c0108975: c3 ret + +c0108976 : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { +c0108976: 55 push %ebp +c0108977: 89 e5 mov %esp,%ebp +c0108979: 57 push %edi +c010897a: 56 push %esi +c010897b: 83 ec 20 sub $0x20,%esp +c010897e: 8b 45 08 mov 0x8(%ebp),%eax +c0108981: 89 45 f4 mov %eax,-0xc(%ebp) +c0108984: 8b 45 0c mov 0xc(%ebp),%eax +c0108987: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( +c010898a: 8b 55 f4 mov -0xc(%ebp),%edx +c010898d: 8b 45 f0 mov -0x10(%ebp),%eax +c0108990: 89 d1 mov %edx,%ecx +c0108992: 89 c2 mov %eax,%edx +c0108994: 89 ce mov %ecx,%esi +c0108996: 89 d7 mov %edx,%edi +c0108998: ac lods %ds:(%esi),%al +c0108999: ae scas %es:(%edi),%al +c010899a: 75 08 jne c01089a4 +c010899c: 84 c0 test %al,%al +c010899e: 75 f8 jne c0108998 +c01089a0: 31 c0 xor %eax,%eax +c01089a2: eb 04 jmp c01089a8 +c01089a4: 19 c0 sbb %eax,%eax +c01089a6: 0c 01 or $0x1,%al +c01089a8: 89 fa mov %edi,%edx +c01089aa: 89 f1 mov %esi,%ecx +c01089ac: 89 45 ec mov %eax,-0x14(%ebp) +c01089af: 89 4d e8 mov %ecx,-0x18(%ebp) +c01089b2: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; +c01089b5: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} +c01089b8: 83 c4 20 add $0x20,%esp +c01089bb: 5e pop %esi +c01089bc: 5f pop %edi +c01089bd: 5d pop %ebp +c01089be: c3 ret + +c01089bf : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { +c01089bf: 55 push %ebp +c01089c0: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c01089c2: eb 09 jmp c01089cd + n --, s1 ++, s2 ++; +c01089c4: ff 4d 10 decl 0x10(%ebp) +c01089c7: ff 45 08 incl 0x8(%ebp) +c01089ca: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c01089cd: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c01089d1: 74 1a je c01089ed +c01089d3: 8b 45 08 mov 0x8(%ebp),%eax +c01089d6: 0f b6 00 movzbl (%eax),%eax +c01089d9: 84 c0 test %al,%al +c01089db: 74 10 je c01089ed +c01089dd: 8b 45 08 mov 0x8(%ebp),%eax +c01089e0: 0f b6 10 movzbl (%eax),%edx +c01089e3: 8b 45 0c mov 0xc(%ebp),%eax +c01089e6: 0f b6 00 movzbl (%eax),%eax +c01089e9: 38 c2 cmp %al,%dl +c01089eb: 74 d7 je c01089c4 + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); +c01089ed: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c01089f1: 74 18 je c0108a0b +c01089f3: 8b 45 08 mov 0x8(%ebp),%eax +c01089f6: 0f b6 00 movzbl (%eax),%eax +c01089f9: 0f b6 d0 movzbl %al,%edx +c01089fc: 8b 45 0c mov 0xc(%ebp),%eax +c01089ff: 0f b6 00 movzbl (%eax),%eax +c0108a02: 0f b6 c8 movzbl %al,%ecx +c0108a05: 89 d0 mov %edx,%eax +c0108a07: 29 c8 sub %ecx,%eax +c0108a09: eb 05 jmp c0108a10 +c0108a0b: b8 00 00 00 00 mov $0x0,%eax +} +c0108a10: 5d pop %ebp +c0108a11: c3 ret + +c0108a12 : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { +c0108a12: 55 push %ebp +c0108a13: 89 e5 mov %esp,%ebp +c0108a15: 83 ec 04 sub $0x4,%esp +c0108a18: 8b 45 0c mov 0xc(%ebp),%eax +c0108a1b: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c0108a1e: eb 13 jmp c0108a33 + if (*s == c) { +c0108a20: 8b 45 08 mov 0x8(%ebp),%eax +c0108a23: 0f b6 00 movzbl (%eax),%eax +c0108a26: 38 45 fc cmp %al,-0x4(%ebp) +c0108a29: 75 05 jne c0108a30 + return (char *)s; +c0108a2b: 8b 45 08 mov 0x8(%ebp),%eax +c0108a2e: eb 12 jmp c0108a42 + } + s ++; +c0108a30: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c0108a33: 8b 45 08 mov 0x8(%ebp),%eax +c0108a36: 0f b6 00 movzbl (%eax),%eax +c0108a39: 84 c0 test %al,%al +c0108a3b: 75 e3 jne c0108a20 + } + return NULL; +c0108a3d: b8 00 00 00 00 mov $0x0,%eax +} +c0108a42: 89 ec mov %ebp,%esp +c0108a44: 5d pop %ebp +c0108a45: c3 ret + +c0108a46 : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { +c0108a46: 55 push %ebp +c0108a47: 89 e5 mov %esp,%ebp +c0108a49: 83 ec 04 sub $0x4,%esp +c0108a4c: 8b 45 0c mov 0xc(%ebp),%eax +c0108a4f: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c0108a52: eb 0e jmp c0108a62 + if (*s == c) { +c0108a54: 8b 45 08 mov 0x8(%ebp),%eax +c0108a57: 0f b6 00 movzbl (%eax),%eax +c0108a5a: 38 45 fc cmp %al,-0x4(%ebp) +c0108a5d: 74 0f je c0108a6e + break; + } + s ++; +c0108a5f: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c0108a62: 8b 45 08 mov 0x8(%ebp),%eax +c0108a65: 0f b6 00 movzbl (%eax),%eax +c0108a68: 84 c0 test %al,%al +c0108a6a: 75 e8 jne c0108a54 +c0108a6c: eb 01 jmp c0108a6f + break; +c0108a6e: 90 nop + } + return (char *)s; +c0108a6f: 8b 45 08 mov 0x8(%ebp),%eax +} +c0108a72: 89 ec mov %ebp,%esp +c0108a74: 5d pop %ebp +c0108a75: c3 ret + +c0108a76 : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { +c0108a76: 55 push %ebp +c0108a77: 89 e5 mov %esp,%ebp +c0108a79: 83 ec 10 sub $0x10,%esp + int neg = 0; +c0108a7c: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; +c0108a83: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { +c0108a8a: eb 03 jmp c0108a8f + s ++; +c0108a8c: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { +c0108a8f: 8b 45 08 mov 0x8(%ebp),%eax +c0108a92: 0f b6 00 movzbl (%eax),%eax +c0108a95: 3c 20 cmp $0x20,%al +c0108a97: 74 f3 je c0108a8c +c0108a99: 8b 45 08 mov 0x8(%ebp),%eax +c0108a9c: 0f b6 00 movzbl (%eax),%eax +c0108a9f: 3c 09 cmp $0x9,%al +c0108aa1: 74 e9 je c0108a8c + } + + // plus/minus sign + if (*s == '+') { +c0108aa3: 8b 45 08 mov 0x8(%ebp),%eax +c0108aa6: 0f b6 00 movzbl (%eax),%eax +c0108aa9: 3c 2b cmp $0x2b,%al +c0108aab: 75 05 jne c0108ab2 + s ++; +c0108aad: ff 45 08 incl 0x8(%ebp) +c0108ab0: eb 14 jmp c0108ac6 + } + else if (*s == '-') { +c0108ab2: 8b 45 08 mov 0x8(%ebp),%eax +c0108ab5: 0f b6 00 movzbl (%eax),%eax +c0108ab8: 3c 2d cmp $0x2d,%al +c0108aba: 75 0a jne c0108ac6 + s ++, neg = 1; +c0108abc: ff 45 08 incl 0x8(%ebp) +c0108abf: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { +c0108ac6: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0108aca: 74 06 je c0108ad2 +c0108acc: 83 7d 10 10 cmpl $0x10,0x10(%ebp) +c0108ad0: 75 22 jne c0108af4 +c0108ad2: 8b 45 08 mov 0x8(%ebp),%eax +c0108ad5: 0f b6 00 movzbl (%eax),%eax +c0108ad8: 3c 30 cmp $0x30,%al +c0108ada: 75 18 jne c0108af4 +c0108adc: 8b 45 08 mov 0x8(%ebp),%eax +c0108adf: 40 inc %eax +c0108ae0: 0f b6 00 movzbl (%eax),%eax +c0108ae3: 3c 78 cmp $0x78,%al +c0108ae5: 75 0d jne c0108af4 + s += 2, base = 16; +c0108ae7: 83 45 08 02 addl $0x2,0x8(%ebp) +c0108aeb: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) +c0108af2: eb 29 jmp c0108b1d + } + else if (base == 0 && s[0] == '0') { +c0108af4: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0108af8: 75 16 jne c0108b10 +c0108afa: 8b 45 08 mov 0x8(%ebp),%eax +c0108afd: 0f b6 00 movzbl (%eax),%eax +c0108b00: 3c 30 cmp $0x30,%al +c0108b02: 75 0c jne c0108b10 + s ++, base = 8; +c0108b04: ff 45 08 incl 0x8(%ebp) +c0108b07: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) +c0108b0e: eb 0d jmp c0108b1d + } + else if (base == 0) { +c0108b10: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0108b14: 75 07 jne c0108b1d + base = 10; +c0108b16: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { +c0108b1d: 8b 45 08 mov 0x8(%ebp),%eax +c0108b20: 0f b6 00 movzbl (%eax),%eax +c0108b23: 3c 2f cmp $0x2f,%al +c0108b25: 7e 1b jle c0108b42 +c0108b27: 8b 45 08 mov 0x8(%ebp),%eax +c0108b2a: 0f b6 00 movzbl (%eax),%eax +c0108b2d: 3c 39 cmp $0x39,%al +c0108b2f: 7f 11 jg c0108b42 + dig = *s - '0'; +c0108b31: 8b 45 08 mov 0x8(%ebp),%eax +c0108b34: 0f b6 00 movzbl (%eax),%eax +c0108b37: 0f be c0 movsbl %al,%eax +c0108b3a: 83 e8 30 sub $0x30,%eax +c0108b3d: 89 45 f4 mov %eax,-0xc(%ebp) +c0108b40: eb 48 jmp c0108b8a + } + else if (*s >= 'a' && *s <= 'z') { +c0108b42: 8b 45 08 mov 0x8(%ebp),%eax +c0108b45: 0f b6 00 movzbl (%eax),%eax +c0108b48: 3c 60 cmp $0x60,%al +c0108b4a: 7e 1b jle c0108b67 +c0108b4c: 8b 45 08 mov 0x8(%ebp),%eax +c0108b4f: 0f b6 00 movzbl (%eax),%eax +c0108b52: 3c 7a cmp $0x7a,%al +c0108b54: 7f 11 jg c0108b67 + dig = *s - 'a' + 10; +c0108b56: 8b 45 08 mov 0x8(%ebp),%eax +c0108b59: 0f b6 00 movzbl (%eax),%eax +c0108b5c: 0f be c0 movsbl %al,%eax +c0108b5f: 83 e8 57 sub $0x57,%eax +c0108b62: 89 45 f4 mov %eax,-0xc(%ebp) +c0108b65: eb 23 jmp c0108b8a + } + else if (*s >= 'A' && *s <= 'Z') { +c0108b67: 8b 45 08 mov 0x8(%ebp),%eax +c0108b6a: 0f b6 00 movzbl (%eax),%eax +c0108b6d: 3c 40 cmp $0x40,%al +c0108b6f: 7e 3b jle c0108bac +c0108b71: 8b 45 08 mov 0x8(%ebp),%eax +c0108b74: 0f b6 00 movzbl (%eax),%eax +c0108b77: 3c 5a cmp $0x5a,%al +c0108b79: 7f 31 jg c0108bac + dig = *s - 'A' + 10; +c0108b7b: 8b 45 08 mov 0x8(%ebp),%eax +c0108b7e: 0f b6 00 movzbl (%eax),%eax +c0108b81: 0f be c0 movsbl %al,%eax +c0108b84: 83 e8 37 sub $0x37,%eax +c0108b87: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { +c0108b8a: 8b 45 f4 mov -0xc(%ebp),%eax +c0108b8d: 3b 45 10 cmp 0x10(%ebp),%eax +c0108b90: 7d 19 jge c0108bab + break; + } + s ++, val = (val * base) + dig; +c0108b92: ff 45 08 incl 0x8(%ebp) +c0108b95: 8b 45 f8 mov -0x8(%ebp),%eax +c0108b98: 0f af 45 10 imul 0x10(%ebp),%eax +c0108b9c: 89 c2 mov %eax,%edx +c0108b9e: 8b 45 f4 mov -0xc(%ebp),%eax +c0108ba1: 01 d0 add %edx,%eax +c0108ba3: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { +c0108ba6: e9 72 ff ff ff jmp c0108b1d + break; +c0108bab: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { +c0108bac: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0108bb0: 74 08 je c0108bba + *endptr = (char *) s; +c0108bb2: 8b 45 0c mov 0xc(%ebp),%eax +c0108bb5: 8b 55 08 mov 0x8(%ebp),%edx +c0108bb8: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); +c0108bba: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c0108bbe: 74 07 je c0108bc7 +c0108bc0: 8b 45 f8 mov -0x8(%ebp),%eax +c0108bc3: f7 d8 neg %eax +c0108bc5: eb 03 jmp c0108bca +c0108bc7: 8b 45 f8 mov -0x8(%ebp),%eax +} +c0108bca: 89 ec mov %ebp,%esp +c0108bcc: 5d pop %ebp +c0108bcd: c3 ret + +c0108bce : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { +c0108bce: 55 push %ebp +c0108bcf: 89 e5 mov %esp,%ebp +c0108bd1: 83 ec 28 sub $0x28,%esp +c0108bd4: 89 7d fc mov %edi,-0x4(%ebp) +c0108bd7: 8b 45 0c mov 0xc(%ebp),%eax +c0108bda: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); +c0108bdd: 0f be 55 d8 movsbl -0x28(%ebp),%edx +c0108be1: 8b 45 08 mov 0x8(%ebp),%eax +c0108be4: 89 45 f8 mov %eax,-0x8(%ebp) +c0108be7: 88 55 f7 mov %dl,-0x9(%ebp) +c0108bea: 8b 45 10 mov 0x10(%ebp),%eax +c0108bed: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( +c0108bf0: 8b 4d f0 mov -0x10(%ebp),%ecx +c0108bf3: 0f b6 45 f7 movzbl -0x9(%ebp),%eax +c0108bf7: 8b 55 f8 mov -0x8(%ebp),%edx +c0108bfa: 89 d7 mov %edx,%edi +c0108bfc: f3 aa rep stos %al,%es:(%edi) +c0108bfe: 89 fa mov %edi,%edx +c0108c00: 89 4d ec mov %ecx,-0x14(%ebp) +c0108c03: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; +c0108c06: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} +c0108c09: 8b 7d fc mov -0x4(%ebp),%edi +c0108c0c: 89 ec mov %ebp,%esp +c0108c0e: 5d pop %ebp +c0108c0f: c3 ret + +c0108c10 : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { +c0108c10: 55 push %ebp +c0108c11: 89 e5 mov %esp,%ebp +c0108c13: 57 push %edi +c0108c14: 56 push %esi +c0108c15: 53 push %ebx +c0108c16: 83 ec 30 sub $0x30,%esp +c0108c19: 8b 45 08 mov 0x8(%ebp),%eax +c0108c1c: 89 45 f0 mov %eax,-0x10(%ebp) +c0108c1f: 8b 45 0c mov 0xc(%ebp),%eax +c0108c22: 89 45 ec mov %eax,-0x14(%ebp) +c0108c25: 8b 45 10 mov 0x10(%ebp),%eax +c0108c28: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { +c0108c2b: 8b 45 f0 mov -0x10(%ebp),%eax +c0108c2e: 3b 45 ec cmp -0x14(%ebp),%eax +c0108c31: 73 42 jae c0108c75 +c0108c33: 8b 45 f0 mov -0x10(%ebp),%eax +c0108c36: 89 45 e4 mov %eax,-0x1c(%ebp) +c0108c39: 8b 45 ec mov -0x14(%ebp),%eax +c0108c3c: 89 45 e0 mov %eax,-0x20(%ebp) +c0108c3f: 8b 45 e8 mov -0x18(%ebp),%eax +c0108c42: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) +c0108c45: 8b 45 dc mov -0x24(%ebp),%eax +c0108c48: c1 e8 02 shr $0x2,%eax +c0108c4b: 89 c1 mov %eax,%ecx + asm volatile ( +c0108c4d: 8b 55 e4 mov -0x1c(%ebp),%edx +c0108c50: 8b 45 e0 mov -0x20(%ebp),%eax +c0108c53: 89 d7 mov %edx,%edi +c0108c55: 89 c6 mov %eax,%esi +c0108c57: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c0108c59: 8b 4d dc mov -0x24(%ebp),%ecx +c0108c5c: 83 e1 03 and $0x3,%ecx +c0108c5f: 74 02 je c0108c63 +c0108c61: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0108c63: 89 f0 mov %esi,%eax +c0108c65: 89 fa mov %edi,%edx +c0108c67: 89 4d d8 mov %ecx,-0x28(%ebp) +c0108c6a: 89 55 d4 mov %edx,-0x2c(%ebp) +c0108c6d: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; +c0108c70: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); +c0108c73: eb 36 jmp c0108cab + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) +c0108c75: 8b 45 e8 mov -0x18(%ebp),%eax +c0108c78: 8d 50 ff lea -0x1(%eax),%edx +c0108c7b: 8b 45 ec mov -0x14(%ebp),%eax +c0108c7e: 01 c2 add %eax,%edx +c0108c80: 8b 45 e8 mov -0x18(%ebp),%eax +c0108c83: 8d 48 ff lea -0x1(%eax),%ecx +c0108c86: 8b 45 f0 mov -0x10(%ebp),%eax +c0108c89: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( +c0108c8c: 8b 45 e8 mov -0x18(%ebp),%eax +c0108c8f: 89 c1 mov %eax,%ecx +c0108c91: 89 d8 mov %ebx,%eax +c0108c93: 89 d6 mov %edx,%esi +c0108c95: 89 c7 mov %eax,%edi +c0108c97: fd std +c0108c98: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0108c9a: fc cld +c0108c9b: 89 f8 mov %edi,%eax +c0108c9d: 89 f2 mov %esi,%edx +c0108c9f: 89 4d cc mov %ecx,-0x34(%ebp) +c0108ca2: 89 55 c8 mov %edx,-0x38(%ebp) +c0108ca5: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; +c0108ca8: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} +c0108cab: 83 c4 30 add $0x30,%esp +c0108cae: 5b pop %ebx +c0108caf: 5e pop %esi +c0108cb0: 5f pop %edi +c0108cb1: 5d pop %ebp +c0108cb2: c3 ret + +c0108cb3 : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { +c0108cb3: 55 push %ebp +c0108cb4: 89 e5 mov %esp,%ebp +c0108cb6: 57 push %edi +c0108cb7: 56 push %esi +c0108cb8: 83 ec 20 sub $0x20,%esp +c0108cbb: 8b 45 08 mov 0x8(%ebp),%eax +c0108cbe: 89 45 f4 mov %eax,-0xc(%ebp) +c0108cc1: 8b 45 0c mov 0xc(%ebp),%eax +c0108cc4: 89 45 f0 mov %eax,-0x10(%ebp) +c0108cc7: 8b 45 10 mov 0x10(%ebp),%eax +c0108cca: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) +c0108ccd: 8b 45 ec mov -0x14(%ebp),%eax +c0108cd0: c1 e8 02 shr $0x2,%eax +c0108cd3: 89 c1 mov %eax,%ecx + asm volatile ( +c0108cd5: 8b 55 f4 mov -0xc(%ebp),%edx +c0108cd8: 8b 45 f0 mov -0x10(%ebp),%eax +c0108cdb: 89 d7 mov %edx,%edi +c0108cdd: 89 c6 mov %eax,%esi +c0108cdf: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c0108ce1: 8b 4d ec mov -0x14(%ebp),%ecx +c0108ce4: 83 e1 03 and $0x3,%ecx +c0108ce7: 74 02 je c0108ceb +c0108ce9: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0108ceb: 89 f0 mov %esi,%eax +c0108ced: 89 fa mov %edi,%edx +c0108cef: 89 4d e8 mov %ecx,-0x18(%ebp) +c0108cf2: 89 55 e4 mov %edx,-0x1c(%ebp) +c0108cf5: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; +c0108cf8: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} +c0108cfb: 83 c4 20 add $0x20,%esp +c0108cfe: 5e pop %esi +c0108cff: 5f pop %edi +c0108d00: 5d pop %ebp +c0108d01: c3 ret + +c0108d02 : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { +c0108d02: 55 push %ebp +c0108d03: 89 e5 mov %esp,%ebp +c0108d05: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; +c0108d08: 8b 45 08 mov 0x8(%ebp),%eax +c0108d0b: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; +c0108d0e: 8b 45 0c mov 0xc(%ebp),%eax +c0108d11: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { +c0108d14: eb 2e jmp c0108d44 + if (*s1 != *s2) { +c0108d16: 8b 45 fc mov -0x4(%ebp),%eax +c0108d19: 0f b6 10 movzbl (%eax),%edx +c0108d1c: 8b 45 f8 mov -0x8(%ebp),%eax +c0108d1f: 0f b6 00 movzbl (%eax),%eax +c0108d22: 38 c2 cmp %al,%dl +c0108d24: 74 18 je c0108d3e + return (int)((unsigned char)*s1 - (unsigned char)*s2); +c0108d26: 8b 45 fc mov -0x4(%ebp),%eax +c0108d29: 0f b6 00 movzbl (%eax),%eax +c0108d2c: 0f b6 d0 movzbl %al,%edx +c0108d2f: 8b 45 f8 mov -0x8(%ebp),%eax +c0108d32: 0f b6 00 movzbl (%eax),%eax +c0108d35: 0f b6 c8 movzbl %al,%ecx +c0108d38: 89 d0 mov %edx,%eax +c0108d3a: 29 c8 sub %ecx,%eax +c0108d3c: eb 18 jmp c0108d56 + } + s1 ++, s2 ++; +c0108d3e: ff 45 fc incl -0x4(%ebp) +c0108d41: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { +c0108d44: 8b 45 10 mov 0x10(%ebp),%eax +c0108d47: 8d 50 ff lea -0x1(%eax),%edx +c0108d4a: 89 55 10 mov %edx,0x10(%ebp) +c0108d4d: 85 c0 test %eax,%eax +c0108d4f: 75 c5 jne c0108d16 + } + return 0; +c0108d51: b8 00 00 00 00 mov $0x0,%eax +} +c0108d56: 89 ec mov %ebp,%esp +c0108d58: 5d pop %ebp +c0108d59: c3 ret diff --git a/labcodes/lab3/obj/kernel.sym b/labcodes/lab3/obj/kernel.sym new file mode 100644 index 0000000000000000000000000000000000000000..950139520bdcabbb2fa3e1651e99730fc149bada --- /dev/null +++ b/labcodes/lab3/obj/kernel.sym @@ -0,0 +1,537 @@ +00000000 entry.o +c010001e next +c0100034 spin +c0124000 __boot_pt1 +00000400 i +00000000 init.c +c010022a lab1_switch_test +c0100153 lab1_print_cur_status +c0125000 round.0 +c0100213 lab1_switch_to_user +c0100220 lab1_switch_to_kernel +00000000 readline.c +c0125020 buf +00000000 stdio.c +c010031d cputch +00000000 kdebug.c +c0100420 stab_binsearch +c01009d1 read_eip +00000000 kmonitor.c +c0122000 commands +c01009ea parse +c0100aa3 runcmd +00000000 panic.c +c0125420 is_panic +00000000 clock.c +00000000 console.c +c0100d7c __intr_save +c0100da8 __intr_restore +c0100dbe delay +c0125440 crt_buf +c0125444 crt_pos +c0125446 addr_6845 +c0100e09 cga_init +c0125448 serial_exists +c0100ef1 serial_init +c0100fde lpt_putc_sub +c010105c lpt_putc +c010109e cga_putc +c0101294 serial_putc_sub +c01012f0 serial_putc +c0125460 cons +c0101332 cons_intr +c0101381 serial_proc_data +c0122040 shiftcode +c0122140 togglecode +c0122240 normalmap +c0122340 shiftmap +c0122440 ctlmap +c0122540 charcode +c01013fa kbd_proc_data +c0125668 shift.0 +c0101581 kbd_intr +c0101598 kbd_init +00000000 ide.c +c0109094 channels +c0125680 ide_devices +c0101693 ide_wait_ready +00000000 intr.c +00000000 picirq.c +c0122550 irq_mask +c0125760 did_init +c0101f00 pic_setmask +00000000 trap.c +c01020dc print_ticks +c01257e0 idt +c0122560 idt_pd +c0102270 trapname +c0109600 excnames.0 +c0122580 IA32flags +c0102523 print_pgfault +c01025a4 pgfault_handler +c0125fe0 in_swap_tick_event +c0102604 trap_dispatch +00000000 default_pmm.c +c010332f page2ppn +c0103342 page2pa +c010335a page_ref +c0103364 set_page_ref +c0103372 default_init +c01033a3 default_init_memmap +c01034f0 default_alloc_pages +c0103674 default_free_pages +c010398c default_nr_free_pages +c0103996 basic_check +c0103ed6 default_check +00000000 pmm.c +c0104528 page2ppn +c010453b page2pa +c0104553 pa2page +c010459b page2kva +c01045f1 kva2page +c010463d pte2page +c010467d pde2page +c0104697 page_ref +c01046a1 set_page_ref +c01046af page_ref_inc +c01046c6 page_ref_dec +c01046dd __intr_save +c0104709 __intr_restore +c0126020 ts +c0122a00 gdt +c0122a30 gdt_pd +c010471f lgdt +c0104763 gdt_init +c010484f init_pmm_manager +c0104885 init_memmap +c0104976 page_init +c0104d29 boot_map_segment +c0104e2f boot_alloc_page +c0105385 check_alloc_page +c01053a6 check_pgdir +c0105a44 check_boot_pgdir +c01050f3 page_remove_pte +c0105dd0 perm2str +c0126088 str.0 +c0105e12 get_pgtable_items +00000000 swap.c +c010616c pa2page +c01061b4 pte2page +c0126160 sm +c010672f check_swap +c010655a check_content_set +c0106715 check_content_access +00000000 swap_fifo.c +c0106d89 _fifo_init_mm +c0106dbe _fifo_map_swappable +c0106e0f _fifo_swap_out_victim +c0106e7b _fifo_check_swap +c01071d2 _fifo_init +c01071dc _fifo_set_unswappable +c01071e6 _fifo_tick_event +00000000 vmm.c +c01071f0 pa2page +c0107238 pde2page +c01073bd check_vma_overlap +c010762e check_vmm +c0107685 check_vma_struct +c0107b47 check_pgfault +00000000 swapfs.c +c0107fa4 page2ppn +c0107fb7 page2pa +c0107fcf page2kva +00000000 printfmt.c +c010ac14 error_string +c0108158 printnum +c010825a getuint +c01082a9 getint +c01086fa sprintputch +00000000 rand.c +c0122a60 next +00000000 string.c +c0103287 vector242 +c0102cde vector119 +c0100898 print_kerninfo +c0102bbe vector87 +c0102bb5 vector86 +c01032f3 vector251 +c01088fe strcpy +c01019f1 ide_device_valid +c0102be2 vector91 +c01029d8 vector33 +c0102ec7 vector162 +c010312b vector213 +c0102c7b vector108 +c0102a32 vector43 +c0100000 kern_entry +c0100c2e mon_backtrace +c0102eeb vector165 +c0102fdb vector185 +c0102cba vector115 +c0102cf9 vector122 +c010519e page_insert +c0102e7f vector156 +c01032ab vector245 +c010300b vector189 +c01028fc vector7 +c0102ad4 vector61 +c0102987 vector24 +c0102c96 vector111 +c010308f vector200 +c0102b0a vector67 +c01052b8 pgdir_alloc_page +c0102da7 vector138 +c0102b49 vector74 +c0108c10 memmove +c0102ab0 vector57 +c0107252 mm_create +c0108730 snprintf +c01022b6 print_trapframe +c0103137 vector214 +c0108321 vprintfmt +c0102c2a vector99 +c0105098 get_page +c010289b __alltraps +c0101622 cons_getc +c0102dcb vector141 +c0100d09 is_kernel_panic +c0102f3f vector172 +c01009e4 print_stackframe +c010327b vector241 +c0126164 pra_list_head +c010330b vector253 +c01028d8 vector3 +c01028cf vector2 +c01031d3 vector227 +c0103107 vector210 +c01031af vector224 +c0102a20 vector41 +c0122a40 swap_manager_fifo +c0100375 cprintf +c010296c vector21 +c0102f7b vector177 +c0102cd5 vector118 +c0102b25 vector70 +c0102b1c vector69 +c010324b vector237 +c0102aef vector64 +c01029a2 vector27 +c010761e vmm_init +c0102d5f vector132 +c0102fe7 vector186 +c010315b vector217 +c010759a mm_destroy +c0108cb3 memcpy +c01028c6 vector1 +c0102f87 vector178 +c0102a05 vector38 +c01060cf kfree +c0103257 vector238 +c0100266 readline +c0102d6b vector133 +c0102b40 vector73 +c0102def vector144 +c0109a9c vpd +c0100036 kern_init +c0103317 vector254 +c0102c3c vector101 +c0103113 vector211 +c0102f57 vector174 +c0103293 vector243 +c0102d2f vector128 +c0102b88 vector81 +c0104914 free_pages +c010292a vector13 +c0108766 vsnprintf +c0102a7a vector51 +c0102941 vector16 +c0125000 edata +c01015b4 cons_init +c0106482 swap_in +c0101caf ide_write_secs +c012600c pmm_manager +c010326f vector240 +c0102a95 vector54 +c010295a vector19 +c011ae74 __STAB_END__ +c0102beb vector92 +c010329f vector244 +c01260a4 swap_init_ok +c0104755 load_esp0 +c0102dbf vector140 +c0102a44 vector45 +c0102b76 vector79 +c01031eb vector229 +c01061f4 swap_init +c0102e97 vector158 +c0101f5d pic_enable +c0108025 swapfs_init +c012612c check_rp +c0102a0e vector39 +c0102f0f vector168 +c01029ea vector35 +c0102ca8 vector113 +c011ae75 __STABSTR_BEGIN__ +c0102d14 vector125 +c0100c42 __panic +c010314f vector216 +c0102ae6 vector63 +c0102999 vector26 +c01013da serial_intr +c010303b vector193 +c010305f vector196 +c010010e grade_backtrace0 +c01030fb vector209 +c01028e1 vector4 +c0102f27 vector170 +c0102d8f vector136 +c0102915 vector10 +c01030d7 vector206 +c0103323 vector255 +c0102fab vector181 +c0102ac2 vector59 +c010012b grade_backtrace +c0102bac vector85 +c0102ba3 vector84 +c0102fc3 vector183 +c0102ea3 vector159 +c010311f vector212 +c0102a56 vector47 +c0108a76 strtol +c01031df vector228 +c0102a29 vector42 +c0102cb1 vector114 +c01088cd strnlen +c0102f63 vector175 +c0102de3 vector143 +c0102d47 vector130 +c01099e0 default_pmm_manager +c01032b7 vector246 +c010290c vector9 +c0102dd7 vector142 +c0102c33 vector100 +c010309b vector201 +c01020fb idt_init +c010092c print_debuginfo +c010730a find_vma +c01260c0 swap_in_seq_no +c0102acb vector60 +c010297e vector23 +c010323f vector236 +c0126004 npage +c0107d8d do_pgfault +c0103203 vector231 +c0102b01 vector66 +c01029b4 vector29 +c0105ec6 print_pgdir +c0102d83 vector135 +c0100b5b kmonitor +c0102b64 vector77 +c0102f9f vector180 +c0100d13 clock_init +c01030ef vector208 +c0102c21 vector98 +c0102c18 vector97 +c0104949 nr_free_pages +c0102f6f vector176 +c0103047 vector194 +c01029cf vector32 +c0126008 boot_cr3 +c0126174 end +c0103083 vector199 +c0102d53 vector131 +c01032ff vector252 +c01028bd vector0 +c0108a46 strfind +c01015e3 cons_putc +c0126100 swap_out_seq_no +c0108d5a etext +c0102dfb vector145 +c0102c72 vector107 +c01229e0 boot_pgdir +c0102a17 vector40 +c0101ef0 intr_enable +c0102c45 vector102 +c0102aa7 vector56 +c0102b13 vector68 +c01028f3 vector6 +c01087cc rand +c0102d3b vector129 +c010306b vector197 +c0102e4f vector152 +c01225e0 __vectors +c01031f7 vector230 +c01089bf strncmp +c0104f5d get_pte +c0101a31 ide_device_size +c01029fc vector37 +c012614c check_swap_addr +c01030cb vector205 +c0102ebb vector161 +c010893d strncpy +c0102b2e vector71 +c0102eaf vector160 +c0103143 vector215 +c0102e8b vector157 +c0101ef8 intr_disable +c0102469 print_regs +c0102c9f vector112 +c01000b6 grade_backtrace2 +c0102fb7 vector182 +c0102923 vector12 +c0108d02 memcmp +c0102c84 vector109 +c0102963 vector20 +c0102a8c vector53 +c0102951 vector18 +c0102c06 vector95 +c01031c7 vector226 +c0102a68 vector49 +c0102a3b vector44 +c0102b6d vector78 +c0102f4b vector173 +c0108070 swapfs_read +c0102ccc vector117 +c01022a1 trap_in_kernel +c01062e9 swap_set_unswappable +c0102b91 vector82 +c0103197 vector222 +c0102905 vector8 +c0102e2b vector149 +c010039d cputchar +c0108bce memset +c010320f vector232 +c0101a6e ide_read_secs +c0102c69 vector106 +c010317f vector220 +c0102bd9 vector90 +c0102ed3 vector163 +c010888b srand +c0103227 vector234 +c01062ba swap_map_swappable +c0102add vector62 +c0102990 vector25 +c0103077 vector198 +c0102ce7 vector120 +c0100404 getchar +c0105157 page_remove +c0102a71 vector50 +c0102938 vector15 +c0126128 swap_out_num +c01082f0 printfmt +c0102e43 vector151 +c0102b9a vector83 +c0102bd0 vector89 +c0102bc7 vector88 +c0102885 trap +c0102f93 vector179 +c01029e1 vector34 +c011fced __STABSTR_END__ +c0102a4d vector46 +c0108976 strcmp +c0102d77 vector134 +c01031a3 vector223 +c0103167 vector218 +c0100570 debuginfo_eip +c01260a0 max_swap_offset +c0107464 insert_vma_struct +c0101f92 pic_init +c01031bb vector225 +c0102ff3 vector187 +c0104e75 pmm_init +c01029bd vector30 +c0102d26 vector127 +c0125424 ticks +c010302f vector192 +c0102ef7 vector166 +c0102b5b vector76 +c0102b52 vector75 +c0103053 vector195 +c0102e37 vector150 +c0102ab9 vector58 +c01032cf vector248 +c0102d02 vector123 +c0102c0f vector96 +c01029c6 vector31 +c01030b3 vector203 +c01048a7 alloc_pages +c0102db3 vector139 +c0102e5b vector153 +c0102edf vector164 +c0102cf0 vector121 +c0125780 switchk2u +c01028ea vector5 +c0102f03 vector167 +c0102e73 vector155 +c01032db vector249 +c0109a98 vpt +c01032e7 vector250 +c0102d0b vector124 +c0102c8d vector110 +c01030bf vector204 +c01260a8 swap_page +c01028b2 __trapret +c0100340 vcprintf +c0102d9b vector137 +c0100cc0 __warn +c01032c3 vector247 +c0102975 vector22 +c01030a7 vector202 +c0102b37 vector72 +c0102a9e vector55 +c01003b3 cputs +c0122000 bootstacktop +c0102d1d vector126 +c0102af8 vector65 +c01029ab vector28 +c0102f1b vector169 +c01062a0 swap_tick_event +c010321b vector233 +c010630a swap_out +c010602d kmalloc +c01072cd vma_create +c0102e13 vector147 +c0120000 bootstack +c0123000 __boot_pgdir +c0102c57 vector104 +c0125fe4 free_area +c0102cc3 vector116 +c01080e4 swapfs_write +c010adac __STAB_BEGIN__ +c012613c check_ptep +c0102a83 vector52 +c010294a vector17 +c0102fcf vector184 +c01088a4 strlen +c0126170 pgfault_num +c01030e3 vector207 +c0103017 vector190 +c01016ee ide_init +c0103263 vector239 +c0102bfd vector94 +c0102bf4 vector93 +c0102fff vector188 +c0108a12 strchr +c0102a5f vector48 +c012616c check_mm_struct +c0106286 swap_init_mm +c01000dd grade_backtrace1 +c0103173 vector219 +c0102e1f vector148 +c010318b vector221 +c0102b7f vector80 +c0102f33 vector171 +c0102e67 vector154 +c01029f3 vector36 +c01257cc switchu2k +c0103233 vector235 +c0102c60 vector105 +c0100c1a mon_kerninfo +c0126000 pages +c0102e07 vector146 +c0103023 vector191 +c0102c4e vector103 +c0100bbd mon_help +c010291c vector11 +c0105259 tlb_invalidate +c0102931 vector14 diff --git a/labcodes/lab3/obj/libs/printfmt.d b/labcodes/lab3/obj/libs/printfmt.d new file mode 100644 index 0000000000000000000000000000000000000000..7f093e2c5c51f8fe66f4042d3156c2cdb20748d9 --- /dev/null +++ b/labcodes/lab3/obj/libs/printfmt.d @@ -0,0 +1,2 @@ +obj/libs/printfmt.o obj/libs/printfmt.d: libs/printfmt.c libs/defs.h \ + libs/x86.h libs/error.h libs/stdio.h libs/stdarg.h libs/string.h diff --git a/labcodes/lab3/obj/libs/printfmt.o b/labcodes/lab3/obj/libs/printfmt.o new file mode 100644 index 0000000000000000000000000000000000000000..41a9c32cc965f862c9cc3ae6f994003b4da58691 Binary files /dev/null and b/labcodes/lab3/obj/libs/printfmt.o differ diff --git a/labcodes/lab3/obj/libs/rand.d b/labcodes/lab3/obj/libs/rand.d new file mode 100644 index 0000000000000000000000000000000000000000..fa05545e25213dc43dca26b8e504180acd762ca0 --- /dev/null +++ b/labcodes/lab3/obj/libs/rand.d @@ -0,0 +1,2 @@ +obj/libs/rand.o obj/libs/rand.d: libs/rand.c libs/x86.h libs/defs.h \ + libs/stdlib.h diff --git a/labcodes/lab3/obj/libs/rand.o b/labcodes/lab3/obj/libs/rand.o new file mode 100644 index 0000000000000000000000000000000000000000..86760c36aa0cfc7da8ee2a3b3e538a668e5ef1f5 Binary files /dev/null and b/labcodes/lab3/obj/libs/rand.o differ diff --git a/labcodes/lab3/obj/libs/string.d b/labcodes/lab3/obj/libs/string.d new file mode 100644 index 0000000000000000000000000000000000000000..dd7b1bae04cf9987465c430bc7f27da31336fc79 --- /dev/null +++ b/labcodes/lab3/obj/libs/string.d @@ -0,0 +1,2 @@ +obj/libs/string.o obj/libs/string.d: libs/string.c libs/string.h \ + libs/defs.h libs/x86.h diff --git a/labcodes/lab3/obj/libs/string.o b/labcodes/lab3/obj/libs/string.o new file mode 100644 index 0000000000000000000000000000000000000000..1e3bf53a07d3ded3268b428698b7a04ae324ab42 Binary files /dev/null and b/labcodes/lab3/obj/libs/string.o differ diff --git a/labcodes/lab3/obj/sign/tools/sign.d b/labcodes/lab3/obj/sign/tools/sign.d new file mode 100644 index 0000000000000000000000000000000000000000..c988243d10c66a835d03e66608f80a6996f2cde4 --- /dev/null +++ b/labcodes/lab3/obj/sign/tools/sign.d @@ -0,0 +1 @@ +obj/sign/tools/sign.o obj/sign/tools/sign.d: tools/sign.c diff --git a/labcodes/lab3/obj/sign/tools/sign.o b/labcodes/lab3/obj/sign/tools/sign.o new file mode 100644 index 0000000000000000000000000000000000000000..ecd7767f359c8813b3104cedf7dcdf5385d8bd07 Binary files /dev/null and b/labcodes/lab3/obj/sign/tools/sign.o differ diff --git a/labcodes/lab3/tools/gdbinit b/labcodes/lab3/tools/gdbinit index df5df85be4fc6cbcedb1c6f1547ab92a7fbc1cac..600f648570ee7d3686afa117629c316eda2f8f25 100644 --- a/labcodes/lab3/tools/gdbinit +++ b/labcodes/lab3/tools/gdbinit @@ -1,3 +1,5 @@ file bin/kernel target remote :1234 -break kern_init +b kern_init +break vmm_init +continue \ No newline at end of file