xv6/bootasm.S

 #include "asm.h"
#include "memlayout.h"
#include "mmu.h" # Start the first CPU: switch to -bit protected mode, jump into C.
# The BIOS loads this code from the first sector of the hard disk into
# memory at physical address 0x7c00 and starts executing in real mode
# with %cs= %ip=7c00. .code16 # Assemble for -bit mode
.globl start
start:
cli # BIOS enabled interrupts; disable # Zero data segment registers DS, ES, and SS.
xorw %ax,%ax # Set %ax to zero
movw %ax,%ds # -> Data Segment
movw %ax,%es # -> Extra Segment
movw %ax,%ss # -> Stack Segment # Physical address line A20 is tied to zero so that the first PCs
# with MB would run software that assumed MB. Undo that.
seta20.:
inb $0x64,%al # Wait for not busy
testb $0x2,%al
jnz seta20. movb $0xd1,%al # 0xd1 -> port 0x64
outb %al,$0x64 seta20.:
inb $0x64,%al # Wait for not busy
testb $0x2,%al
jnz seta20. movb $0xdf,%al # 0xdf -> port 0x60
outb %al,$0x60 # Switch from real to protected mode. Use a bootstrap GDT that makes
# virtual addresses map directly to physical addresses so that the
# effective memory map doesn’t change during the transition.
lgdt gdtdesc
movl %cr0, %eax
orl $CR0_PE, %eax
movl %eax, %cr0 # Complete transition to -bit protected mode by using long jmp
# to reload %cs and %eip. The segment descriptors are set up with no
# translation, so that the mapping is still the identity mapping.
ljmp $(SEG_KCODE<<), $start32 .code32 # Tell assembler to generate -bit code now.
start32:
# Set up the protected-mode data segment registers
movw $(SEG_KDATA<<), %ax # Our data segment selector
movw %ax, %ds # -> DS: Data Segment
movw %ax, %es # -> ES: Extra Segment
movw %ax, %ss # -> SS: Stack Segment
movw $, %ax # Zero segments not ready for use
movw %ax, %fs # -> FS
movw %ax, %gs # -> GS # Set up the stack pointer and call into C.
movl $start, %esp
call bootmain # If bootmain returns (it shouldn’t), trigger a Bochs
# breakpoint if running under Bochs, then loop.
movw $0x8a00, %ax # 0x8a00 -> port 0x8a00
movw %ax, %dx
outw %ax, %dx
movw $0x8ae0, %ax # 0x8ae0 -> port 0x8a00
outw %ax, %dx
spin:
jmp spin # Bootstrap GDT
.p2align # force byte alignment
gdt:
SEG_NULLASM # null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg gdtdesc:
.word (gdtdesc - gdt - ) # sizeof(gdt) -
.long gdt # address gdt

xv6/bootmain.c

 // Boot loader.
//
// Part of the boot sector, along with bootasm.S, which calls bootmain().
// bootasm.S has put the processor into protected 32-bit mode.
// bootmain() loads an ELF kernel image from the disk starting at
// sector 1 and then jumps to the kernel entry routine. #include "types.h"
#include "elf.h"
#include "x86.h"
#include "memlayout.h" #define SECTSIZE 512 void readseg(uchar*, uint, uint); void
bootmain(void)
{
struct elfhdr *elf;
struct proghdr *ph, *eph;
void (*entry)(void);
uchar* pa; elf = (struct elfhdr*)0x10000; // scratch space // Read 1st page off disk
readseg((uchar*)elf, , ); // Is this an ELF executable?
if(elf->magic != ELF_MAGIC)
return; // let bootasm.S handle error // Load each program segment (ignores ph flags).
ph = (struct proghdr*)((uchar*)elf + elf->phoff);
eph = ph + elf->phnum;
for(; ph < eph; ph++){
pa = (uchar*)ph->paddr;
readseg(pa, ph->filesz, ph->off);
if(ph->memsz > ph->filesz)
stosb(pa + ph->filesz, , ph->memsz - ph->filesz);
} // Call the entry point from the ELF header.
// Does not return!
entry = (void(*)(void))(elf->entry);
entry();
} void
waitdisk(void)
{
// Wait for disk ready.
while((inb(0x1F7) & 0xC0) != 0x40)
;
} // Read a single sector at offset into dst.
void
readsect(void *dst, uint offset)
{
// Issue command.
waitdisk();
outb(0x1F2, ); // count = 1
outb(0x1F3, offset);
outb(0x1F4, offset >> );
outb(0x1F5, offset >> );
outb(0x1F6, (offset >> ) | 0xE0);
outb(0x1F7, 0x20); // cmd 0x20 - read sectors // Read data.
waitdisk();
insl(0x1F0, dst, SECTSIZE/);
} // Read ’count’ bytes at ’offset’ from kernel into physical address ’pa’.
// Might copy more than asked.
void
readseg(uchar* pa, uint count, uint offset)
{
uchar* epa; epa = pa + count; // Round down to sector boundary.
pa -= offset % SECTSIZE; // Translate from bytes to sectors; kernel starts at sector 1.
offset = (offset / SECTSIZE) + ; // 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(; pa < epa; pa += SECTSIZE, offset++)
readsect(pa, offset);
}

xv6/bootasm.S + xv6/bootmain.c的更多相关文章

  1. XV6源代码阅读-中断与系统调用

    Exercise1 源代码阅读 1.启动部分: bootasm.S bootmain.c 和xv6初始化模块:main.c bootasm.S 由16位和32位汇编混合编写成的XV6引导加载器.boo ...

  2. xv6 makefile

    1. xv6.img的构建 在makefile中 bootblock: bootasm.S bootmain.c $(CC) $(CFLAGS) -fno-pic -O -nostdinc -I. - ...

  3. xv6的作业翻译——作业1 - shell和系统调用

    Xv6的lecture LEC 1 Operating systems   L1: O/S overview L1:O/S概述   * 6.828 goals 6.828的目标   Understan ...

  4. ubuntu编译运行xv6

    最近想找个简单的类Unix系统学习下, xv6不错的, 所有代码加起来不到一万行,首先把代码跑起来还是很重要的. # 下载xv6源码并编译 git clone git://pdos.csail.mit ...

  5. xv6 + Qemu 在Ubuntu下编译运行教程【转】

    转自:https://blog.csdn.net/yinglang19941010/article/details/49310111 如果想要离线看教程,可以下载该 文档 一.使用工具说明 1.    ...

  6. XV6操作系统代码阅读心得(三):锁

    锁是操作系统中实现进程同步的重要机制. 基本概念 临界区(Critical Section)是指对共享数据进行访问与操作的代码区域.所谓共享数据,就是可能有多个代码执行流并发地执行,并在执行中可能会同 ...

  7. XV6学习(2)Lab syscall

    实验的代码放在了Github上. 第二个实验是Lab: system calls. 这个实验主要就是自己实现几个简单的系统调用并添加到XV6中. XV6系统调用 添加系统调用主要有以下几步: 在use ...

  8. XV6学习(1) Lab util

    正在学习MIT的6.S081,把做的实验写一写吧. 实验的代码放在了Github上. 第一个实验是Lab util,算是一个热身的实验,没有涉及到系统的底层,就是使用系统调用来完成几个用户模式的小程序 ...

  9. lab 1实验报告

    练习1:理解通过make生成执行文件的过程. 1.操作系统镜像文件ucore.img是如何一步一步生成的? 生成 bin/kern 部分 生成 init.o 生成 readline.o 生成 stdi ...

随机推荐

  1. linux下面Zookeeper的单机模式(standalone)

    1.下载 zk下载地址 http://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/ 我用的是http://mirrors.tuna.tsinghua.e ...

  2. MATLAB串口操作和GUI编程

    程序说明 V1.0 2015/2/08 MATLAB串口操作和GUI编程   概述   本文介绍了程序AD9512_Serial_GUI的编程思路和功能.该程序设计到MATLAB的图像用户界面编程的基 ...

  3. 【数据库】同一字段根据不同条件更新的sql语句的写法

    语法: update test set 字段1=case when 条件1 then 值1 when 条件2 then 值2 end 示例: update PMS_ProjectInfo set Pr ...

  4. P3984 高兴的津津

    题目描述 津津上高中了.她在自己的妈妈的魔鬼训练下,成为了一个神犇,每次参加一次OI比赛必拿Au虐全场.每次她拿到一个Au后就很高兴.假设津津不会因为其它事高兴,并且她的高兴会持续T天(包包含获奖当天 ...

  5. Simpsons’ Hidden Talents HDU - 2594(拓展kmp)

    Sample Input clinton homer riemann marjorie Sample Output 0 rie 3 看输出才题意...拓展kmp特征很明显嘛....注意开始就匹配到尾的 ...

  6. sql case用法举例

    用一条sql语句查出学生表成绩小于60为不及格60-80为良好80-90为优秀 select name, case when 成绩<60 then 不及格 when 成绩>=60 and ...

  7. 【bzoj3589】动态树

    Portal --> bzoj3589 Description 给你一棵\(n\)个节点的树,总共有\(q\)次操作,每次操作是以下两种中的一种: 操作\((0,x,delta)\):给以\(x ...

  8. HTTP ------ connection 为 close 和 keep-alive 的区别

    keep-alive和close这个要从TCP握手讲起 HTTP请求是基于TCP连接的,TCP的请求会包含(三次握手,中间请求,四次挥手)在HTTP/1.0时代,一个HTTP请求就要三次握手和四次挥手 ...

  9. [DeeplearningAI笔记]卷积神经网络4.1-4.5 人脸识别/one-shot learning/Siamase网络/Triplet损失/将面部识别转化为二分类问题

    4.4特殊应用:人脸识别和神经网络风格转换 觉得有用的话,欢迎一起讨论相互学习~Follow Me 4.1什么是人脸识别 Face verification人脸验证 VS face recogniti ...

  10. OpenCV---分水岭算法

    推文: OpenCV学习(7) 分水岭算法(1)(原理简介简单明了) OpenCV-Python教程:31.分水岭算法对图像进行分割(步骤讲解不错) 使用分水岭算法进行图像分割 (一)获取灰度图像,二 ...