├── .gitignore ├── .gitmodules ├── Dockerfile ├── Makefile ├── Readme.md ├── bootloader ├── Cargo.lock ├── Cargo.toml ├── Makefile ├── linker.ld ├── src │ ├── boot.S │ ├── elf.rs │ └── main.rs └── xv6-rs-bootloader.json ├── docker-compose.yml ├── kernel ├── Cargo.lock ├── Cargo.toml ├── Makefile ├── kernel.ld ├── lib │ ├── entry.S │ ├── entrypgdir.c │ ├── memlayout.h │ ├── mmu.h │ └── types.h ├── src │ ├── console.rs │ ├── io │ │ ├── mod.rs │ │ └── uart.rs │ ├── lib.rs │ └── util │ │ └── lazy.rs └── xv6-rs-kernel.json └── lib └── x86 ├── Cargo.lock ├── Cargo.toml ├── src ├── instruction.rs └── lib.rs └── x86.iml /.gitignore: -------------------------------------------------------------------------------- 1 | *.vscode/ 2 | *target/ 3 | *build/ 4 | .DS_Store -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lab"] 2 | path = lab 3 | url = https://pdos.csail.mit.edu/6.828/2017/jos.git 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | LABEL maintainer="youta1119 " 3 | LABEL version="1.0" 4 | LABEL description="xv6 rs compile" 5 | 6 | RUN mkdir /root/work 7 | WORKDIR /root/work 8 | RUN apt-get -y update &&\ 9 | apt-get -y install curl\ 10 | build-essential\ 11 | gdb\ 12 | gcc-multilib\ 13 | m4\ 14 | m4-doc\ 15 | libncurses5-dev\ 16 | git\ 17 | python\ 18 | pkg-config\ 19 | libpixman-1-dev\ 20 | zlib1g-dev\ 21 | libglib2.0-dev\ 22 | libtool-bin\ 23 | libsdl1.2-dev 24 | 25 | #make gmp 26 | ARG GMP_VERSION="5.0.5" 27 | RUN curl -SL ftp://ftp.gmplib.org/pub/gmp-${GMP_VERSION}/gmp-${GMP_VERSION}.tar.bz2 | tar xj -C ./ 28 | RUN cd ./gmp-${GMP_VERSION} &&\ 29 | ./configure --prefix=/usr/local &&\ 30 | make -s -j8 &&\ 31 | make check -s -j8 &&\ 32 | make install &&\ 33 | rm -rf ../gmp-${GMP_VERSION} &&\ 34 | ldconfig 35 | 36 | #make mpfr 37 | ARG MPFR_VIRSION="3.1.3" 38 | RUN curl -SL http://www.mpfr.org/mpfr-${MPFR_VIRSION}/mpfr-${MPFR_VIRSION}.tar.bz2 | tar xj -C ./ 39 | RUN cd ./mpfr-${MPFR_VIRSION} &&\ 40 | ./configure --prefix=/usr/local &&\ 41 | make -s -j8 &&\ 42 | make check -s -j8 &&\ 43 | make install &&\ 44 | rm -rf ../mpfr-${MPFR_VIRSION} &&\ 45 | ldconfig 46 | 47 | #make mpc 48 | ARG MPC_VIRSION="0.9" 49 | RUN curl -SL http://www.multiprecision.org/downloads/mpc-${MPC_VIRSION}.tar.gz | tar zx -C ./ 50 | RUN cd ./mpc-${MPC_VIRSION} &&\ 51 | ./configure -target=i386-jos-elf --disable-nls --prefix=/usr/local &&\ 52 | make -s -j8 &&\ 53 | make check -s -j8 &&\ 54 | make install &&\ 55 | rm -rf ../mpc-${MPC_VIRSION} &&\ 56 | ldconfig 57 | 58 | #make binutils 59 | ARG BINUTILS_VERSION="2.21.1" 60 | RUN curl -SL https://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.bz2 | tar xj -C ./ 61 | RUN cd ./binutils-${BINUTILS_VERSION} &&\ 62 | ./configure --prefix=/usr/local --target=i386-jos-elf --disable-werror &&\ 63 | make -s -j8 &&\ 64 | make install &&\ 65 | rm -rf ../binutils-${BINUTILS_VERSION} 66 | 67 | #make gcc 68 | ARG GCC_VERSION="4.6.4" 69 | RUN curl -SL http://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION}/gcc-core-${GCC_VERSION}.tar.bz2 | tar xj -C ./ 70 | RUN cd ./gcc-${GCC_VERSION} &&\ 71 | mkdir gcc-build &&\ 72 | cd gcc-build &&\ 73 | ../configure --prefix=/usr/local --target=i386-jos-elf --disable-werror \ 74 | --disable-libssp --disable-libmudflap --with-newlib --without-headers --enable-languages=c &&\ 75 | make -s -j8 all-gcc &&\ 76 | make install-gcc &&\ 77 | make -s -j8 all-target-libgcc &&\ 78 | make install-target-libgcc &&\ 79 | rm -rf ../../gcc-${GCC_VERSION} 80 | 81 | #make gdb 82 | ARG GDB_VERSION="7.3.1" 83 | RUN curl -SL http://ftpmirror.gnu.org/gdb/gdb-${GDB_VERSION}.tar.bz2 | tar xj -C ./ 84 | RUN cd ./gdb-${GDB_VERSION} &&\ 85 | ./configure --prefix=/usr/local --target=i386-jos-elf --program-prefix=i386-jos-elf- --disable-werror &&\ 86 | make -s -j8 all &&\ 87 | make install &&\ 88 | rm -rf ../gdb-${GDB_VERSION} 89 | 90 | #make qemu 91 | RUN git clone http://web.mit.edu/ccutler/www/qemu.git -b 6.828-2.3.0 92 | RUN cd qemu &&\ 93 | ./configure --disable-kvm --disable-werror --target-list="i386-softmmu x86_64-softmmu" &&\ 94 | make &&\ 95 | make install &&\ 96 | rm -rf ../qemu 97 | 98 | RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly 99 | ENV PATH $PATH:/root/.cargo/bin 100 | RUN cargo install xargo 101 | RUN rustup component add rust-src -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | V := @ 3 | OBJ_DIR := build 4 | .PHONY: all 5 | 6 | all:$(OBJ_DIR)/xv6-rs.img 7 | 8 | qemu: $(OBJ_DIR)/xv6-rs.img 9 | qemu-system-i386 -no-reboot -nographic -serial mon:stdio build/xv6-rs.img 10 | #qemu-system-i386 -d int -no-reboot -hda $< 11 | 12 | clean: 13 | make -C bootloader V=$(V) clean 14 | make -C kernel V=$(V) clean 15 | rm -rf $(OBJ_DIR) 16 | 17 | $(OBJ_DIR)/bootloader/bootloader: 18 | $(V)make -C bootloader V=$(V) 19 | 20 | $(OBJ_DIR)/kernel/kernel: 21 | $(V)make -C kernel V=$(V) 22 | # How to build the kernel disk image 23 | $(OBJ_DIR)/xv6-rs.img: $(OBJ_DIR)/bootloader/bootloader $(OBJ_DIR)/kernel/kernel 24 | @echo + mk $@ 25 | $(V)dd if=/dev/zero of=$(OBJ_DIR)/xv6-rs.img~ count=10000 2>/dev/null 26 | $(V)dd if=$(OBJ_DIR)/bootloader/bootloader of=$(OBJ_DIR)/xv6-rs.img~ conv=notrunc 2>/dev/null 27 | $(V)dd if=$(OBJ_DIR)/kernel/kernel of=$(OBJ_DIR)/xv6-rs.img~ seek=1 conv=notrunc 2>/dev/null 28 | $(V)mv $(OBJ_DIR)/xv6-rs.img~ $(OBJ_DIR)/xv6-rs.img -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # xv6-rs 2 | xv6-rs is re-implementation xv6 in rust 3 | 4 | ## requirement 5 | - rustc 1.32.0-nightly 6 | - xargo 0.3.12 7 | - i386-jos-elf gnu tool-chain 8 | - qemu 9 | 10 | **note: you can use docker** 11 | 12 | `docker-compose build` 13 | 14 | `docker-compose run --rm toolchain` 15 | 16 | 17 | ## build 18 | `make` 19 | 20 | ## run 21 | `make qemu` 22 | -------------------------------------------------------------------------------- /bootloader/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "bootloader" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "x86 0.1.0", 6 | ] 7 | 8 | [[package]] 9 | name = "x86" 10 | version = "0.1.0" 11 | 12 | -------------------------------------------------------------------------------- /bootloader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bootloader" 3 | version = "0.1.0" 4 | authors = ["youta ogino "] 5 | 6 | [dependencies] 7 | x86 = { path = "../lib/x86" } 8 | 9 | 10 | -------------------------------------------------------------------------------- /bootloader/Makefile: -------------------------------------------------------------------------------- 1 | V := @ 2 | OBJ_DIR := ../build 3 | 4 | OBJCOPY := objcopy 5 | OBJDUMP := objdump 6 | 7 | BUILD_FRAVER := release 8 | RUSTC_TERGET := xv6-rs-bootloader 9 | CARGO_FLAG := 10 | ifeq ($(BUILD_FRAVER),release) 11 | CARGO_FLAG += --release 12 | endif 13 | .PHONY: all 14 | 15 | all: $(OBJ_DIR)/bootloader/bootloader; 16 | 17 | $(OBJ_DIR)/bootloader/bootloader: target/$(RUSTC_TERGET)/$(BUILD_FRAVER)/bootloader 18 | $(V)mkdir -p $(OBJ_DIR)/bootloader 19 | $(V)$(OBJDUMP) -S $< > $@.asm 20 | $(V)$(OBJCOPY) -O binary $< $@ 21 | 22 | target/$(RUSTC_TERGET)/$(BUILD_FRAVER)/bootloader: src/*.rs src/*.S $(RUSTC_TERGET).json 23 | RUST_TARGET_PATH=$(shell pwd) xargo build --target $(RUSTC_TERGET) $(CARGO_FLAG) 24 | 25 | clean: 26 | $(V)rm -rf $(OBJ_DIR)/bootloader 27 | $(V)xargo clean -------------------------------------------------------------------------------- /bootloader/linker.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 2 | OUTPUT_ARCH(i386) 3 | ENTRY(start) 4 | IPLBASE = 0x7c00; 5 | 6 | SECTIONS { 7 | . = IPLBASE; 8 | .text : AT(IPLBASE) { 9 | *(.text) 10 | *(.data) 11 | *(.bbs) 12 | } 13 | . = IPLBASE + 510; 14 | .sign : { 15 | SHORT(0xaa55) 16 | } 17 | } -------------------------------------------------------------------------------- /bootloader/src/boot.S: -------------------------------------------------------------------------------- 1 | # Start the CPU: switch to 32-bit protected mode, jump into C. 2 | # The BIOS loads this code from the first sector of the hard disk into 3 | # memory at physical address 0x7c00 and starts executing in real mode 4 | # with %cs=0 %ip=7c00. 5 | 6 | .set PROT_MODE_CSEG, 0x8 # kernel code segment selector 7 | .set PROT_MODE_DSEG, 0x10 # kernel data segment selector 8 | .set CR0_PE_ON, 0x1 # protected mode enable flag 9 | .set STA_X, 0x8 // Executable segment 10 | .set STA_R, 0x2 // Readable (executable segments) 11 | .set STA_W, 0x2 // Writeable (non-executable segments) 12 | 13 | .macro SEG_NULL 14 | .word 0, 0 15 | .byte 0, 0, 0, 0 16 | .endm 17 | 18 | .macro SEG type, base, lim 19 | .word ((\lim >> 12) & 0xffff), (\base & 0xffff) 20 | .byte ((\base >> 16) & 0xff), (0x90 | \type), (0xC0 | ((\lim >> 28) & 0xf)), ((\base >> 24) & 0xff) 21 | .endm 22 | 23 | .code16 # Assemble for 16-bit mode 24 | .globl start 25 | 26 | start: 27 | cli # Disable interrupts 28 | cld # String operations increment 29 | # Set up the important data segment registers (DS, ES, SS). 30 | xorw %ax,%ax # Segment number zero 31 | movw %ax,%ds # -> Data Segment 32 | movw %ax,%es # -> Extra Segment 33 | movw %ax,%ss # -> Stack Segment 34 | 35 | 36 | # Enable A20: 37 | # For backwards compatibility with the earliest PCs, physical 38 | # address line 20 is tied low, so that addresses higher than 39 | # 1MB wrap around to zero by default. This code undoes this. 40 | seta20.1: 41 | inb $0x64,%al # Wait for not busy 42 | testb $0x2,%al 43 | jnz seta20.1 44 | 45 | movb $0xd1,%al # 0xd1 -> port 0x64 46 | outb %al,$0x64 47 | 48 | seta20.2: 49 | inb $0x64,%al # Wait for not busy 50 | testb $0x2,%al 51 | jnz seta20.2 52 | 53 | movb $0xdf,%al # 0xdf -> port 0x60 54 | outb %al,$0x60 55 | 56 | # Switch from real to protected mode, using a bootstrap GDT 57 | # and segment translation that makes virtual addresses 58 | # identical to their physical addresses, so that the 59 | # effective memory map does not change during the switch. 60 | lgdt gdtdesc 61 | movl %cr0, %eax 62 | orl $CR0_PE_ON, %eax 63 | movl %eax, %cr0 64 | 65 | # Jump to next instruction, but in 32-bit code segment. 66 | # Switches processor into 32-bit mode. 67 | ljmp $PROT_MODE_CSEG, $protcseg 68 | 69 | .code32 # Assemble for 32-bit mode 70 | protcseg: 71 | # Set up the protected-mode data segment registers 72 | movw $PROT_MODE_DSEG, %ax # Our data segment selector 73 | movw %ax, %ds # -> DS: Data Segment 74 | movw %ax, %es # -> ES: Extra Segment 75 | movw %ax, %ss # -> SS: Stack Segment 76 | movw %ax, %fs # -> FS 77 | movw %ax, %gs # -> GS 78 | 79 | 80 | # Set up the stack pointer and call into C. 81 | movl $start, %esp 82 | call bootmain 83 | 84 | # If bootmain returns (it shouldn't), loop. 85 | spin: 86 | hlt 87 | jmp spin 88 | 89 | # Bootstrap GDT 90 | #.p2align 2 # force 4 byte alignment 91 | gdt: 92 | SEG_NULL # null seg 93 | SEG STA_X|STA_R, 0x0, 0xffffffff # code seg 94 | SEG STA_W, 0x0, 0xffffffff # data seg 95 | 96 | gdtdesc: 97 | .word 0x17 # sizeof(gdt) - 1 98 | .long gdt # address gdt 99 | -------------------------------------------------------------------------------- /bootloader/src/elf.rs: -------------------------------------------------------------------------------- 1 | pub const ELF_MAGIC: u32 = 0x464C457F; // "\x7FELF" in little endian 2 | 3 | #[repr(C)] 4 | pub struct ElfHeader { 5 | pub magic: u32, 6 | pub elf: [u8; 12], 7 | pub typ: u16, 8 | pub machine: u16, 9 | pub version: u32, 10 | pub entry: u32, 11 | pub phoff: u32, // physical header offset 12 | pub shoff: u32, 13 | pub flags: u32, 14 | pub ehsize: u16, 15 | pub phentsize: u16, 16 | pub phnum: u16, 17 | pub shntsize: u16, 18 | pub shnum: u16, 19 | pub shstrndx: u16, 20 | } 21 | 22 | #[repr(C)] 23 | pub struct ProgramHeader { 24 | pub typ: u32, 25 | pub off: u32, 26 | pub vaddr: u32, 27 | pub paddr: u32, 28 | pub filesz: u32, 29 | pub memsz: u32, 30 | pub flags: u32, 31 | pub align: u32, 32 | } 33 | 34 | -------------------------------------------------------------------------------- /bootloader/src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | #![feature(lang_items)] 4 | #![feature(global_asm)] 5 | #![feature(asm)] 6 | 7 | extern crate x86; 8 | 9 | mod elf; 10 | use elf::{ElfHeader, ProgramHeader, ELF_MAGIC}; 11 | use x86::instruction::{inb, insl, outb}; 12 | use core::panic::PanicInfo; 13 | 14 | global_asm!(include_str!("boot.S")); 15 | 16 | const SECTOR_SIZE: u32 = 512; 17 | #[no_mangle] 18 | pub unsafe extern "C" fn bootmain() { 19 | let elf_header = 0x10000 as *const ElfHeader;// scratch space 20 | read_segment(elf_header as u32, SECTOR_SIZE * 8, 0); 21 | if (*elf_header).magic != ELF_MAGIC { 22 | //outw(0x8A00, 0x8A00); 23 | //outw(0x8A00, 0x8E00); 24 | return; 25 | } 26 | // load each program segment (ignores ph flags) 27 | let mut ph = ((elf_header as *const u8).offset((*elf_header).phoff as isize)) as *const ProgramHeader; 28 | let eph = ph.offset((*elf_header).phnum as isize); 29 | while ph < eph { 30 | read_segment((*ph).paddr, (*ph).memsz, (*ph).off); 31 | ph = ((ph as u32) + 32) as *const ProgramHeader; //ph.offset(1); 32 | } 33 | // call the entry point from the ELF header 34 | // note: does not return! 35 | let entry: extern "C" fn() -> ! = core::mem::transmute((*elf_header).entry); 36 | entry(); 37 | } 38 | 39 | // Read 'count' bytes at 'offset' from kernel into physical address 'pa'. 40 | // Might copy more than asked 41 | #[inline(never)] 42 | unsafe fn read_segment(pa: u32, count: u32, offset: u32) { 43 | let epa = pa + count; 44 | // round down to sector boundary 45 | let mut bpa = pa & !(SECTOR_SIZE - 1); 46 | 47 | // translate from bytes to sectors, and kernel starts at sector 1 48 | let mut offset = (offset / SECTOR_SIZE) + 1; 49 | // If this is too slow, we could read lots of sectors at a time. 50 | // We'd write more to memory than asked, but it doesn't matter -- 51 | // we load in increasing order. 52 | while bpa < epa { 53 | // Since we haven't enabled paging yet and we're using 54 | // an identity segment mapping (see boot.S), we can 55 | // use physical addresses directly. This won't be the 56 | // case once JOS enables the MMU. 57 | read_sector(bpa , offset); 58 | offset += 1; 59 | bpa += SECTOR_SIZE; 60 | } 61 | } 62 | 63 | unsafe fn wait_disk() { 64 | // wait for disk reaady 65 | while (inb(0x1F7) & 0xC0) != 0x40 {}; 66 | } 67 | 68 | unsafe fn read_sector(dst: u32, offset: u32) { 69 | // wait for disk to be ready 70 | wait_disk(); 71 | outb(0x1F2, 1); // count = 1 72 | outb(0x1F3, offset as u8); 73 | outb(0x1F4, (offset >> 8) as u8); 74 | outb(0x1F5, (offset >> 16) as u8); 75 | outb(0x1F6, ((offset >> 24) | 0xE0) as u8); 76 | outb(0x1F7, 0x20); // cmd 0x20 - read sectors 77 | // wait for disk to be ready 78 | wait_disk(); 79 | // read a sector 80 | insl(0x1F0, dst, SECTOR_SIZE / 4); 81 | } 82 | 83 | #[panic_handler] 84 | #[no_mangle] 85 | pub extern "C" fn panic(_info: &PanicInfo) -> ! { 86 | loop {} 87 | } 88 | 89 | #[lang = "eh_personality"] 90 | #[no_mangle] 91 | pub extern "C" fn eh_personality() { 92 | loop {} 93 | } 94 | -------------------------------------------------------------------------------- /bootloader/xv6-rs-bootloader.json: -------------------------------------------------------------------------------- 1 | { 2 | "llvm-target": "i386-unknown-none", 3 | "target-endian": "little", 4 | "target-c-int-width": "32", 5 | "target-pointer-width": "32", 6 | "max-atomic-width": "64", 7 | "data-layout": "e-m:e-i32:32-f32:32-n8:16:32-S128-p:32:32:32", 8 | "arch": "x86", 9 | "cpu": "pentium4", 10 | "os": "none", 11 | "linker-flavor": "ld.lld", 12 | "linker": "rust-lld", 13 | "pre-link-args": { 14 | "ld.lld": [ 15 | "--script=linker.ld" 16 | ] 17 | }, 18 | "features": "-mmx,-sse,+soft-float", 19 | "dynamic-linking": false, 20 | "has-rpath": false, 21 | "no-default-libraries": true, 22 | "has-elf-tls": true, 23 | "eliminate-frame-pointer": false, 24 | "no-compiler-rt": true, 25 | "disable-redzone": true, 26 | "panic-strategy": "abort", 27 | "executables": true 28 | } 29 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | toolchain: 4 | build: 5 | context: . 6 | dockerfile: Dockerfile 7 | volumes: 8 | - .:/root/work 9 | - xargo:/root/.xargo 10 | volumes: 11 | xargo: 12 | -------------------------------------------------------------------------------- /kernel/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "kernel" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "x86 0.1.0", 8 | ] 9 | 10 | [[package]] 11 | name = "lazy_static" 12 | version = "1.2.0" 13 | source = "registry+https://github.com/rust-lang/crates.io-index" 14 | dependencies = [ 15 | "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 16 | ] 17 | 18 | [[package]] 19 | name = "spin" 20 | version = "0.4.10" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | 23 | [[package]] 24 | name = "x86" 25 | version = "0.1.0" 26 | 27 | [metadata] 28 | "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" 29 | "checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" 30 | -------------------------------------------------------------------------------- /kernel/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kernel" 3 | version = "0.1.0" 4 | authors = ["youta ogino "] 5 | 6 | [dependencies] 7 | x86 = { path = "../lib/x86" } 8 | spin = "0.4.10" 9 | 10 | [dependencies.lazy_static] 11 | version = "1.0" 12 | features = ["spin_no_std"] 13 | 14 | [lib] 15 | crate-type = ["staticlib"] -------------------------------------------------------------------------------- /kernel/Makefile: -------------------------------------------------------------------------------- 1 | V := @ 2 | OBJ_DIR := ../build 3 | 4 | OBJCOPY:= i386-jos-elf-objcopy 5 | OBJDUMP:= i386-jos-elf-objdump 6 | CC := i386-jos-elf-gcc -pipe 7 | LD := i386-jos-elf-ld 8 | NM := i386-jos-elf-nm 9 | GCC_LIB := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) 10 | 11 | # compiler flags 12 | # -fno-builtin is required to avoid refs to undefined functions in the kernel. 13 | # Only optimize to -O1 to discourage inlining, which complicates backtraces. 14 | CFLAGS := -O1 -fno-builtin -I. -MD 15 | CFLAGS += -fno-omit-frame-pointer 16 | CFLAGS += -std=gnu99 17 | CFLAGS += -static 18 | CFLAGS += -Wall -Wno-format -Wno-unused -Werror -gstabs -m32 19 | # -fno-tree-ch prevented gcc from sometimes reordering read_ebp() before 20 | # mon_backtrace()'s function prologue on gcc version: (Debian 4.7.2-5) 4.7.2 21 | CFLAGS += -fno-tree-ch 22 | # Add -fno-stack-protector if the option exists. 23 | CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector) 24 | #kernel option 25 | CFLAGS += -DJOS_KERNEL -gstabs 26 | # linker flags 27 | LDFLAGS := -m elf_i386 28 | LDFLAGS += -T kernel.ld -nostdlib 29 | # rustc option 30 | BUILD_FRAVER := debug 31 | RUSTC_TERGET := xv6-rs-kernel 32 | CARGO_FLAG := 33 | ifeq ($(BUILD_FRAVER),release) 34 | CARGO_FLAG += --release 35 | endif 36 | RUST_LIB := target/$(RUSTC_TERGET)/$(BUILD_FRAVER)/libkernel.a 37 | KERN_SRCFILES := lib/entry.S lib/entrypgdir.c 38 | # Only build files if they exist. 39 | KERN_SRCFILES := $(wildcard $(KERN_SRCFILES)) 40 | # Binary program images to embed within the kernel. 41 | KERN_OBJFILES := $(patsubst %.c, $(OBJ_DIR)/%.o, $(KERN_SRCFILES)) 42 | KERN_OBJFILES := $(patsubst %.S, $(OBJ_DIR)/%.o, $(KERN_OBJFILES)) 43 | 44 | KERN_OBJFILES := $(patsubst $(OBJ_DIR)/lib/%, $(OBJ_DIR)/kernel/%, $(KERN_OBJFILES)) 45 | KERN_OBJFILES += $(RUST_LIB) 46 | 47 | .PHONY: all 48 | 49 | all: $(OBJ_DIR)/kernel/kernel ; 50 | 51 | # How to build kernel object files 52 | $(OBJ_DIR)/kernel/%.o: lib/%.c 53 | @echo + cc $< 54 | @mkdir -p $(@D) 55 | $(V)$(CC) -nostdinc $(CFLAGS) -c -o $@ $< 56 | 57 | $(OBJ_DIR)/kernel/%.o: lib/%.S 58 | @echo + as $< 59 | @mkdir -p $(@D) 60 | $(V)$(CC) -nostdinc $(CFLAGS) -c -o $@ $< 61 | 62 | $(RUST_LIB): src/*.rs $(RUSTC_TERGET).json 63 | RUST_TARGET_PATH=$(shell pwd) xargo build --target $(RUSTC_TERGET) $(CARGO_FLAG) 64 | 65 | # How to build the kernel itself 66 | $(OBJ_DIR)/kernel/kernel:$(KERN_OBJFILES) 67 | @echo + ld $@ 68 | $(V)$(LD) -o $@ $(LDFLAGS) $(KERN_OBJFILES) $(GCC_LIB) -b binary 69 | $(V)$(OBJDUMP) -S $@ > $@.asm 70 | $(V)$(NM) -n $@ > $@.sym 71 | 72 | clean: 73 | $(V)rm -rf $(OBJ_DIR)/kernel 74 | $(V)xargo clean 75 | -------------------------------------------------------------------------------- /kernel/kernel.ld: -------------------------------------------------------------------------------- 1 | /* Simple linker script for the JOS kernel. 2 | See the GNU ld 'info' manual ("info ld") to learn the syntax. */ 3 | 4 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 5 | OUTPUT_ARCH(i386) 6 | ENTRY(_start) 7 | 8 | SECTIONS 9 | { 10 | /* Link the kernel at this address: "." means the current address */ 11 | . = 0xF0100000; 12 | 13 | /* AT(...) gives the load address of this section, which tells 14 | the boot loader where to load the kernel in physical memory */ 15 | .text : AT(0x100000) { 16 | *(.text .stub .text.* .gnu.linkonce.t.*) 17 | } 18 | 19 | PROVIDE(etext = .); /* Define the 'etext' symbol to this value */ 20 | 21 | .rodata : { 22 | *(.rodata .rodata.* .gnu.linkonce.r.*) 23 | } 24 | 25 | /* Include debugging information in kernel memory */ 26 | .stab : { 27 | PROVIDE(__STAB_BEGIN__ = .); 28 | *(.stab); 29 | PROVIDE(__STAB_END__ = .); 30 | BYTE(0) /* Force the linker to allocate space 31 | for this section */ 32 | } 33 | 34 | .stabstr : { 35 | PROVIDE(__STABSTR_BEGIN__ = .); 36 | *(.stabstr); 37 | PROVIDE(__STABSTR_END__ = .); 38 | BYTE(0) /* Force the linker to allocate space 39 | for this section */ 40 | } 41 | 42 | /* Adjust the address for the data segment to the next page */ 43 | . = ALIGN(0x1000); 44 | 45 | /* The data segment */ 46 | .data : { 47 | *(.data) 48 | } 49 | 50 | PROVIDE(edata = .); 51 | 52 | .bss : { 53 | *(.bss) 54 | } 55 | 56 | PROVIDE(end = .); 57 | 58 | /DISCARD/ : { 59 | *(.eh_frame .note.GNU-stack) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /kernel/lib/entry.S: -------------------------------------------------------------------------------- 1 | /* See COPYRIGHT for copyright information. */ 2 | 3 | #include "mmu.h" 4 | #include "memlayout.h" 5 | 6 | # Shift Right Logical 7 | #define SRL(val, shamt) (((val) >> (shamt)) & ~(-1 << (32 - (shamt)))) 8 | 9 | 10 | ################################################################### 11 | # The kernel (this code) is linked at address ~(KERNBASE + 1 Meg), 12 | # but the bootloader loads it at address ~1 Meg. 13 | # 14 | # RELOC(x) maps a symbol x from its link address to its actual 15 | # location in physical memory (its load address). 16 | ################################################################### 17 | 18 | #define RELOC(x) ((x) - KERNBASE) 19 | 20 | #define MULTIBOOT_HEADER_MAGIC (0x1BADB002) 21 | #define MULTIBOOT_HEADER_FLAGS (0) 22 | #define CHECKSUM (-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)) 23 | 24 | ################################################################### 25 | # entry point 26 | ################################################################### 27 | 28 | .text 29 | 30 | # The Multiboot header 31 | .align 4 32 | .long MULTIBOOT_HEADER_MAGIC 33 | .long MULTIBOOT_HEADER_FLAGS 34 | .long CHECKSUM 35 | 36 | # '_start' specifies the ELF entry point. Since we haven't set up 37 | # virtual memory when the bootloader enters this code, we need the 38 | # bootloader to jump to the *physical* address of the entry point. 39 | .globl _start 40 | _start = RELOC(entry) 41 | 42 | .globl entry 43 | entry: 44 | movw $0x1234,0x472 # warm boot 45 | 46 | # We haven't set up virtual memory yet, so we're running from 47 | # the physical address the boot loader loaded the kernel at: 1MB 48 | # (plus a few bytes). However, the C code is linked to run at 49 | # KERNBASE+1MB. Hence, we set up a trivial page directory that 50 | # translates virtual addresses [KERNBASE, KERNBASE+4MB) to 51 | # physical addresses [0, 4MB). This 4MB region will be 52 | # sufficient until we set up our real page table in mem_init 53 | # in lab 2. 54 | 55 | # Load the physical address of entry_pgdir into cr3. entry_pgdir 56 | # is defined in entrypgdir.c. 57 | movl $(RELOC(entry_pgdir)), %eax 58 | movl %eax, %cr3 59 | # Turn on paging. 60 | movl %cr0, %eax 61 | orl $(CR0_PE|CR0_PG|CR0_WP), %eax 62 | movl %eax, %cr0 63 | 64 | # Now paging is enabled, but we're still running at a low EIP 65 | # (why is this okay?). Jump up above KERNBASE before entering 66 | # C code. 67 | mov $relocated, %eax 68 | jmp *%eax 69 | relocated: 70 | 71 | # Clear the frame pointer register (EBP) 72 | # so that once we get into debugging C code, 73 | # stack backtraces will be terminated properly. 74 | movl $0x0,%ebp # nuke frame pointer 75 | 76 | # Set the stack pointer 77 | movl $(bootstacktop),%esp 78 | 79 | # now to C code 80 | call i386_init 81 | 82 | # Should never get here, but in case we do, just spin. 83 | spin: jmp spin 84 | 85 | 86 | .data 87 | ################################################################### 88 | # boot stack 89 | ################################################################### 90 | .p2align PGSHIFT # force page alignment 91 | .globl bootstack 92 | bootstack: 93 | .space KSTKSIZE 94 | .globl bootstacktop 95 | bootstacktop: 96 | 97 | -------------------------------------------------------------------------------- /kernel/lib/entrypgdir.c: -------------------------------------------------------------------------------- 1 | #include "mmu.h" 2 | #include "memlayout.h" 3 | 4 | pte_t entry_pgtable[NPTENTRIES]; 5 | 6 | // The entry.S page directory maps the first 4MB of physical memory 7 | // starting at virtual address KERNBASE (that is, it maps virtual 8 | // addresses [KERNBASE, KERNBASE+4MB) to physical addresses [0, 4MB)). 9 | // We choose 4MB because that's how much we can map with one page 10 | // table and it's enough to get us through early boot. We also map 11 | // virtual addresses [0, 4MB) to physical addresses [0, 4MB); this 12 | // region is critical for a few instructions in entry.S and then we 13 | // never use it again. 14 | // 15 | // Page directories (and page tables), must start on a page boundary, 16 | // hence the "__aligned__" attribute. Also, because of restrictions 17 | // related to linking and static initializers, we use "x + PTE_P" 18 | // here, rather than the more standard "x | PTE_P". Everywhere else 19 | // you should use "|" to combine flags. 20 | __attribute__((__aligned__(PGSIZE))) 21 | pde_t entry_pgdir[NPDENTRIES] = { 22 | // Map VA's [0, 4MB) to PA's [0, 4MB) 23 | [0] 24 | = ((uintptr_t)entry_pgtable - KERNBASE) + PTE_P, 25 | // Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB) 26 | [KERNBASE>>PDXSHIFT] 27 | = ((uintptr_t)entry_pgtable - KERNBASE) + PTE_P + PTE_W 28 | }; 29 | 30 | // Entry 0 of the page table maps to physical page 0, entry 1 to 31 | // physical page 1, etc. 32 | __attribute__((__aligned__(PGSIZE))) 33 | pte_t entry_pgtable[NPTENTRIES] = { 34 | 0x000000 | PTE_P | PTE_W, 35 | 0x001000 | PTE_P | PTE_W, 36 | 0x002000 | PTE_P | PTE_W, 37 | 0x003000 | PTE_P | PTE_W, 38 | 0x004000 | PTE_P | PTE_W, 39 | 0x005000 | PTE_P | PTE_W, 40 | 0x006000 | PTE_P | PTE_W, 41 | 0x007000 | PTE_P | PTE_W, 42 | 0x008000 | PTE_P | PTE_W, 43 | 0x009000 | PTE_P | PTE_W, 44 | 0x00a000 | PTE_P | PTE_W, 45 | 0x00b000 | PTE_P | PTE_W, 46 | 0x00c000 | PTE_P | PTE_W, 47 | 0x00d000 | PTE_P | PTE_W, 48 | 0x00e000 | PTE_P | PTE_W, 49 | 0x00f000 | PTE_P | PTE_W, 50 | 0x010000 | PTE_P | PTE_W, 51 | 0x011000 | PTE_P | PTE_W, 52 | 0x012000 | PTE_P | PTE_W, 53 | 0x013000 | PTE_P | PTE_W, 54 | 0x014000 | PTE_P | PTE_W, 55 | 0x015000 | PTE_P | PTE_W, 56 | 0x016000 | PTE_P | PTE_W, 57 | 0x017000 | PTE_P | PTE_W, 58 | 0x018000 | PTE_P | PTE_W, 59 | 0x019000 | PTE_P | PTE_W, 60 | 0x01a000 | PTE_P | PTE_W, 61 | 0x01b000 | PTE_P | PTE_W, 62 | 0x01c000 | PTE_P | PTE_W, 63 | 0x01d000 | PTE_P | PTE_W, 64 | 0x01e000 | PTE_P | PTE_W, 65 | 0x01f000 | PTE_P | PTE_W, 66 | 0x020000 | PTE_P | PTE_W, 67 | 0x021000 | PTE_P | PTE_W, 68 | 0x022000 | PTE_P | PTE_W, 69 | 0x023000 | PTE_P | PTE_W, 70 | 0x024000 | PTE_P | PTE_W, 71 | 0x025000 | PTE_P | PTE_W, 72 | 0x026000 | PTE_P | PTE_W, 73 | 0x027000 | PTE_P | PTE_W, 74 | 0x028000 | PTE_P | PTE_W, 75 | 0x029000 | PTE_P | PTE_W, 76 | 0x02a000 | PTE_P | PTE_W, 77 | 0x02b000 | PTE_P | PTE_W, 78 | 0x02c000 | PTE_P | PTE_W, 79 | 0x02d000 | PTE_P | PTE_W, 80 | 0x02e000 | PTE_P | PTE_W, 81 | 0x02f000 | PTE_P | PTE_W, 82 | 0x030000 | PTE_P | PTE_W, 83 | 0x031000 | PTE_P | PTE_W, 84 | 0x032000 | PTE_P | PTE_W, 85 | 0x033000 | PTE_P | PTE_W, 86 | 0x034000 | PTE_P | PTE_W, 87 | 0x035000 | PTE_P | PTE_W, 88 | 0x036000 | PTE_P | PTE_W, 89 | 0x037000 | PTE_P | PTE_W, 90 | 0x038000 | PTE_P | PTE_W, 91 | 0x039000 | PTE_P | PTE_W, 92 | 0x03a000 | PTE_P | PTE_W, 93 | 0x03b000 | PTE_P | PTE_W, 94 | 0x03c000 | PTE_P | PTE_W, 95 | 0x03d000 | PTE_P | PTE_W, 96 | 0x03e000 | PTE_P | PTE_W, 97 | 0x03f000 | PTE_P | PTE_W, 98 | 0x040000 | PTE_P | PTE_W, 99 | 0x041000 | PTE_P | PTE_W, 100 | 0x042000 | PTE_P | PTE_W, 101 | 0x043000 | PTE_P | PTE_W, 102 | 0x044000 | PTE_P | PTE_W, 103 | 0x045000 | PTE_P | PTE_W, 104 | 0x046000 | PTE_P | PTE_W, 105 | 0x047000 | PTE_P | PTE_W, 106 | 0x048000 | PTE_P | PTE_W, 107 | 0x049000 | PTE_P | PTE_W, 108 | 0x04a000 | PTE_P | PTE_W, 109 | 0x04b000 | PTE_P | PTE_W, 110 | 0x04c000 | PTE_P | PTE_W, 111 | 0x04d000 | PTE_P | PTE_W, 112 | 0x04e000 | PTE_P | PTE_W, 113 | 0x04f000 | PTE_P | PTE_W, 114 | 0x050000 | PTE_P | PTE_W, 115 | 0x051000 | PTE_P | PTE_W, 116 | 0x052000 | PTE_P | PTE_W, 117 | 0x053000 | PTE_P | PTE_W, 118 | 0x054000 | PTE_P | PTE_W, 119 | 0x055000 | PTE_P | PTE_W, 120 | 0x056000 | PTE_P | PTE_W, 121 | 0x057000 | PTE_P | PTE_W, 122 | 0x058000 | PTE_P | PTE_W, 123 | 0x059000 | PTE_P | PTE_W, 124 | 0x05a000 | PTE_P | PTE_W, 125 | 0x05b000 | PTE_P | PTE_W, 126 | 0x05c000 | PTE_P | PTE_W, 127 | 0x05d000 | PTE_P | PTE_W, 128 | 0x05e000 | PTE_P | PTE_W, 129 | 0x05f000 | PTE_P | PTE_W, 130 | 0x060000 | PTE_P | PTE_W, 131 | 0x061000 | PTE_P | PTE_W, 132 | 0x062000 | PTE_P | PTE_W, 133 | 0x063000 | PTE_P | PTE_W, 134 | 0x064000 | PTE_P | PTE_W, 135 | 0x065000 | PTE_P | PTE_W, 136 | 0x066000 | PTE_P | PTE_W, 137 | 0x067000 | PTE_P | PTE_W, 138 | 0x068000 | PTE_P | PTE_W, 139 | 0x069000 | PTE_P | PTE_W, 140 | 0x06a000 | PTE_P | PTE_W, 141 | 0x06b000 | PTE_P | PTE_W, 142 | 0x06c000 | PTE_P | PTE_W, 143 | 0x06d000 | PTE_P | PTE_W, 144 | 0x06e000 | PTE_P | PTE_W, 145 | 0x06f000 | PTE_P | PTE_W, 146 | 0x070000 | PTE_P | PTE_W, 147 | 0x071000 | PTE_P | PTE_W, 148 | 0x072000 | PTE_P | PTE_W, 149 | 0x073000 | PTE_P | PTE_W, 150 | 0x074000 | PTE_P | PTE_W, 151 | 0x075000 | PTE_P | PTE_W, 152 | 0x076000 | PTE_P | PTE_W, 153 | 0x077000 | PTE_P | PTE_W, 154 | 0x078000 | PTE_P | PTE_W, 155 | 0x079000 | PTE_P | PTE_W, 156 | 0x07a000 | PTE_P | PTE_W, 157 | 0x07b000 | PTE_P | PTE_W, 158 | 0x07c000 | PTE_P | PTE_W, 159 | 0x07d000 | PTE_P | PTE_W, 160 | 0x07e000 | PTE_P | PTE_W, 161 | 0x07f000 | PTE_P | PTE_W, 162 | 0x080000 | PTE_P | PTE_W, 163 | 0x081000 | PTE_P | PTE_W, 164 | 0x082000 | PTE_P | PTE_W, 165 | 0x083000 | PTE_P | PTE_W, 166 | 0x084000 | PTE_P | PTE_W, 167 | 0x085000 | PTE_P | PTE_W, 168 | 0x086000 | PTE_P | PTE_W, 169 | 0x087000 | PTE_P | PTE_W, 170 | 0x088000 | PTE_P | PTE_W, 171 | 0x089000 | PTE_P | PTE_W, 172 | 0x08a000 | PTE_P | PTE_W, 173 | 0x08b000 | PTE_P | PTE_W, 174 | 0x08c000 | PTE_P | PTE_W, 175 | 0x08d000 | PTE_P | PTE_W, 176 | 0x08e000 | PTE_P | PTE_W, 177 | 0x08f000 | PTE_P | PTE_W, 178 | 0x090000 | PTE_P | PTE_W, 179 | 0x091000 | PTE_P | PTE_W, 180 | 0x092000 | PTE_P | PTE_W, 181 | 0x093000 | PTE_P | PTE_W, 182 | 0x094000 | PTE_P | PTE_W, 183 | 0x095000 | PTE_P | PTE_W, 184 | 0x096000 | PTE_P | PTE_W, 185 | 0x097000 | PTE_P | PTE_W, 186 | 0x098000 | PTE_P | PTE_W, 187 | 0x099000 | PTE_P | PTE_W, 188 | 0x09a000 | PTE_P | PTE_W, 189 | 0x09b000 | PTE_P | PTE_W, 190 | 0x09c000 | PTE_P | PTE_W, 191 | 0x09d000 | PTE_P | PTE_W, 192 | 0x09e000 | PTE_P | PTE_W, 193 | 0x09f000 | PTE_P | PTE_W, 194 | 0x0a0000 | PTE_P | PTE_W, 195 | 0x0a1000 | PTE_P | PTE_W, 196 | 0x0a2000 | PTE_P | PTE_W, 197 | 0x0a3000 | PTE_P | PTE_W, 198 | 0x0a4000 | PTE_P | PTE_W, 199 | 0x0a5000 | PTE_P | PTE_W, 200 | 0x0a6000 | PTE_P | PTE_W, 201 | 0x0a7000 | PTE_P | PTE_W, 202 | 0x0a8000 | PTE_P | PTE_W, 203 | 0x0a9000 | PTE_P | PTE_W, 204 | 0x0aa000 | PTE_P | PTE_W, 205 | 0x0ab000 | PTE_P | PTE_W, 206 | 0x0ac000 | PTE_P | PTE_W, 207 | 0x0ad000 | PTE_P | PTE_W, 208 | 0x0ae000 | PTE_P | PTE_W, 209 | 0x0af000 | PTE_P | PTE_W, 210 | 0x0b0000 | PTE_P | PTE_W, 211 | 0x0b1000 | PTE_P | PTE_W, 212 | 0x0b2000 | PTE_P | PTE_W, 213 | 0x0b3000 | PTE_P | PTE_W, 214 | 0x0b4000 | PTE_P | PTE_W, 215 | 0x0b5000 | PTE_P | PTE_W, 216 | 0x0b6000 | PTE_P | PTE_W, 217 | 0x0b7000 | PTE_P | PTE_W, 218 | 0x0b8000 | PTE_P | PTE_W, 219 | 0x0b9000 | PTE_P | PTE_W, 220 | 0x0ba000 | PTE_P | PTE_W, 221 | 0x0bb000 | PTE_P | PTE_W, 222 | 0x0bc000 | PTE_P | PTE_W, 223 | 0x0bd000 | PTE_P | PTE_W, 224 | 0x0be000 | PTE_P | PTE_W, 225 | 0x0bf000 | PTE_P | PTE_W, 226 | 0x0c0000 | PTE_P | PTE_W, 227 | 0x0c1000 | PTE_P | PTE_W, 228 | 0x0c2000 | PTE_P | PTE_W, 229 | 0x0c3000 | PTE_P | PTE_W, 230 | 0x0c4000 | PTE_P | PTE_W, 231 | 0x0c5000 | PTE_P | PTE_W, 232 | 0x0c6000 | PTE_P | PTE_W, 233 | 0x0c7000 | PTE_P | PTE_W, 234 | 0x0c8000 | PTE_P | PTE_W, 235 | 0x0c9000 | PTE_P | PTE_W, 236 | 0x0ca000 | PTE_P | PTE_W, 237 | 0x0cb000 | PTE_P | PTE_W, 238 | 0x0cc000 | PTE_P | PTE_W, 239 | 0x0cd000 | PTE_P | PTE_W, 240 | 0x0ce000 | PTE_P | PTE_W, 241 | 0x0cf000 | PTE_P | PTE_W, 242 | 0x0d0000 | PTE_P | PTE_W, 243 | 0x0d1000 | PTE_P | PTE_W, 244 | 0x0d2000 | PTE_P | PTE_W, 245 | 0x0d3000 | PTE_P | PTE_W, 246 | 0x0d4000 | PTE_P | PTE_W, 247 | 0x0d5000 | PTE_P | PTE_W, 248 | 0x0d6000 | PTE_P | PTE_W, 249 | 0x0d7000 | PTE_P | PTE_W, 250 | 0x0d8000 | PTE_P | PTE_W, 251 | 0x0d9000 | PTE_P | PTE_W, 252 | 0x0da000 | PTE_P | PTE_W, 253 | 0x0db000 | PTE_P | PTE_W, 254 | 0x0dc000 | PTE_P | PTE_W, 255 | 0x0dd000 | PTE_P | PTE_W, 256 | 0x0de000 | PTE_P | PTE_W, 257 | 0x0df000 | PTE_P | PTE_W, 258 | 0x0e0000 | PTE_P | PTE_W, 259 | 0x0e1000 | PTE_P | PTE_W, 260 | 0x0e2000 | PTE_P | PTE_W, 261 | 0x0e3000 | PTE_P | PTE_W, 262 | 0x0e4000 | PTE_P | PTE_W, 263 | 0x0e5000 | PTE_P | PTE_W, 264 | 0x0e6000 | PTE_P | PTE_W, 265 | 0x0e7000 | PTE_P | PTE_W, 266 | 0x0e8000 | PTE_P | PTE_W, 267 | 0x0e9000 | PTE_P | PTE_W, 268 | 0x0ea000 | PTE_P | PTE_W, 269 | 0x0eb000 | PTE_P | PTE_W, 270 | 0x0ec000 | PTE_P | PTE_W, 271 | 0x0ed000 | PTE_P | PTE_W, 272 | 0x0ee000 | PTE_P | PTE_W, 273 | 0x0ef000 | PTE_P | PTE_W, 274 | 0x0f0000 | PTE_P | PTE_W, 275 | 0x0f1000 | PTE_P | PTE_W, 276 | 0x0f2000 | PTE_P | PTE_W, 277 | 0x0f3000 | PTE_P | PTE_W, 278 | 0x0f4000 | PTE_P | PTE_W, 279 | 0x0f5000 | PTE_P | PTE_W, 280 | 0x0f6000 | PTE_P | PTE_W, 281 | 0x0f7000 | PTE_P | PTE_W, 282 | 0x0f8000 | PTE_P | PTE_W, 283 | 0x0f9000 | PTE_P | PTE_W, 284 | 0x0fa000 | PTE_P | PTE_W, 285 | 0x0fb000 | PTE_P | PTE_W, 286 | 0x0fc000 | PTE_P | PTE_W, 287 | 0x0fd000 | PTE_P | PTE_W, 288 | 0x0fe000 | PTE_P | PTE_W, 289 | 0x0ff000 | PTE_P | PTE_W, 290 | 0x100000 | PTE_P | PTE_W, 291 | 0x101000 | PTE_P | PTE_W, 292 | 0x102000 | PTE_P | PTE_W, 293 | 0x103000 | PTE_P | PTE_W, 294 | 0x104000 | PTE_P | PTE_W, 295 | 0x105000 | PTE_P | PTE_W, 296 | 0x106000 | PTE_P | PTE_W, 297 | 0x107000 | PTE_P | PTE_W, 298 | 0x108000 | PTE_P | PTE_W, 299 | 0x109000 | PTE_P | PTE_W, 300 | 0x10a000 | PTE_P | PTE_W, 301 | 0x10b000 | PTE_P | PTE_W, 302 | 0x10c000 | PTE_P | PTE_W, 303 | 0x10d000 | PTE_P | PTE_W, 304 | 0x10e000 | PTE_P | PTE_W, 305 | 0x10f000 | PTE_P | PTE_W, 306 | 0x110000 | PTE_P | PTE_W, 307 | 0x111000 | PTE_P | PTE_W, 308 | 0x112000 | PTE_P | PTE_W, 309 | 0x113000 | PTE_P | PTE_W, 310 | 0x114000 | PTE_P | PTE_W, 311 | 0x115000 | PTE_P | PTE_W, 312 | 0x116000 | PTE_P | PTE_W, 313 | 0x117000 | PTE_P | PTE_W, 314 | 0x118000 | PTE_P | PTE_W, 315 | 0x119000 | PTE_P | PTE_W, 316 | 0x11a000 | PTE_P | PTE_W, 317 | 0x11b000 | PTE_P | PTE_W, 318 | 0x11c000 | PTE_P | PTE_W, 319 | 0x11d000 | PTE_P | PTE_W, 320 | 0x11e000 | PTE_P | PTE_W, 321 | 0x11f000 | PTE_P | PTE_W, 322 | 0x120000 | PTE_P | PTE_W, 323 | 0x121000 | PTE_P | PTE_W, 324 | 0x122000 | PTE_P | PTE_W, 325 | 0x123000 | PTE_P | PTE_W, 326 | 0x124000 | PTE_P | PTE_W, 327 | 0x125000 | PTE_P | PTE_W, 328 | 0x126000 | PTE_P | PTE_W, 329 | 0x127000 | PTE_P | PTE_W, 330 | 0x128000 | PTE_P | PTE_W, 331 | 0x129000 | PTE_P | PTE_W, 332 | 0x12a000 | PTE_P | PTE_W, 333 | 0x12b000 | PTE_P | PTE_W, 334 | 0x12c000 | PTE_P | PTE_W, 335 | 0x12d000 | PTE_P | PTE_W, 336 | 0x12e000 | PTE_P | PTE_W, 337 | 0x12f000 | PTE_P | PTE_W, 338 | 0x130000 | PTE_P | PTE_W, 339 | 0x131000 | PTE_P | PTE_W, 340 | 0x132000 | PTE_P | PTE_W, 341 | 0x133000 | PTE_P | PTE_W, 342 | 0x134000 | PTE_P | PTE_W, 343 | 0x135000 | PTE_P | PTE_W, 344 | 0x136000 | PTE_P | PTE_W, 345 | 0x137000 | PTE_P | PTE_W, 346 | 0x138000 | PTE_P | PTE_W, 347 | 0x139000 | PTE_P | PTE_W, 348 | 0x13a000 | PTE_P | PTE_W, 349 | 0x13b000 | PTE_P | PTE_W, 350 | 0x13c000 | PTE_P | PTE_W, 351 | 0x13d000 | PTE_P | PTE_W, 352 | 0x13e000 | PTE_P | PTE_W, 353 | 0x13f000 | PTE_P | PTE_W, 354 | 0x140000 | PTE_P | PTE_W, 355 | 0x141000 | PTE_P | PTE_W, 356 | 0x142000 | PTE_P | PTE_W, 357 | 0x143000 | PTE_P | PTE_W, 358 | 0x144000 | PTE_P | PTE_W, 359 | 0x145000 | PTE_P | PTE_W, 360 | 0x146000 | PTE_P | PTE_W, 361 | 0x147000 | PTE_P | PTE_W, 362 | 0x148000 | PTE_P | PTE_W, 363 | 0x149000 | PTE_P | PTE_W, 364 | 0x14a000 | PTE_P | PTE_W, 365 | 0x14b000 | PTE_P | PTE_W, 366 | 0x14c000 | PTE_P | PTE_W, 367 | 0x14d000 | PTE_P | PTE_W, 368 | 0x14e000 | PTE_P | PTE_W, 369 | 0x14f000 | PTE_P | PTE_W, 370 | 0x150000 | PTE_P | PTE_W, 371 | 0x151000 | PTE_P | PTE_W, 372 | 0x152000 | PTE_P | PTE_W, 373 | 0x153000 | PTE_P | PTE_W, 374 | 0x154000 | PTE_P | PTE_W, 375 | 0x155000 | PTE_P | PTE_W, 376 | 0x156000 | PTE_P | PTE_W, 377 | 0x157000 | PTE_P | PTE_W, 378 | 0x158000 | PTE_P | PTE_W, 379 | 0x159000 | PTE_P | PTE_W, 380 | 0x15a000 | PTE_P | PTE_W, 381 | 0x15b000 | PTE_P | PTE_W, 382 | 0x15c000 | PTE_P | PTE_W, 383 | 0x15d000 | PTE_P | PTE_W, 384 | 0x15e000 | PTE_P | PTE_W, 385 | 0x15f000 | PTE_P | PTE_W, 386 | 0x160000 | PTE_P | PTE_W, 387 | 0x161000 | PTE_P | PTE_W, 388 | 0x162000 | PTE_P | PTE_W, 389 | 0x163000 | PTE_P | PTE_W, 390 | 0x164000 | PTE_P | PTE_W, 391 | 0x165000 | PTE_P | PTE_W, 392 | 0x166000 | PTE_P | PTE_W, 393 | 0x167000 | PTE_P | PTE_W, 394 | 0x168000 | PTE_P | PTE_W, 395 | 0x169000 | PTE_P | PTE_W, 396 | 0x16a000 | PTE_P | PTE_W, 397 | 0x16b000 | PTE_P | PTE_W, 398 | 0x16c000 | PTE_P | PTE_W, 399 | 0x16d000 | PTE_P | PTE_W, 400 | 0x16e000 | PTE_P | PTE_W, 401 | 0x16f000 | PTE_P | PTE_W, 402 | 0x170000 | PTE_P | PTE_W, 403 | 0x171000 | PTE_P | PTE_W, 404 | 0x172000 | PTE_P | PTE_W, 405 | 0x173000 | PTE_P | PTE_W, 406 | 0x174000 | PTE_P | PTE_W, 407 | 0x175000 | PTE_P | PTE_W, 408 | 0x176000 | PTE_P | PTE_W, 409 | 0x177000 | PTE_P | PTE_W, 410 | 0x178000 | PTE_P | PTE_W, 411 | 0x179000 | PTE_P | PTE_W, 412 | 0x17a000 | PTE_P | PTE_W, 413 | 0x17b000 | PTE_P | PTE_W, 414 | 0x17c000 | PTE_P | PTE_W, 415 | 0x17d000 | PTE_P | PTE_W, 416 | 0x17e000 | PTE_P | PTE_W, 417 | 0x17f000 | PTE_P | PTE_W, 418 | 0x180000 | PTE_P | PTE_W, 419 | 0x181000 | PTE_P | PTE_W, 420 | 0x182000 | PTE_P | PTE_W, 421 | 0x183000 | PTE_P | PTE_W, 422 | 0x184000 | PTE_P | PTE_W, 423 | 0x185000 | PTE_P | PTE_W, 424 | 0x186000 | PTE_P | PTE_W, 425 | 0x187000 | PTE_P | PTE_W, 426 | 0x188000 | PTE_P | PTE_W, 427 | 0x189000 | PTE_P | PTE_W, 428 | 0x18a000 | PTE_P | PTE_W, 429 | 0x18b000 | PTE_P | PTE_W, 430 | 0x18c000 | PTE_P | PTE_W, 431 | 0x18d000 | PTE_P | PTE_W, 432 | 0x18e000 | PTE_P | PTE_W, 433 | 0x18f000 | PTE_P | PTE_W, 434 | 0x190000 | PTE_P | PTE_W, 435 | 0x191000 | PTE_P | PTE_W, 436 | 0x192000 | PTE_P | PTE_W, 437 | 0x193000 | PTE_P | PTE_W, 438 | 0x194000 | PTE_P | PTE_W, 439 | 0x195000 | PTE_P | PTE_W, 440 | 0x196000 | PTE_P | PTE_W, 441 | 0x197000 | PTE_P | PTE_W, 442 | 0x198000 | PTE_P | PTE_W, 443 | 0x199000 | PTE_P | PTE_W, 444 | 0x19a000 | PTE_P | PTE_W, 445 | 0x19b000 | PTE_P | PTE_W, 446 | 0x19c000 | PTE_P | PTE_W, 447 | 0x19d000 | PTE_P | PTE_W, 448 | 0x19e000 | PTE_P | PTE_W, 449 | 0x19f000 | PTE_P | PTE_W, 450 | 0x1a0000 | PTE_P | PTE_W, 451 | 0x1a1000 | PTE_P | PTE_W, 452 | 0x1a2000 | PTE_P | PTE_W, 453 | 0x1a3000 | PTE_P | PTE_W, 454 | 0x1a4000 | PTE_P | PTE_W, 455 | 0x1a5000 | PTE_P | PTE_W, 456 | 0x1a6000 | PTE_P | PTE_W, 457 | 0x1a7000 | PTE_P | PTE_W, 458 | 0x1a8000 | PTE_P | PTE_W, 459 | 0x1a9000 | PTE_P | PTE_W, 460 | 0x1aa000 | PTE_P | PTE_W, 461 | 0x1ab000 | PTE_P | PTE_W, 462 | 0x1ac000 | PTE_P | PTE_W, 463 | 0x1ad000 | PTE_P | PTE_W, 464 | 0x1ae000 | PTE_P | PTE_W, 465 | 0x1af000 | PTE_P | PTE_W, 466 | 0x1b0000 | PTE_P | PTE_W, 467 | 0x1b1000 | PTE_P | PTE_W, 468 | 0x1b2000 | PTE_P | PTE_W, 469 | 0x1b3000 | PTE_P | PTE_W, 470 | 0x1b4000 | PTE_P | PTE_W, 471 | 0x1b5000 | PTE_P | PTE_W, 472 | 0x1b6000 | PTE_P | PTE_W, 473 | 0x1b7000 | PTE_P | PTE_W, 474 | 0x1b8000 | PTE_P | PTE_W, 475 | 0x1b9000 | PTE_P | PTE_W, 476 | 0x1ba000 | PTE_P | PTE_W, 477 | 0x1bb000 | PTE_P | PTE_W, 478 | 0x1bc000 | PTE_P | PTE_W, 479 | 0x1bd000 | PTE_P | PTE_W, 480 | 0x1be000 | PTE_P | PTE_W, 481 | 0x1bf000 | PTE_P | PTE_W, 482 | 0x1c0000 | PTE_P | PTE_W, 483 | 0x1c1000 | PTE_P | PTE_W, 484 | 0x1c2000 | PTE_P | PTE_W, 485 | 0x1c3000 | PTE_P | PTE_W, 486 | 0x1c4000 | PTE_P | PTE_W, 487 | 0x1c5000 | PTE_P | PTE_W, 488 | 0x1c6000 | PTE_P | PTE_W, 489 | 0x1c7000 | PTE_P | PTE_W, 490 | 0x1c8000 | PTE_P | PTE_W, 491 | 0x1c9000 | PTE_P | PTE_W, 492 | 0x1ca000 | PTE_P | PTE_W, 493 | 0x1cb000 | PTE_P | PTE_W, 494 | 0x1cc000 | PTE_P | PTE_W, 495 | 0x1cd000 | PTE_P | PTE_W, 496 | 0x1ce000 | PTE_P | PTE_W, 497 | 0x1cf000 | PTE_P | PTE_W, 498 | 0x1d0000 | PTE_P | PTE_W, 499 | 0x1d1000 | PTE_P | PTE_W, 500 | 0x1d2000 | PTE_P | PTE_W, 501 | 0x1d3000 | PTE_P | PTE_W, 502 | 0x1d4000 | PTE_P | PTE_W, 503 | 0x1d5000 | PTE_P | PTE_W, 504 | 0x1d6000 | PTE_P | PTE_W, 505 | 0x1d7000 | PTE_P | PTE_W, 506 | 0x1d8000 | PTE_P | PTE_W, 507 | 0x1d9000 | PTE_P | PTE_W, 508 | 0x1da000 | PTE_P | PTE_W, 509 | 0x1db000 | PTE_P | PTE_W, 510 | 0x1dc000 | PTE_P | PTE_W, 511 | 0x1dd000 | PTE_P | PTE_W, 512 | 0x1de000 | PTE_P | PTE_W, 513 | 0x1df000 | PTE_P | PTE_W, 514 | 0x1e0000 | PTE_P | PTE_W, 515 | 0x1e1000 | PTE_P | PTE_W, 516 | 0x1e2000 | PTE_P | PTE_W, 517 | 0x1e3000 | PTE_P | PTE_W, 518 | 0x1e4000 | PTE_P | PTE_W, 519 | 0x1e5000 | PTE_P | PTE_W, 520 | 0x1e6000 | PTE_P | PTE_W, 521 | 0x1e7000 | PTE_P | PTE_W, 522 | 0x1e8000 | PTE_P | PTE_W, 523 | 0x1e9000 | PTE_P | PTE_W, 524 | 0x1ea000 | PTE_P | PTE_W, 525 | 0x1eb000 | PTE_P | PTE_W, 526 | 0x1ec000 | PTE_P | PTE_W, 527 | 0x1ed000 | PTE_P | PTE_W, 528 | 0x1ee000 | PTE_P | PTE_W, 529 | 0x1ef000 | PTE_P | PTE_W, 530 | 0x1f0000 | PTE_P | PTE_W, 531 | 0x1f1000 | PTE_P | PTE_W, 532 | 0x1f2000 | PTE_P | PTE_W, 533 | 0x1f3000 | PTE_P | PTE_W, 534 | 0x1f4000 | PTE_P | PTE_W, 535 | 0x1f5000 | PTE_P | PTE_W, 536 | 0x1f6000 | PTE_P | PTE_W, 537 | 0x1f7000 | PTE_P | PTE_W, 538 | 0x1f8000 | PTE_P | PTE_W, 539 | 0x1f9000 | PTE_P | PTE_W, 540 | 0x1fa000 | PTE_P | PTE_W, 541 | 0x1fb000 | PTE_P | PTE_W, 542 | 0x1fc000 | PTE_P | PTE_W, 543 | 0x1fd000 | PTE_P | PTE_W, 544 | 0x1fe000 | PTE_P | PTE_W, 545 | 0x1ff000 | PTE_P | PTE_W, 546 | 0x200000 | PTE_P | PTE_W, 547 | 0x201000 | PTE_P | PTE_W, 548 | 0x202000 | PTE_P | PTE_W, 549 | 0x203000 | PTE_P | PTE_W, 550 | 0x204000 | PTE_P | PTE_W, 551 | 0x205000 | PTE_P | PTE_W, 552 | 0x206000 | PTE_P | PTE_W, 553 | 0x207000 | PTE_P | PTE_W, 554 | 0x208000 | PTE_P | PTE_W, 555 | 0x209000 | PTE_P | PTE_W, 556 | 0x20a000 | PTE_P | PTE_W, 557 | 0x20b000 | PTE_P | PTE_W, 558 | 0x20c000 | PTE_P | PTE_W, 559 | 0x20d000 | PTE_P | PTE_W, 560 | 0x20e000 | PTE_P | PTE_W, 561 | 0x20f000 | PTE_P | PTE_W, 562 | 0x210000 | PTE_P | PTE_W, 563 | 0x211000 | PTE_P | PTE_W, 564 | 0x212000 | PTE_P | PTE_W, 565 | 0x213000 | PTE_P | PTE_W, 566 | 0x214000 | PTE_P | PTE_W, 567 | 0x215000 | PTE_P | PTE_W, 568 | 0x216000 | PTE_P | PTE_W, 569 | 0x217000 | PTE_P | PTE_W, 570 | 0x218000 | PTE_P | PTE_W, 571 | 0x219000 | PTE_P | PTE_W, 572 | 0x21a000 | PTE_P | PTE_W, 573 | 0x21b000 | PTE_P | PTE_W, 574 | 0x21c000 | PTE_P | PTE_W, 575 | 0x21d000 | PTE_P | PTE_W, 576 | 0x21e000 | PTE_P | PTE_W, 577 | 0x21f000 | PTE_P | PTE_W, 578 | 0x220000 | PTE_P | PTE_W, 579 | 0x221000 | PTE_P | PTE_W, 580 | 0x222000 | PTE_P | PTE_W, 581 | 0x223000 | PTE_P | PTE_W, 582 | 0x224000 | PTE_P | PTE_W, 583 | 0x225000 | PTE_P | PTE_W, 584 | 0x226000 | PTE_P | PTE_W, 585 | 0x227000 | PTE_P | PTE_W, 586 | 0x228000 | PTE_P | PTE_W, 587 | 0x229000 | PTE_P | PTE_W, 588 | 0x22a000 | PTE_P | PTE_W, 589 | 0x22b000 | PTE_P | PTE_W, 590 | 0x22c000 | PTE_P | PTE_W, 591 | 0x22d000 | PTE_P | PTE_W, 592 | 0x22e000 | PTE_P | PTE_W, 593 | 0x22f000 | PTE_P | PTE_W, 594 | 0x230000 | PTE_P | PTE_W, 595 | 0x231000 | PTE_P | PTE_W, 596 | 0x232000 | PTE_P | PTE_W, 597 | 0x233000 | PTE_P | PTE_W, 598 | 0x234000 | PTE_P | PTE_W, 599 | 0x235000 | PTE_P | PTE_W, 600 | 0x236000 | PTE_P | PTE_W, 601 | 0x237000 | PTE_P | PTE_W, 602 | 0x238000 | PTE_P | PTE_W, 603 | 0x239000 | PTE_P | PTE_W, 604 | 0x23a000 | PTE_P | PTE_W, 605 | 0x23b000 | PTE_P | PTE_W, 606 | 0x23c000 | PTE_P | PTE_W, 607 | 0x23d000 | PTE_P | PTE_W, 608 | 0x23e000 | PTE_P | PTE_W, 609 | 0x23f000 | PTE_P | PTE_W, 610 | 0x240000 | PTE_P | PTE_W, 611 | 0x241000 | PTE_P | PTE_W, 612 | 0x242000 | PTE_P | PTE_W, 613 | 0x243000 | PTE_P | PTE_W, 614 | 0x244000 | PTE_P | PTE_W, 615 | 0x245000 | PTE_P | PTE_W, 616 | 0x246000 | PTE_P | PTE_W, 617 | 0x247000 | PTE_P | PTE_W, 618 | 0x248000 | PTE_P | PTE_W, 619 | 0x249000 | PTE_P | PTE_W, 620 | 0x24a000 | PTE_P | PTE_W, 621 | 0x24b000 | PTE_P | PTE_W, 622 | 0x24c000 | PTE_P | PTE_W, 623 | 0x24d000 | PTE_P | PTE_W, 624 | 0x24e000 | PTE_P | PTE_W, 625 | 0x24f000 | PTE_P | PTE_W, 626 | 0x250000 | PTE_P | PTE_W, 627 | 0x251000 | PTE_P | PTE_W, 628 | 0x252000 | PTE_P | PTE_W, 629 | 0x253000 | PTE_P | PTE_W, 630 | 0x254000 | PTE_P | PTE_W, 631 | 0x255000 | PTE_P | PTE_W, 632 | 0x256000 | PTE_P | PTE_W, 633 | 0x257000 | PTE_P | PTE_W, 634 | 0x258000 | PTE_P | PTE_W, 635 | 0x259000 | PTE_P | PTE_W, 636 | 0x25a000 | PTE_P | PTE_W, 637 | 0x25b000 | PTE_P | PTE_W, 638 | 0x25c000 | PTE_P | PTE_W, 639 | 0x25d000 | PTE_P | PTE_W, 640 | 0x25e000 | PTE_P | PTE_W, 641 | 0x25f000 | PTE_P | PTE_W, 642 | 0x260000 | PTE_P | PTE_W, 643 | 0x261000 | PTE_P | PTE_W, 644 | 0x262000 | PTE_P | PTE_W, 645 | 0x263000 | PTE_P | PTE_W, 646 | 0x264000 | PTE_P | PTE_W, 647 | 0x265000 | PTE_P | PTE_W, 648 | 0x266000 | PTE_P | PTE_W, 649 | 0x267000 | PTE_P | PTE_W, 650 | 0x268000 | PTE_P | PTE_W, 651 | 0x269000 | PTE_P | PTE_W, 652 | 0x26a000 | PTE_P | PTE_W, 653 | 0x26b000 | PTE_P | PTE_W, 654 | 0x26c000 | PTE_P | PTE_W, 655 | 0x26d000 | PTE_P | PTE_W, 656 | 0x26e000 | PTE_P | PTE_W, 657 | 0x26f000 | PTE_P | PTE_W, 658 | 0x270000 | PTE_P | PTE_W, 659 | 0x271000 | PTE_P | PTE_W, 660 | 0x272000 | PTE_P | PTE_W, 661 | 0x273000 | PTE_P | PTE_W, 662 | 0x274000 | PTE_P | PTE_W, 663 | 0x275000 | PTE_P | PTE_W, 664 | 0x276000 | PTE_P | PTE_W, 665 | 0x277000 | PTE_P | PTE_W, 666 | 0x278000 | PTE_P | PTE_W, 667 | 0x279000 | PTE_P | PTE_W, 668 | 0x27a000 | PTE_P | PTE_W, 669 | 0x27b000 | PTE_P | PTE_W, 670 | 0x27c000 | PTE_P | PTE_W, 671 | 0x27d000 | PTE_P | PTE_W, 672 | 0x27e000 | PTE_P | PTE_W, 673 | 0x27f000 | PTE_P | PTE_W, 674 | 0x280000 | PTE_P | PTE_W, 675 | 0x281000 | PTE_P | PTE_W, 676 | 0x282000 | PTE_P | PTE_W, 677 | 0x283000 | PTE_P | PTE_W, 678 | 0x284000 | PTE_P | PTE_W, 679 | 0x285000 | PTE_P | PTE_W, 680 | 0x286000 | PTE_P | PTE_W, 681 | 0x287000 | PTE_P | PTE_W, 682 | 0x288000 | PTE_P | PTE_W, 683 | 0x289000 | PTE_P | PTE_W, 684 | 0x28a000 | PTE_P | PTE_W, 685 | 0x28b000 | PTE_P | PTE_W, 686 | 0x28c000 | PTE_P | PTE_W, 687 | 0x28d000 | PTE_P | PTE_W, 688 | 0x28e000 | PTE_P | PTE_W, 689 | 0x28f000 | PTE_P | PTE_W, 690 | 0x290000 | PTE_P | PTE_W, 691 | 0x291000 | PTE_P | PTE_W, 692 | 0x292000 | PTE_P | PTE_W, 693 | 0x293000 | PTE_P | PTE_W, 694 | 0x294000 | PTE_P | PTE_W, 695 | 0x295000 | PTE_P | PTE_W, 696 | 0x296000 | PTE_P | PTE_W, 697 | 0x297000 | PTE_P | PTE_W, 698 | 0x298000 | PTE_P | PTE_W, 699 | 0x299000 | PTE_P | PTE_W, 700 | 0x29a000 | PTE_P | PTE_W, 701 | 0x29b000 | PTE_P | PTE_W, 702 | 0x29c000 | PTE_P | PTE_W, 703 | 0x29d000 | PTE_P | PTE_W, 704 | 0x29e000 | PTE_P | PTE_W, 705 | 0x29f000 | PTE_P | PTE_W, 706 | 0x2a0000 | PTE_P | PTE_W, 707 | 0x2a1000 | PTE_P | PTE_W, 708 | 0x2a2000 | PTE_P | PTE_W, 709 | 0x2a3000 | PTE_P | PTE_W, 710 | 0x2a4000 | PTE_P | PTE_W, 711 | 0x2a5000 | PTE_P | PTE_W, 712 | 0x2a6000 | PTE_P | PTE_W, 713 | 0x2a7000 | PTE_P | PTE_W, 714 | 0x2a8000 | PTE_P | PTE_W, 715 | 0x2a9000 | PTE_P | PTE_W, 716 | 0x2aa000 | PTE_P | PTE_W, 717 | 0x2ab000 | PTE_P | PTE_W, 718 | 0x2ac000 | PTE_P | PTE_W, 719 | 0x2ad000 | PTE_P | PTE_W, 720 | 0x2ae000 | PTE_P | PTE_W, 721 | 0x2af000 | PTE_P | PTE_W, 722 | 0x2b0000 | PTE_P | PTE_W, 723 | 0x2b1000 | PTE_P | PTE_W, 724 | 0x2b2000 | PTE_P | PTE_W, 725 | 0x2b3000 | PTE_P | PTE_W, 726 | 0x2b4000 | PTE_P | PTE_W, 727 | 0x2b5000 | PTE_P | PTE_W, 728 | 0x2b6000 | PTE_P | PTE_W, 729 | 0x2b7000 | PTE_P | PTE_W, 730 | 0x2b8000 | PTE_P | PTE_W, 731 | 0x2b9000 | PTE_P | PTE_W, 732 | 0x2ba000 | PTE_P | PTE_W, 733 | 0x2bb000 | PTE_P | PTE_W, 734 | 0x2bc000 | PTE_P | PTE_W, 735 | 0x2bd000 | PTE_P | PTE_W, 736 | 0x2be000 | PTE_P | PTE_W, 737 | 0x2bf000 | PTE_P | PTE_W, 738 | 0x2c0000 | PTE_P | PTE_W, 739 | 0x2c1000 | PTE_P | PTE_W, 740 | 0x2c2000 | PTE_P | PTE_W, 741 | 0x2c3000 | PTE_P | PTE_W, 742 | 0x2c4000 | PTE_P | PTE_W, 743 | 0x2c5000 | PTE_P | PTE_W, 744 | 0x2c6000 | PTE_P | PTE_W, 745 | 0x2c7000 | PTE_P | PTE_W, 746 | 0x2c8000 | PTE_P | PTE_W, 747 | 0x2c9000 | PTE_P | PTE_W, 748 | 0x2ca000 | PTE_P | PTE_W, 749 | 0x2cb000 | PTE_P | PTE_W, 750 | 0x2cc000 | PTE_P | PTE_W, 751 | 0x2cd000 | PTE_P | PTE_W, 752 | 0x2ce000 | PTE_P | PTE_W, 753 | 0x2cf000 | PTE_P | PTE_W, 754 | 0x2d0000 | PTE_P | PTE_W, 755 | 0x2d1000 | PTE_P | PTE_W, 756 | 0x2d2000 | PTE_P | PTE_W, 757 | 0x2d3000 | PTE_P | PTE_W, 758 | 0x2d4000 | PTE_P | PTE_W, 759 | 0x2d5000 | PTE_P | PTE_W, 760 | 0x2d6000 | PTE_P | PTE_W, 761 | 0x2d7000 | PTE_P | PTE_W, 762 | 0x2d8000 | PTE_P | PTE_W, 763 | 0x2d9000 | PTE_P | PTE_W, 764 | 0x2da000 | PTE_P | PTE_W, 765 | 0x2db000 | PTE_P | PTE_W, 766 | 0x2dc000 | PTE_P | PTE_W, 767 | 0x2dd000 | PTE_P | PTE_W, 768 | 0x2de000 | PTE_P | PTE_W, 769 | 0x2df000 | PTE_P | PTE_W, 770 | 0x2e0000 | PTE_P | PTE_W, 771 | 0x2e1000 | PTE_P | PTE_W, 772 | 0x2e2000 | PTE_P | PTE_W, 773 | 0x2e3000 | PTE_P | PTE_W, 774 | 0x2e4000 | PTE_P | PTE_W, 775 | 0x2e5000 | PTE_P | PTE_W, 776 | 0x2e6000 | PTE_P | PTE_W, 777 | 0x2e7000 | PTE_P | PTE_W, 778 | 0x2e8000 | PTE_P | PTE_W, 779 | 0x2e9000 | PTE_P | PTE_W, 780 | 0x2ea000 | PTE_P | PTE_W, 781 | 0x2eb000 | PTE_P | PTE_W, 782 | 0x2ec000 | PTE_P | PTE_W, 783 | 0x2ed000 | PTE_P | PTE_W, 784 | 0x2ee000 | PTE_P | PTE_W, 785 | 0x2ef000 | PTE_P | PTE_W, 786 | 0x2f0000 | PTE_P | PTE_W, 787 | 0x2f1000 | PTE_P | PTE_W, 788 | 0x2f2000 | PTE_P | PTE_W, 789 | 0x2f3000 | PTE_P | PTE_W, 790 | 0x2f4000 | PTE_P | PTE_W, 791 | 0x2f5000 | PTE_P | PTE_W, 792 | 0x2f6000 | PTE_P | PTE_W, 793 | 0x2f7000 | PTE_P | PTE_W, 794 | 0x2f8000 | PTE_P | PTE_W, 795 | 0x2f9000 | PTE_P | PTE_W, 796 | 0x2fa000 | PTE_P | PTE_W, 797 | 0x2fb000 | PTE_P | PTE_W, 798 | 0x2fc000 | PTE_P | PTE_W, 799 | 0x2fd000 | PTE_P | PTE_W, 800 | 0x2fe000 | PTE_P | PTE_W, 801 | 0x2ff000 | PTE_P | PTE_W, 802 | 0x300000 | PTE_P | PTE_W, 803 | 0x301000 | PTE_P | PTE_W, 804 | 0x302000 | PTE_P | PTE_W, 805 | 0x303000 | PTE_P | PTE_W, 806 | 0x304000 | PTE_P | PTE_W, 807 | 0x305000 | PTE_P | PTE_W, 808 | 0x306000 | PTE_P | PTE_W, 809 | 0x307000 | PTE_P | PTE_W, 810 | 0x308000 | PTE_P | PTE_W, 811 | 0x309000 | PTE_P | PTE_W, 812 | 0x30a000 | PTE_P | PTE_W, 813 | 0x30b000 | PTE_P | PTE_W, 814 | 0x30c000 | PTE_P | PTE_W, 815 | 0x30d000 | PTE_P | PTE_W, 816 | 0x30e000 | PTE_P | PTE_W, 817 | 0x30f000 | PTE_P | PTE_W, 818 | 0x310000 | PTE_P | PTE_W, 819 | 0x311000 | PTE_P | PTE_W, 820 | 0x312000 | PTE_P | PTE_W, 821 | 0x313000 | PTE_P | PTE_W, 822 | 0x314000 | PTE_P | PTE_W, 823 | 0x315000 | PTE_P | PTE_W, 824 | 0x316000 | PTE_P | PTE_W, 825 | 0x317000 | PTE_P | PTE_W, 826 | 0x318000 | PTE_P | PTE_W, 827 | 0x319000 | PTE_P | PTE_W, 828 | 0x31a000 | PTE_P | PTE_W, 829 | 0x31b000 | PTE_P | PTE_W, 830 | 0x31c000 | PTE_P | PTE_W, 831 | 0x31d000 | PTE_P | PTE_W, 832 | 0x31e000 | PTE_P | PTE_W, 833 | 0x31f000 | PTE_P | PTE_W, 834 | 0x320000 | PTE_P | PTE_W, 835 | 0x321000 | PTE_P | PTE_W, 836 | 0x322000 | PTE_P | PTE_W, 837 | 0x323000 | PTE_P | PTE_W, 838 | 0x324000 | PTE_P | PTE_W, 839 | 0x325000 | PTE_P | PTE_W, 840 | 0x326000 | PTE_P | PTE_W, 841 | 0x327000 | PTE_P | PTE_W, 842 | 0x328000 | PTE_P | PTE_W, 843 | 0x329000 | PTE_P | PTE_W, 844 | 0x32a000 | PTE_P | PTE_W, 845 | 0x32b000 | PTE_P | PTE_W, 846 | 0x32c000 | PTE_P | PTE_W, 847 | 0x32d000 | PTE_P | PTE_W, 848 | 0x32e000 | PTE_P | PTE_W, 849 | 0x32f000 | PTE_P | PTE_W, 850 | 0x330000 | PTE_P | PTE_W, 851 | 0x331000 | PTE_P | PTE_W, 852 | 0x332000 | PTE_P | PTE_W, 853 | 0x333000 | PTE_P | PTE_W, 854 | 0x334000 | PTE_P | PTE_W, 855 | 0x335000 | PTE_P | PTE_W, 856 | 0x336000 | PTE_P | PTE_W, 857 | 0x337000 | PTE_P | PTE_W, 858 | 0x338000 | PTE_P | PTE_W, 859 | 0x339000 | PTE_P | PTE_W, 860 | 0x33a000 | PTE_P | PTE_W, 861 | 0x33b000 | PTE_P | PTE_W, 862 | 0x33c000 | PTE_P | PTE_W, 863 | 0x33d000 | PTE_P | PTE_W, 864 | 0x33e000 | PTE_P | PTE_W, 865 | 0x33f000 | PTE_P | PTE_W, 866 | 0x340000 | PTE_P | PTE_W, 867 | 0x341000 | PTE_P | PTE_W, 868 | 0x342000 | PTE_P | PTE_W, 869 | 0x343000 | PTE_P | PTE_W, 870 | 0x344000 | PTE_P | PTE_W, 871 | 0x345000 | PTE_P | PTE_W, 872 | 0x346000 | PTE_P | PTE_W, 873 | 0x347000 | PTE_P | PTE_W, 874 | 0x348000 | PTE_P | PTE_W, 875 | 0x349000 | PTE_P | PTE_W, 876 | 0x34a000 | PTE_P | PTE_W, 877 | 0x34b000 | PTE_P | PTE_W, 878 | 0x34c000 | PTE_P | PTE_W, 879 | 0x34d000 | PTE_P | PTE_W, 880 | 0x34e000 | PTE_P | PTE_W, 881 | 0x34f000 | PTE_P | PTE_W, 882 | 0x350000 | PTE_P | PTE_W, 883 | 0x351000 | PTE_P | PTE_W, 884 | 0x352000 | PTE_P | PTE_W, 885 | 0x353000 | PTE_P | PTE_W, 886 | 0x354000 | PTE_P | PTE_W, 887 | 0x355000 | PTE_P | PTE_W, 888 | 0x356000 | PTE_P | PTE_W, 889 | 0x357000 | PTE_P | PTE_W, 890 | 0x358000 | PTE_P | PTE_W, 891 | 0x359000 | PTE_P | PTE_W, 892 | 0x35a000 | PTE_P | PTE_W, 893 | 0x35b000 | PTE_P | PTE_W, 894 | 0x35c000 | PTE_P | PTE_W, 895 | 0x35d000 | PTE_P | PTE_W, 896 | 0x35e000 | PTE_P | PTE_W, 897 | 0x35f000 | PTE_P | PTE_W, 898 | 0x360000 | PTE_P | PTE_W, 899 | 0x361000 | PTE_P | PTE_W, 900 | 0x362000 | PTE_P | PTE_W, 901 | 0x363000 | PTE_P | PTE_W, 902 | 0x364000 | PTE_P | PTE_W, 903 | 0x365000 | PTE_P | PTE_W, 904 | 0x366000 | PTE_P | PTE_W, 905 | 0x367000 | PTE_P | PTE_W, 906 | 0x368000 | PTE_P | PTE_W, 907 | 0x369000 | PTE_P | PTE_W, 908 | 0x36a000 | PTE_P | PTE_W, 909 | 0x36b000 | PTE_P | PTE_W, 910 | 0x36c000 | PTE_P | PTE_W, 911 | 0x36d000 | PTE_P | PTE_W, 912 | 0x36e000 | PTE_P | PTE_W, 913 | 0x36f000 | PTE_P | PTE_W, 914 | 0x370000 | PTE_P | PTE_W, 915 | 0x371000 | PTE_P | PTE_W, 916 | 0x372000 | PTE_P | PTE_W, 917 | 0x373000 | PTE_P | PTE_W, 918 | 0x374000 | PTE_P | PTE_W, 919 | 0x375000 | PTE_P | PTE_W, 920 | 0x376000 | PTE_P | PTE_W, 921 | 0x377000 | PTE_P | PTE_W, 922 | 0x378000 | PTE_P | PTE_W, 923 | 0x379000 | PTE_P | PTE_W, 924 | 0x37a000 | PTE_P | PTE_W, 925 | 0x37b000 | PTE_P | PTE_W, 926 | 0x37c000 | PTE_P | PTE_W, 927 | 0x37d000 | PTE_P | PTE_W, 928 | 0x37e000 | PTE_P | PTE_W, 929 | 0x37f000 | PTE_P | PTE_W, 930 | 0x380000 | PTE_P | PTE_W, 931 | 0x381000 | PTE_P | PTE_W, 932 | 0x382000 | PTE_P | PTE_W, 933 | 0x383000 | PTE_P | PTE_W, 934 | 0x384000 | PTE_P | PTE_W, 935 | 0x385000 | PTE_P | PTE_W, 936 | 0x386000 | PTE_P | PTE_W, 937 | 0x387000 | PTE_P | PTE_W, 938 | 0x388000 | PTE_P | PTE_W, 939 | 0x389000 | PTE_P | PTE_W, 940 | 0x38a000 | PTE_P | PTE_W, 941 | 0x38b000 | PTE_P | PTE_W, 942 | 0x38c000 | PTE_P | PTE_W, 943 | 0x38d000 | PTE_P | PTE_W, 944 | 0x38e000 | PTE_P | PTE_W, 945 | 0x38f000 | PTE_P | PTE_W, 946 | 0x390000 | PTE_P | PTE_W, 947 | 0x391000 | PTE_P | PTE_W, 948 | 0x392000 | PTE_P | PTE_W, 949 | 0x393000 | PTE_P | PTE_W, 950 | 0x394000 | PTE_P | PTE_W, 951 | 0x395000 | PTE_P | PTE_W, 952 | 0x396000 | PTE_P | PTE_W, 953 | 0x397000 | PTE_P | PTE_W, 954 | 0x398000 | PTE_P | PTE_W, 955 | 0x399000 | PTE_P | PTE_W, 956 | 0x39a000 | PTE_P | PTE_W, 957 | 0x39b000 | PTE_P | PTE_W, 958 | 0x39c000 | PTE_P | PTE_W, 959 | 0x39d000 | PTE_P | PTE_W, 960 | 0x39e000 | PTE_P | PTE_W, 961 | 0x39f000 | PTE_P | PTE_W, 962 | 0x3a0000 | PTE_P | PTE_W, 963 | 0x3a1000 | PTE_P | PTE_W, 964 | 0x3a2000 | PTE_P | PTE_W, 965 | 0x3a3000 | PTE_P | PTE_W, 966 | 0x3a4000 | PTE_P | PTE_W, 967 | 0x3a5000 | PTE_P | PTE_W, 968 | 0x3a6000 | PTE_P | PTE_W, 969 | 0x3a7000 | PTE_P | PTE_W, 970 | 0x3a8000 | PTE_P | PTE_W, 971 | 0x3a9000 | PTE_P | PTE_W, 972 | 0x3aa000 | PTE_P | PTE_W, 973 | 0x3ab000 | PTE_P | PTE_W, 974 | 0x3ac000 | PTE_P | PTE_W, 975 | 0x3ad000 | PTE_P | PTE_W, 976 | 0x3ae000 | PTE_P | PTE_W, 977 | 0x3af000 | PTE_P | PTE_W, 978 | 0x3b0000 | PTE_P | PTE_W, 979 | 0x3b1000 | PTE_P | PTE_W, 980 | 0x3b2000 | PTE_P | PTE_W, 981 | 0x3b3000 | PTE_P | PTE_W, 982 | 0x3b4000 | PTE_P | PTE_W, 983 | 0x3b5000 | PTE_P | PTE_W, 984 | 0x3b6000 | PTE_P | PTE_W, 985 | 0x3b7000 | PTE_P | PTE_W, 986 | 0x3b8000 | PTE_P | PTE_W, 987 | 0x3b9000 | PTE_P | PTE_W, 988 | 0x3ba000 | PTE_P | PTE_W, 989 | 0x3bb000 | PTE_P | PTE_W, 990 | 0x3bc000 | PTE_P | PTE_W, 991 | 0x3bd000 | PTE_P | PTE_W, 992 | 0x3be000 | PTE_P | PTE_W, 993 | 0x3bf000 | PTE_P | PTE_W, 994 | 0x3c0000 | PTE_P | PTE_W, 995 | 0x3c1000 | PTE_P | PTE_W, 996 | 0x3c2000 | PTE_P | PTE_W, 997 | 0x3c3000 | PTE_P | PTE_W, 998 | 0x3c4000 | PTE_P | PTE_W, 999 | 0x3c5000 | PTE_P | PTE_W, 1000 | 0x3c6000 | PTE_P | PTE_W, 1001 | 0x3c7000 | PTE_P | PTE_W, 1002 | 0x3c8000 | PTE_P | PTE_W, 1003 | 0x3c9000 | PTE_P | PTE_W, 1004 | 0x3ca000 | PTE_P | PTE_W, 1005 | 0x3cb000 | PTE_P | PTE_W, 1006 | 0x3cc000 | PTE_P | PTE_W, 1007 | 0x3cd000 | PTE_P | PTE_W, 1008 | 0x3ce000 | PTE_P | PTE_W, 1009 | 0x3cf000 | PTE_P | PTE_W, 1010 | 0x3d0000 | PTE_P | PTE_W, 1011 | 0x3d1000 | PTE_P | PTE_W, 1012 | 0x3d2000 | PTE_P | PTE_W, 1013 | 0x3d3000 | PTE_P | PTE_W, 1014 | 0x3d4000 | PTE_P | PTE_W, 1015 | 0x3d5000 | PTE_P | PTE_W, 1016 | 0x3d6000 | PTE_P | PTE_W, 1017 | 0x3d7000 | PTE_P | PTE_W, 1018 | 0x3d8000 | PTE_P | PTE_W, 1019 | 0x3d9000 | PTE_P | PTE_W, 1020 | 0x3da000 | PTE_P | PTE_W, 1021 | 0x3db000 | PTE_P | PTE_W, 1022 | 0x3dc000 | PTE_P | PTE_W, 1023 | 0x3dd000 | PTE_P | PTE_W, 1024 | 0x3de000 | PTE_P | PTE_W, 1025 | 0x3df000 | PTE_P | PTE_W, 1026 | 0x3e0000 | PTE_P | PTE_W, 1027 | 0x3e1000 | PTE_P | PTE_W, 1028 | 0x3e2000 | PTE_P | PTE_W, 1029 | 0x3e3000 | PTE_P | PTE_W, 1030 | 0x3e4000 | PTE_P | PTE_W, 1031 | 0x3e5000 | PTE_P | PTE_W, 1032 | 0x3e6000 | PTE_P | PTE_W, 1033 | 0x3e7000 | PTE_P | PTE_W, 1034 | 0x3e8000 | PTE_P | PTE_W, 1035 | 0x3e9000 | PTE_P | PTE_W, 1036 | 0x3ea000 | PTE_P | PTE_W, 1037 | 0x3eb000 | PTE_P | PTE_W, 1038 | 0x3ec000 | PTE_P | PTE_W, 1039 | 0x3ed000 | PTE_P | PTE_W, 1040 | 0x3ee000 | PTE_P | PTE_W, 1041 | 0x3ef000 | PTE_P | PTE_W, 1042 | 0x3f0000 | PTE_P | PTE_W, 1043 | 0x3f1000 | PTE_P | PTE_W, 1044 | 0x3f2000 | PTE_P | PTE_W, 1045 | 0x3f3000 | PTE_P | PTE_W, 1046 | 0x3f4000 | PTE_P | PTE_W, 1047 | 0x3f5000 | PTE_P | PTE_W, 1048 | 0x3f6000 | PTE_P | PTE_W, 1049 | 0x3f7000 | PTE_P | PTE_W, 1050 | 0x3f8000 | PTE_P | PTE_W, 1051 | 0x3f9000 | PTE_P | PTE_W, 1052 | 0x3fa000 | PTE_P | PTE_W, 1053 | 0x3fb000 | PTE_P | PTE_W, 1054 | 0x3fc000 | PTE_P | PTE_W, 1055 | 0x3fd000 | PTE_P | PTE_W, 1056 | 0x3fe000 | PTE_P | PTE_W, 1057 | 0x3ff000 | PTE_P | PTE_W, 1058 | }; 1059 | 1060 | -------------------------------------------------------------------------------- /kernel/lib/memlayout.h: -------------------------------------------------------------------------------- 1 | #ifndef JOS_INC_MEMLAYOUT_H 2 | #define JOS_INC_MEMLAYOUT_H 3 | 4 | #ifndef __ASSEMBLER__ 5 | #include "types.h" 6 | #include "mmu.h" 7 | #endif /* not __ASSEMBLER__ */ 8 | 9 | /* 10 | * This file contains definitions for memory management in our OS, 11 | * which are relevant to both the kernel and user-mode software. 12 | */ 13 | 14 | // Global descriptor numbers 15 | #define GD_KT 0x08 // kernel text 16 | #define GD_KD 0x10 // kernel data 17 | #define GD_UT 0x18 // user text 18 | #define GD_UD 0x20 // user data 19 | #define GD_TSS0 0x28 // Task segment selector for CPU 0 20 | 21 | /* 22 | * Virtual memory map: Permissions 23 | * kernel/user 24 | * 25 | * 4 Gig --------> +------------------------------+ 26 | * | | RW/-- 27 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 28 | * : . : 29 | * : . : 30 | * : . : 31 | * |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/-- 32 | * | | RW/-- 33 | * | Remapped Physical Memory | RW/-- 34 | * | | RW/-- 35 | * KERNBASE, ----> +------------------------------+ 0xf0000000 --+ 36 | * KSTACKTOP | CPU0's Kernel Stack | RW/-- KSTKSIZE | 37 | * | - - - - - - - - - - - - - - -| | 38 | * | Invalid Memory (*) | --/-- KSTKGAP | 39 | * +------------------------------+ | 40 | * | CPU1's Kernel Stack | RW/-- KSTKSIZE | 41 | * | - - - - - - - - - - - - - - -| PTSIZE 42 | * | Invalid Memory (*) | --/-- KSTKGAP | 43 | * +------------------------------+ | 44 | * : . : | 45 | * : . : | 46 | * MMIOLIM ------> +------------------------------+ 0xefc00000 --+ 47 | * | Memory-mapped I/O | RW/-- PTSIZE 48 | * ULIM, MMIOBASE --> +------------------------------+ 0xef800000 49 | * | Cur. Page Table (User R-) | R-/R- PTSIZE 50 | * UVPT ----> +------------------------------+ 0xef400000 51 | * | RO PAGES | R-/R- PTSIZE 52 | * UPAGES ----> +------------------------------+ 0xef000000 53 | * | RO ENVS | R-/R- PTSIZE 54 | * UTOP,UENVS ------> +------------------------------+ 0xeec00000 55 | * UXSTACKTOP -/ | User Exception Stack | RW/RW PGSIZE 56 | * +------------------------------+ 0xeebff000 57 | * | Empty Memory (*) | --/-- PGSIZE 58 | * USTACKTOP ---> +------------------------------+ 0xeebfe000 59 | * | Normal User Stack | RW/RW PGSIZE 60 | * +------------------------------+ 0xeebfd000 61 | * | | 62 | * | | 63 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 64 | * . . 65 | * . . 66 | * . . 67 | * |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| 68 | * | Program Data & Heap | 69 | * UTEXT --------> +------------------------------+ 0x00800000 70 | * PFTEMP -------> | Empty Memory (*) | PTSIZE 71 | * | | 72 | * UTEMP --------> +------------------------------+ 0x00400000 --+ 73 | * | Empty Memory (*) | | 74 | * | - - - - - - - - - - - - - - -| | 75 | * | User STAB Data (optional) | PTSIZE 76 | * USTABDATA ----> +------------------------------+ 0x00200000 | 77 | * | Empty Memory (*) | | 78 | * 0 ------------> +------------------------------+ --+ 79 | * 80 | * (*) Note: The kernel ensures that "Invalid Memory" is *never* mapped. 81 | * "Empty Memory" is normally unmapped, but user programs may map pages 82 | * there if desired. JOS user programs map pages temporarily at UTEMP. 83 | */ 84 | 85 | 86 | // All physical memory mapped at this address 87 | #define KERNBASE 0xF0000000 88 | 89 | // At IOPHYSMEM (640K) there is a 384K hole for I/O. From the kernel, 90 | // IOPHYSMEM can be addressed at KERNBASE + IOPHYSMEM. The hole ends 91 | // at physical address EXTPHYSMEM. 92 | #define IOPHYSMEM 0x0A0000 93 | #define EXTPHYSMEM 0x100000 94 | 95 | // Kernel stack. 96 | #define KSTACKTOP KERNBASE 97 | #define KSTKSIZE (8*PGSIZE) // size of a kernel stack 98 | #define KSTKGAP (8*PGSIZE) // size of a kernel stack guard 99 | 100 | // Memory-mapped IO. 101 | #define MMIOLIM (KSTACKTOP - PTSIZE) 102 | #define MMIOBASE (MMIOLIM - PTSIZE) 103 | 104 | #define ULIM (MMIOBASE) 105 | 106 | /* 107 | * User read-only mappings! Anything below here til UTOP are readonly to user. 108 | * They are global pages mapped in at env allocation time. 109 | */ 110 | 111 | // User read-only virtual page table (see 'uvpt' below) 112 | #define UVPT (ULIM - PTSIZE) 113 | // Read-only copies of the Page structures 114 | #define UPAGES (UVPT - PTSIZE) 115 | // Read-only copies of the global env structures 116 | #define UENVS (UPAGES - PTSIZE) 117 | 118 | /* 119 | * Top of user VM. User can manipulate VA from UTOP-1 and down! 120 | */ 121 | 122 | // Top of user-accessible VM 123 | #define UTOP UENVS 124 | // Top of one-page user exception stack 125 | #define UXSTACKTOP UTOP 126 | // Next page left invalid to guard against exception stack overflow; then: 127 | // Top of normal user stack 128 | #define USTACKTOP (UTOP - 2*PGSIZE) 129 | 130 | // Where user programs generally begin 131 | #define UTEXT (2*PTSIZE) 132 | 133 | // Used for temporary page mappings. Typed 'void*' for convenience 134 | #define UTEMP ((void*) PTSIZE) 135 | // Used for temporary page mappings for the user page-fault handler 136 | // (should not conflict with other temporary page mappings) 137 | #define PFTEMP (UTEMP + PTSIZE - PGSIZE) 138 | // The location of the user-level STABS data structure 139 | #define USTABDATA (PTSIZE / 2) 140 | 141 | #ifndef __ASSEMBLER__ 142 | 143 | typedef uint32_t pte_t; 144 | typedef uint32_t pde_t; 145 | 146 | #endif /* !__ASSEMBLER__ */ 147 | #endif /* !JOS_INC_MEMLAYOUT_H */ 148 | -------------------------------------------------------------------------------- /kernel/lib/mmu.h: -------------------------------------------------------------------------------- 1 | #ifndef JOS_INC_MMU_H 2 | #define JOS_INC_MMU_H 3 | 4 | /* 5 | * This file contains definitions for the x86 memory management unit (MMU), 6 | * including paging- and segmentation-related data structures and constants, 7 | * the %cr0, %cr4, and %eflags registers, and traps. 8 | */ 9 | 10 | /* 11 | * 12 | * Part 1. Paging data structures and constants. 13 | * 14 | */ 15 | 16 | // A linear address 'la' has a three-part structure as follows: 17 | // 18 | // +--------10------+-------10-------+---------12----------+ 19 | // | Page Directory | Page Table | Offset within Page | 20 | // | Index | Index | | 21 | // +----------------+----------------+---------------------+ 22 | // \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/ 23 | // \---------- PGNUM(la) ----------/ 24 | // 25 | // The PDX, PTX, PGOFF, and PGNUM macros decompose linear addresses as shown. 26 | // To construct a linear address la from PDX(la), PTX(la), and PGOFF(la), 27 | // use PGADDR(PDX(la), PTX(la), PGOFF(la)). 28 | 29 | // page number field of address 30 | #define PGNUM(la) (((uintptr_t) (la)) >> PTXSHIFT) 31 | 32 | // page directory index 33 | #define PDX(la) ((((uintptr_t) (la)) >> PDXSHIFT) & 0x3FF) 34 | 35 | // page table index 36 | #define PTX(la) ((((uintptr_t) (la)) >> PTXSHIFT) & 0x3FF) 37 | 38 | // offset in page 39 | #define PGOFF(la) (((uintptr_t) (la)) & 0xFFF) 40 | 41 | // construct linear address from indexes and offset 42 | #define PGADDR(d, t, o) ((void*) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) 43 | 44 | // Page directory and page table constants. 45 | #define NPDENTRIES 1024 // page directory entries per page directory 46 | #define NPTENTRIES 1024 // page table entries per page table 47 | 48 | #define PGSIZE 4096 // bytes mapped by a page 49 | #define PGSHIFT 12 // log2(PGSIZE) 50 | 51 | #define PTSIZE (PGSIZE*NPTENTRIES) // bytes mapped by a page directory entry 52 | #define PTSHIFT 22 // log2(PTSIZE) 53 | 54 | #define PTXSHIFT 12 // offset of PTX in a linear address 55 | #define PDXSHIFT 22 // offset of PDX in a linear address 56 | 57 | // Page table/directory entry flags. 58 | #define PTE_P 0x001 // Present 59 | #define PTE_W 0x002 // Writeable 60 | #define PTE_U 0x004 // User 61 | #define PTE_PWT 0x008 // Write-Through 62 | #define PTE_PCD 0x010 // Cache-Disable 63 | #define PTE_A 0x020 // Accessed 64 | #define PTE_D 0x040 // Dirty 65 | #define PTE_PS 0x080 // Page Size 66 | #define PTE_G 0x100 // Global 67 | 68 | // The PTE_AVAIL bits aren't used by the kernel or interpreted by the 69 | // hardware, so user processes are allowed to set them arbitrarily. 70 | #define PTE_AVAIL 0xE00 // Available for software use 71 | 72 | // Flags in PTE_SYSCALL may be used in system calls. (Others may not.) 73 | #define PTE_SYSCALL (PTE_AVAIL | PTE_P | PTE_W | PTE_U) 74 | 75 | // Address in page table or page directory entry 76 | #define PTE_ADDR(pte) ((physaddr_t) (pte) & ~0xFFF) 77 | 78 | // Control Register flags 79 | #define CR0_PE 0x00000001 // Protection Enable 80 | #define CR0_MP 0x00000002 // Monitor coProcessor 81 | #define CR0_EM 0x00000004 // Emulation 82 | #define CR0_TS 0x00000008 // Task Switched 83 | #define CR0_ET 0x00000010 // Extension Type 84 | #define CR0_NE 0x00000020 // Numeric Errror 85 | #define CR0_WP 0x00010000 // Write Protect 86 | #define CR0_AM 0x00040000 // Alignment Mask 87 | #define CR0_NW 0x20000000 // Not Writethrough 88 | #define CR0_CD 0x40000000 // Cache Disable 89 | #define CR0_PG 0x80000000 // Paging 90 | 91 | #define CR4_PCE 0x00000100 // Performance counter enable 92 | #define CR4_MCE 0x00000040 // Machine Check Enable 93 | #define CR4_PSE 0x00000010 // Page Size Extensions 94 | #define CR4_DE 0x00000008 // Debugging Extensions 95 | #define CR4_TSD 0x00000004 // Time Stamp Disable 96 | #define CR4_PVI 0x00000002 // Protected-Mode Virtual Interrupts 97 | #define CR4_VME 0x00000001 // V86 Mode Extensions 98 | 99 | // Eflags register 100 | #define FL_CF 0x00000001 // Carry Flag 101 | #define FL_PF 0x00000004 // Parity Flag 102 | #define FL_AF 0x00000010 // Auxiliary carry Flag 103 | #define FL_ZF 0x00000040 // Zero Flag 104 | #define FL_SF 0x00000080 // Sign Flag 105 | #define FL_TF 0x00000100 // Trap Flag 106 | #define FL_IF 0x00000200 // Interrupt Flag 107 | #define FL_DF 0x00000400 // Direction Flag 108 | #define FL_OF 0x00000800 // Overflow Flag 109 | #define FL_IOPL_MASK 0x00003000 // I/O Privilege Level bitmask 110 | #define FL_IOPL_0 0x00000000 // IOPL == 0 111 | #define FL_IOPL_1 0x00001000 // IOPL == 1 112 | #define FL_IOPL_2 0x00002000 // IOPL == 2 113 | #define FL_IOPL_3 0x00003000 // IOPL == 3 114 | #define FL_NT 0x00004000 // Nested Task 115 | #define FL_RF 0x00010000 // Resume Flag 116 | #define FL_VM 0x00020000 // Virtual 8086 mode 117 | #define FL_AC 0x00040000 // Alignment Check 118 | #define FL_VIF 0x00080000 // Virtual Interrupt Flag 119 | #define FL_VIP 0x00100000 // Virtual Interrupt Pending 120 | #define FL_ID 0x00200000 // ID flag 121 | 122 | // Page fault error codes 123 | #define FEC_PR 0x1 // Page fault caused by protection violation 124 | #define FEC_WR 0x2 // Page fault caused by a write 125 | #define FEC_U 0x4 // Page fault occured while in user mode 126 | 127 | 128 | /* 129 | * 130 | * Part 2. Segmentation data structures and constants. 131 | * 132 | */ 133 | 134 | #ifdef __ASSEMBLER__ 135 | 136 | /* 137 | * Macros to build GDT entries in assembly. 138 | */ 139 | #define SEG_NULL \ 140 | .word 0, 0; \ 141 | .byte 0, 0, 0, 0 142 | #define SEG(type,base,lim) \ 143 | .word (((lim) >> 12) & 0xffff), ((base) & 0xffff); \ 144 | .byte (((base) >> 16) & 0xff), (0x90 | (type)), \ 145 | (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff) 146 | 147 | #else // not __ASSEMBLER__ 148 | 149 | #include "types.h" 150 | 151 | // Segment Descriptors 152 | struct Segdesc { 153 | unsigned sd_lim_15_0 : 16; // Low bits of segment limit 154 | unsigned sd_base_15_0 : 16; // Low bits of segment base address 155 | unsigned sd_base_23_16 : 8; // Middle bits of segment base address 156 | unsigned sd_type : 4; // Segment type (see STS_ constants) 157 | unsigned sd_s : 1; // 0 = system, 1 = application 158 | unsigned sd_dpl : 2; // Descriptor Privilege Level 159 | unsigned sd_p : 1; // Present 160 | unsigned sd_lim_19_16 : 4; // High bits of segment limit 161 | unsigned sd_avl : 1; // Unused (available for software use) 162 | unsigned sd_rsv1 : 1; // Reserved 163 | unsigned sd_db : 1; // 0 = 16-bit segment, 1 = 32-bit segment 164 | unsigned sd_g : 1; // Granularity: limit scaled by 4K when set 165 | unsigned sd_base_31_24 : 8; // High bits of segment base address 166 | }; 167 | // Null segment 168 | #define SEG_NULL { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 169 | // Segment that is loadable but faults when used 170 | #define SEG_FAULT { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 } 171 | // Normal segment 172 | #define SEG(type, base, lim, dpl) \ 173 | { ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \ 174 | type, 1, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1, \ 175 | (unsigned) (base) >> 24 } 176 | #define SEG16(type, base, lim, dpl) (struct Segdesc) \ 177 | { (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff, \ 178 | type, 1, dpl, 1, (unsigned) (lim) >> 16, 0, 0, 1, 0, \ 179 | (unsigned) (base) >> 24 } 180 | 181 | #endif /* !__ASSEMBLER__ */ 182 | 183 | // Application segment type bits 184 | #define STA_X 0x8 // Executable segment 185 | #define STA_E 0x4 // Expand down (non-executable segments) 186 | #define STA_C 0x4 // Conforming code segment (executable only) 187 | #define STA_W 0x2 // Writeable (non-executable segments) 188 | #define STA_R 0x2 // Readable (executable segments) 189 | #define STA_A 0x1 // Accessed 190 | 191 | // System segment type bits 192 | #define STS_T16A 0x1 // Available 16-bit TSS 193 | #define STS_LDT 0x2 // Local Descriptor Table 194 | #define STS_T16B 0x3 // Busy 16-bit TSS 195 | #define STS_CG16 0x4 // 16-bit Call Gate 196 | #define STS_TG 0x5 // Task Gate / Coum Transmitions 197 | #define STS_IG16 0x6 // 16-bit Interrupt Gate 198 | #define STS_TG16 0x7 // 16-bit Trap Gate 199 | #define STS_T32A 0x9 // Available 32-bit TSS 200 | #define STS_T32B 0xB // Busy 32-bit TSS 201 | #define STS_CG32 0xC // 32-bit Call Gate 202 | #define STS_IG32 0xE // 32-bit Interrupt Gate 203 | #define STS_TG32 0xF // 32-bit Trap Gate 204 | 205 | 206 | /* 207 | * 208 | * Part 3. Traps. 209 | * 210 | */ 211 | 212 | #ifndef __ASSEMBLER__ 213 | 214 | // Task state segment format (as described by the Pentium architecture book) 215 | struct Taskstate { 216 | uint32_t ts_link; // Old ts selector 217 | uintptr_t ts_esp0; // Stack pointers and segment selectors 218 | uint16_t ts_ss0; // after an increase in privilege level 219 | uint16_t ts_padding1; 220 | uintptr_t ts_esp1; 221 | uint16_t ts_ss1; 222 | uint16_t ts_padding2; 223 | uintptr_t ts_esp2; 224 | uint16_t ts_ss2; 225 | uint16_t ts_padding3; 226 | physaddr_t ts_cr3; // Page directory base 227 | uintptr_t ts_eip; // Saved state from last task switch 228 | uint32_t ts_eflags; 229 | uint32_t ts_eax; // More saved state (registers) 230 | uint32_t ts_ecx; 231 | uint32_t ts_edx; 232 | uint32_t ts_ebx; 233 | uintptr_t ts_esp; 234 | uintptr_t ts_ebp; 235 | uint32_t ts_esi; 236 | uint32_t ts_edi; 237 | uint16_t ts_es; // Even more saved state (segment selectors) 238 | uint16_t ts_padding4; 239 | uint16_t ts_cs; 240 | uint16_t ts_padding5; 241 | uint16_t ts_ss; 242 | uint16_t ts_padding6; 243 | uint16_t ts_ds; 244 | uint16_t ts_padding7; 245 | uint16_t ts_fs; 246 | uint16_t ts_padding8; 247 | uint16_t ts_gs; 248 | uint16_t ts_padding9; 249 | uint16_t ts_ldt; 250 | uint16_t ts_padding10; 251 | uint16_t ts_t; // Trap on task switch 252 | uint16_t ts_iomb; // I/O map base address 253 | }; 254 | 255 | // Gate descriptors for interrupts and traps 256 | struct Gatedesc { 257 | unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment 258 | unsigned gd_sel : 16; // segment selector 259 | unsigned gd_args : 5; // # args, 0 for interrupt/trap gates 260 | unsigned gd_rsv1 : 3; // reserved(should be zero I guess) 261 | unsigned gd_type : 4; // type(STS_{TG,IG32,TG32}) 262 | unsigned gd_s : 1; // must be 0 (system) 263 | unsigned gd_dpl : 2; // descriptor(meaning new) privilege level 264 | unsigned gd_p : 1; // Present 265 | unsigned gd_off_31_16 : 16; // high bits of offset in segment 266 | }; 267 | 268 | // Set up a normal interrupt/trap gate descriptor. 269 | // - istrap: 1 for a trap (= exception) gate, 0 for an interrupt gate. 270 | // see section 9.6.1.3 of the i386 reference: "The difference between 271 | // an interrupt gate and a trap gate is in the effect on IF (the 272 | // interrupt-enable flag). An interrupt that vectors through an 273 | // interrupt gate resets IF, thereby preventing other interrupts from 274 | // interfering with the current interrupt handler. A subsequent IRET 275 | // instruction restores IF to the value in the EFLAGS image on the 276 | // stack. An interrupt through a trap gate does not change IF." 277 | // - sel: Code segment selector for interrupt/trap handler 278 | // - off: Offset in code segment for interrupt/trap handler 279 | // - dpl: Descriptor Privilege Level - 280 | // the privilege level required for software to invoke 281 | // this interrupt/trap gate explicitly using an int instruction. 282 | #define SETGATE(gate, istrap, sel, off, dpl) \ 283 | { \ 284 | (gate).gd_off_15_0 = (uint32_t) (off) & 0xffff; \ 285 | (gate).gd_sel = (sel); \ 286 | (gate).gd_args = 0; \ 287 | (gate).gd_rsv1 = 0; \ 288 | (gate).gd_type = (istrap) ? STS_TG32 : STS_IG32; \ 289 | (gate).gd_s = 0; \ 290 | (gate).gd_dpl = (dpl); \ 291 | (gate).gd_p = 1; \ 292 | (gate).gd_off_31_16 = (uint32_t) (off) >> 16; \ 293 | } 294 | 295 | // Set up a call gate descriptor. 296 | #define SETCALLGATE(gate, sel, off, dpl) \ 297 | { \ 298 | (gate).gd_off_15_0 = (uint32_t) (off) & 0xffff; \ 299 | (gate).gd_sel = (sel); \ 300 | (gate).gd_args = 0; \ 301 | (gate).gd_rsv1 = 0; \ 302 | (gate).gd_type = STS_CG32; \ 303 | (gate).gd_s = 0; \ 304 | (gate).gd_dpl = (dpl); \ 305 | (gate).gd_p = 1; \ 306 | (gate).gd_off_31_16 = (uint32_t) (off) >> 16; \ 307 | } 308 | 309 | // Pseudo-descriptors used for LGDT, LLDT and LIDT instructions. 310 | struct Pseudodesc { 311 | uint16_t pd_lim; // Limit 312 | uint32_t pd_base; // Base address 313 | } __attribute__ ((packed)); 314 | 315 | #endif /* !__ASSEMBLER__ */ 316 | 317 | #endif /* !JOS_INC_MMU_H */ 318 | -------------------------------------------------------------------------------- /kernel/lib/types.h: -------------------------------------------------------------------------------- 1 | #ifndef JOS_INC_TYPES_H 2 | #define JOS_INC_TYPES_H 3 | 4 | #ifndef NULL 5 | #define NULL ((void*) 0) 6 | #endif 7 | 8 | // Represents true-or-false values 9 | typedef _Bool bool; 10 | enum { false, true }; 11 | 12 | // Explicitly-sized versions of integer types 13 | typedef __signed char int8_t; 14 | typedef unsigned char uint8_t; 15 | typedef short int16_t; 16 | typedef unsigned short uint16_t; 17 | typedef int int32_t; 18 | typedef unsigned int uint32_t; 19 | typedef long long int64_t; 20 | typedef unsigned long long uint64_t; 21 | 22 | // Pointers and addresses are 32 bits long. 23 | // We use pointer types to represent virtual addresses, 24 | // uintptr_t to represent the numerical values of virtual addresses, 25 | // and physaddr_t to represent physical addresses. 26 | typedef int32_t intptr_t; 27 | typedef uint32_t uintptr_t; 28 | typedef uint32_t physaddr_t; 29 | 30 | // Page numbers are 32 bits long. 31 | typedef uint32_t ppn_t; 32 | 33 | // size_t is used for memory object sizes. 34 | typedef uint32_t size_t; 35 | // ssize_t is a signed version of ssize_t, used in case there might be an 36 | // error return. 37 | typedef int32_t ssize_t; 38 | 39 | // off_t is used for file offsets and lengths. 40 | typedef int32_t off_t; 41 | 42 | // Efficient min and max operations 43 | #define MIN(_a, _b) \ 44 | ({ \ 45 | typeof(_a) __a = (_a); \ 46 | typeof(_b) __b = (_b); \ 47 | __a <= __b ? __a : __b; \ 48 | }) 49 | #define MAX(_a, _b) \ 50 | ({ \ 51 | typeof(_a) __a = (_a); \ 52 | typeof(_b) __b = (_b); \ 53 | __a >= __b ? __a : __b; \ 54 | }) 55 | 56 | // Rounding operations (efficient when n is a power of 2) 57 | // Round down to the nearest multiple of n 58 | #define ROUNDDOWN(a, n) \ 59 | ({ \ 60 | uint32_t __a = (uint32_t) (a); \ 61 | (typeof(a)) (__a - __a % (n)); \ 62 | }) 63 | // Round up to the nearest multiple of n 64 | #define ROUNDUP(a, n) \ 65 | ({ \ 66 | uint32_t __n = (uint32_t) (n); \ 67 | (typeof(a)) (ROUNDDOWN((uint32_t) (a) + __n - 1, __n)); \ 68 | }) 69 | 70 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 71 | 72 | // Return the offset of 'member' relative to the beginning of a struct type 73 | #define offsetof(type, member) ((size_t) (&((type*)0)->member)) 74 | 75 | #endif /* !JOS_INC_TYPES_H */ 76 | -------------------------------------------------------------------------------- /kernel/src/console.rs: -------------------------------------------------------------------------------- 1 | use io::uart::Uart; 2 | use core::fmt; 3 | use spin::Mutex; 4 | use lazy_static::lazy_static; 5 | 6 | lazy_static! { 7 | pub static ref CONSOLE: Mutex = Mutex::new(Console::new()); 8 | } 9 | 10 | pub struct Console { 11 | uart: Uart 12 | } 13 | 14 | impl Console { 15 | fn new() -> Console{ 16 | Console { uart: Uart::new().unwrap()} 17 | } 18 | fn write_byte(&self, value: u8) { 19 | self.uart.write_byte(value) 20 | } 21 | } 22 | impl fmt::Write for Console { 23 | fn write_str(&mut self, s: &str) -> ::core::fmt::Result { 24 | for b in s.bytes() { 25 | self.write_byte(b); 26 | } 27 | Ok(()) 28 | } 29 | } 30 | 31 | pub fn print(args: fmt::Arguments) { 32 | use core::fmt::Write; 33 | CONSOLE.lock().write_fmt(args).unwrap(); 34 | } 35 | 36 | #[macro_export] 37 | macro_rules! println { 38 | () => (print!("\n")); 39 | ($fmt:expr) => (print!(concat!($fmt, "\n"))); 40 | ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); 41 | } 42 | 43 | #[macro_export] 44 | macro_rules! print { 45 | ($($arg:tt)*) => ({ 46 | $crate::console::print(format_args!($($arg)*)); 47 | }); 48 | } -------------------------------------------------------------------------------- /kernel/src/io/mod.rs: -------------------------------------------------------------------------------- 1 | use core::result; 2 | //pub use self::uart::Uart; 3 | 4 | pub mod uart; 5 | 6 | /* 7 | type Result = result::Result; 8 | trait Read { 9 | fn read(&mut self, buf: &mut [u8]) -> Result; 10 | } 11 | */ 12 | -------------------------------------------------------------------------------- /kernel/src/io/uart.rs: -------------------------------------------------------------------------------- 1 | use x86::instruction::{outb, inb}; 2 | //use core::sync::atomic::{AtomicBool, Ordering}; 3 | 4 | const COM1: u16 = 0x3F8; 5 | const COM_RX: u16 = 0; 6 | // In:Receive buffer (DLAB=0) 7 | const COM_TX: u16 = 0; 8 | // Out: Transmit buffer (DLAB=0) 9 | const COM_DLL: u16 = 0; 10 | // Out: Divisor Latch Low (DLAB=1) 11 | const COM_DLM: u16 = 1; 12 | // Out: Divisor Latch High (DLAB=1) 13 | const COM_IER: u16 = 1; 14 | // Out: Interrupt Enable Register 15 | const COM_IER_RDI: u8 = 0x01; 16 | // Enable receiver data interrupt 17 | const COM_IIR: u16 = 2; 18 | // In: Interrupt ID Register 19 | const COM_FCR: u16 = 2; 20 | // Out: FIFO Control Register 21 | const COM_LCR: u16 = 3; 22 | // Out: Line Control Register 23 | const COM_LCR_DLAB: u8 = 0x80; 24 | // Divisor latch access bit 25 | const COM_LCR_WLEN8: u8 = 0x03; 26 | // Wordlength: 8 bits 27 | const COM_MCR: u16 = 4; 28 | // Out: Modem Control Register 29 | const COM_MCR_RTS: u16 = 0x02; 30 | // RTS complement 31 | const COM_MCR_DTR: u16 = 0x01; 32 | // DTR complement 33 | const COM_MCR_OUT2: u16 = 0x08; 34 | // Out2 complement 35 | const COM_LSR: u16 = 5; 36 | // In: Line Status Register 37 | const COM_LSR_DATA: u8 = 0x01; 38 | // Data available 39 | const COM_LSR_TXRDY: u8 = 0x20; 40 | // Transmit buffer avail 41 | const COM_LSR_TSRE: u8 = 0x40; 42 | 43 | //static UART_INITIALIZED: AtomicBool = AtomicBool::new(false); 44 | 45 | // Transmitter off 46 | pub struct Uart { 47 | serial_exists: bool 48 | } 49 | 50 | 51 | impl Uart { 52 | pub fn new() -> Result { 53 | unsafe { Self::init() } 54 | } 55 | 56 | unsafe fn init() -> Result { 57 | // Turn off the FIFO 58 | outb(COM1 + COM_FCR, 0); 59 | 60 | // Set speed; requires DLAB latch 61 | outb(COM1 + COM_LCR, COM_LCR_DLAB); 62 | outb(COM1 + COM_DLL, 12);//12 = (uint8_t)(115200 / 9600) 63 | outb(COM1 + COM_DLM, 0); 64 | 65 | // 8 data bits, 1 stop bit, parity off; turn off DLAB latch 66 | outb(COM1 + COM_LCR, COM_LCR_WLEN8 & !COM_LCR_DLAB); 67 | 68 | // No modem controls 69 | outb(COM1 + COM_MCR, 0); 70 | // Enable rcv interrupts 71 | outb(COM1 + COM_IER, COM_IER_RDI); 72 | 73 | // Clear any preexisting overrun indications and interrupts 74 | // Serial port doesn't exist if COM_LSR returns 0xFF 75 | let serial_exists = inb(COM1 + COM_LSR) != 0xFF; 76 | inb(COM1 + COM_IIR); 77 | inb(COM1 + COM_RX); 78 | Ok(Uart { serial_exists }) 79 | } 80 | 81 | pub fn read_byte(&self) -> Option { 82 | if !self.serial_exists { 83 | return None 84 | } 85 | unsafe { 86 | //wait com port empty 87 | for _ in 0..10000 { 88 | if (inb(COM1 + COM_IER) & COM_LSR_DATA) != 0 { 89 | return Some(inb(COM1)) 90 | } 91 | } 92 | None 93 | } 94 | } 95 | 96 | pub fn write_byte(&self, value: u8) { 97 | unsafe { 98 | //wait com port empty 99 | for _ in 0..10000 { 100 | if inb(COM1 + COM_LSR) & COM_LSR_TXRDY != 0 { 101 | break; 102 | } 103 | } 104 | outb(COM1, value); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /kernel/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![feature(lang_items)] 3 | #![feature(asm)] 4 | extern crate x86; 5 | #[macro_use] 6 | extern crate lazy_static; 7 | extern crate spin; 8 | mod io; 9 | use core::panic::PanicInfo; 10 | use io::uart::Uart; 11 | 12 | #[macro_use] 13 | mod console; 14 | //global_asm!(include_str!("entry.S")); 15 | static HELLO: &[u8] = b"\nHello World!!!!!"; 16 | 17 | #[no_mangle] 18 | pub extern "C" fn i386_init() { 19 | println!("Hello world!"); 20 | println!("Hello {}!", "world"); 21 | println!("{} | {} | {1} | {three} | {four}", 22 | "One", 23 | "Two", 24 | three="three", 25 | four=4); 26 | loop {} 27 | } 28 | 29 | #[panic_handler] 30 | #[no_mangle] 31 | pub extern "C" fn panic(_info: &PanicInfo) -> ! { 32 | loop {} 33 | } 34 | 35 | #[lang = "eh_personality"] 36 | #[no_mangle] 37 | pub extern "C" fn eh_personality() {} -------------------------------------------------------------------------------- /kernel/src/util/lazy.rs: -------------------------------------------------------------------------------- 1 | use spin::Once; 2 | struct Lazy T> { 3 | cell: Once, 4 | init: F, 5 | } 6 | impl T> Lazy { 7 | const fn new(init: F) -> Lazy { 8 | Lazy { cell: sync::OnceCell::new(), init } 9 | } 10 | } 11 | impl T> ::std::ops::Deref for Lazy { 12 | type Target = T; 13 | fn deref(&self) -> &T { 14 | self.cell.get_or_init(|| (self.init)()) 15 | } 16 | } -------------------------------------------------------------------------------- /kernel/xv6-rs-kernel.json: -------------------------------------------------------------------------------- 1 | { 2 | "llvm-target": "i386-unknown-none", 3 | "target-endian": "little", 4 | "target-c-int-width": "32", 5 | "target-pointer-width": "32", 6 | "max-atomic-width": "64", 7 | "data-layout": "e-m:e-i32:32-f32:32-n8:16:32-S128-p:32:32:32", 8 | "arch": "x86", 9 | "cpu": "pentium4", 10 | "os": "none", 11 | "linker-flavor": "ld", 12 | "linker": "i386-jos-elf-ld.bfd", 13 | "features": "-mmx,-sse,+soft-float", 14 | "dynamic-linking": false, 15 | "has-rpath": false, 16 | "no-default-libraries": true, 17 | "has-elf-tls": true, 18 | "eliminate-frame-pointer": false, 19 | "no-compiler-rt": true, 20 | "disable-redzone": true, 21 | "panic-strategy": "abort", 22 | "executables": false 23 | } 24 | -------------------------------------------------------------------------------- /lib/x86/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "x86" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /lib/x86/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "x86" 3 | version = "0.1.0" 4 | authors = ["youta ogino "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /lib/x86/src/instruction.rs: -------------------------------------------------------------------------------- 1 | 2 | #[inline(always)] 3 | pub unsafe fn inb(port: u16) -> u8 { 4 | let data: u8; 5 | asm!("inb %dx, %al" : "={ax}" (data) : "{dx}"(port) :: "volatile"); 6 | return data; 7 | } 8 | 9 | #[inline(always)] 10 | pub unsafe fn insl(port: u16, addr: u32, cnt: u32) { 11 | asm!("cld; rep insl %dx, (%edi)" 12 | : 13 | : "{ecx}"(cnt), "{dx}"(port), "{edi}"(addr) 14 | : "ecx", "edi", "memory", "cc" 15 | : "volatile"); 16 | } 17 | 18 | #[inline(always)] 19 | pub unsafe fn outb(port: u16, data: u8) { 20 | asm!("outb %al, %dx" :: "{dx}"(port), "{al}"(data) :: "volatile"); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /lib/x86/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![feature(asm)] 3 | pub mod instruction; -------------------------------------------------------------------------------- /lib/x86/x86.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | --------------------------------------------------------------------------------