some stuff
This commit is contained in:
parent
0aae87eda3
commit
e2cf54877e
16 changed files with 186 additions and 116 deletions
2
kernel-rs/.gdbinit
Normal file
2
kernel-rs/.gdbinit
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
set arch i386:x86-64
|
||||||
|
symbol-file build/bluesnow-x86.bin
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bluesnow"
|
name = "bluesnow"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Jack Halford <j@crans.org>", "William Escande <wescande@student.42.fr>"]
|
authors = ["Jack Halford <jack@crans.org>", "William Escande <wescande@student.42.fr>"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["staticlib"]
|
crate-type = ["staticlib"]
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,11 @@ ARCH := x86
|
||||||
OS := bluesnow
|
OS := bluesnow
|
||||||
TARGET ?= $(ARCH)-$(OS)
|
TARGET ?= $(ARCH)-$(OS)
|
||||||
|
|
||||||
|
all:
|
||||||
|
@printf "make kernel\t# build kernel binary\n"
|
||||||
|
@printf "make iso\t# build iso cdrom with grub\n"
|
||||||
|
@printf "make qemu\t# run qemu+gdb in tmux window\n"
|
||||||
|
|
||||||
## COMPILE ASM (nasm)
|
## COMPILE ASM (nasm)
|
||||||
asm_source := $(wildcard src/arch/$(ARCH)/*.asm)
|
asm_source := $(wildcard src/arch/$(ARCH)/*.asm)
|
||||||
asm_object := $(patsubst src/arch/$(ARCH)/%.asm, build/arch/$(ARCH)/%.o, $(asm_source))
|
asm_object := $(patsubst src/arch/$(ARCH)/%.asm, build/arch/$(ARCH)/%.o, $(asm_source))
|
||||||
|
|
@ -15,18 +20,18 @@ build/arch/$(ARCH)/%.o: src/arch/$(ARCH)/%.asm Makefile
|
||||||
## COMPILE RUST (xargo)
|
## COMPILE RUST (xargo)
|
||||||
rust_os := target/$(TARGET)/debug/lib$(OS).a
|
rust_os := target/$(TARGET)/debug/lib$(OS).a
|
||||||
$(rust_os): $(TARGET).json Makefile
|
$(rust_os): $(TARGET).json Makefile
|
||||||
@TERM=xterm RUST_TARGET_PATH="$(shell pwd)" xargo build --target $(TARGET)
|
TERM=xterm RUST_TARGET_PATH="$(shell pwd)" xargo build --target $(TARGET)
|
||||||
|
|
||||||
## LINKAGE
|
## LINKAGE
|
||||||
kernel := build/$(OS)
|
kernel := build/$(OS)-$(ARCH).bin
|
||||||
linker_script := src/arch/$(ARCH)/linker.ld
|
linker_script := src/arch/$(ARCH)/linker.ld
|
||||||
LD := /usr/bin/ld -m elf_i386 -L ./ -n --gc-sections
|
LD := /usr/bin/ld -m elf_i386 -L ./ -n --gc-sections
|
||||||
$(kernel): $(rust_os) $(asm_object) $(linker_script) Makefile
|
$(kernel): $(rust_os) $(asm_object) $(linker_script) Makefile
|
||||||
$(LD) -o $@ -T $(linker_script) $(asm_object) $(rust_os)
|
$(LD) -o $@ -T $(linker_script) $(asm_object) $(rust_os)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@xargo clean
|
xargo clean
|
||||||
@rm -rf build
|
rm -rf build
|
||||||
|
|
||||||
.PHONY: clean kernel iso $(rust_os)
|
.PHONY: clean kernel iso $(rust_os)
|
||||||
|
|
||||||
|
|
@ -37,3 +42,4 @@ include mk/qemu.mk
|
||||||
include mk/grub.mk
|
include mk/grub.mk
|
||||||
iso: $(grub-iso)
|
iso: $(grub-iso)
|
||||||
|
|
||||||
|
kernel: $(kernel)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
grub-iso := $(kernel).iso
|
grub-iso := $(kernel:.bin=.iso)
|
||||||
grub-cfg := src/arch/$(ARCH)/grub.cfg
|
grub-cfg := src/arch/$(ARCH)/grub.cfg
|
||||||
isodir := build/isofiles
|
isodir := build/isofiles
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
ifeq ($(shell whoami), william)
|
ifeq ($(shell whoami), jack)
|
||||||
PORT := 4242
|
PORT := 4242
|
||||||
PORTG := 4244
|
PORTG := 4244
|
||||||
else
|
else
|
||||||
|
|
@ -6,20 +6,22 @@ else
|
||||||
PORTG := 4344
|
PORTG := 4344
|
||||||
endif
|
endif
|
||||||
|
|
||||||
QEMU := qemu-system-x86_64
|
QEMU := qemu-system-x86_64\
|
||||||
QEMUFLAGS := -gdb tcp::$(PORTG) -enable-kvm -monitor telnet:127.0.0.1:$(PORT),server,nowait -curses -cdrom build/bluesnow.iso
|
-gdb tcp::$(PORTG)\
|
||||||
|
-S\
|
||||||
|
-enable-kvm\
|
||||||
|
-monitor telnet:127.0.0.1:$(PORT),server,nowait\
|
||||||
|
-curses\
|
||||||
|
-cdrom build/bluesnow-x86.iso
|
||||||
|
|
||||||
MONITOR := sleep 0.5;\
|
MONITOR := sleep 0.5;\
|
||||||
telnet 127.0.0.1 $(PORT);\
|
telnet 127.0.0.1 $(PORT);\
|
||||||
kill \`ps -x | grep \"[g]db -q\" | cut -d \ -f 1 \`;\
|
kill \`ps -x | grep \"[g]db -q\" | cut -d \ -f 1 \`;\
|
||||||
kill \`ps -x | grep \"[g]db -q\" | cut -d \ -f 2 \`
|
kill \`ps -x | grep \"[g]db -q\" | cut -d \ -f 2 \`
|
||||||
GDB := gdb -q\
|
GDB := gdb -q\
|
||||||
-ex \"set arch i386:x86-64\"\
|
-ex \"target remote :$(PORTG)\"
|
||||||
-ex \"file $(kernel)\"\
|
|
||||||
-ex \"target remote :$(PORTG)\"\
|
|
||||||
-ex \"continue\"
|
|
||||||
|
|
||||||
qemu:
|
qemu:
|
||||||
@tmux info >&- || { echo -e "\033[38;5;16mPlease run inside a tmux session\033[0m" ; exit 1; }
|
@tmux info >&- || { echo -e "\033[38;5;16mPlease run inside a tmux session\033[0m" ; exit 1; }
|
||||||
@tmux new-window 'tmux split-window -h "$(MONITOR)"; tmux split-window -fv "$(GDB)"; tmux select-pane -t 1; tmux resize-pane -x 80 -y 25; $(QEMU) $(QEMUFLAGS)'
|
@tmux new-window 'tmux split-window -h "$(MONITOR)"; tmux split-window -fv "$(GDB)"; tmux select-pane -t 1; tmux resize-pane -x 80 -y 25; $(QEMU)'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,9 @@ use x86::*;
|
||||||
use x86::structures::paging::*;
|
use x86::structures::paging::*;
|
||||||
use arch::x86::paging::*;
|
use arch::x86::paging::*;
|
||||||
|
|
||||||
fn map_heap(active_table: &mut ActivePageTable, offset: u32, size: u32) {
|
fn map_heap(active_table: &mut ActivePageTable) {
|
||||||
let heap_start_page = Page::containing_address(VirtAddr::new(offset));
|
//zone for heap is predefines in `consts.rs`
|
||||||
let heap_end_page = Page::containing_address(VirtAddr::new(offset + size - 1));
|
for page in ::KERNEL_HEAP_RANGE {
|
||||||
|
|
||||||
for page in heap_start_page..heap_end_page + 1 {
|
|
||||||
//we really should only map 1 huge page instead of 1024 small pages
|
|
||||||
active_table.map(page, PageTableFlags::WRITABLE);
|
active_table.map(page, PageTableFlags::WRITABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20,7 +17,8 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
|
||||||
let offset = ::KERNEL_HEAP_OFFSET;
|
let offset = ::KERNEL_HEAP_OFFSET;
|
||||||
let size = ::KERNEL_HEAP_SIZE;
|
let size = ::KERNEL_HEAP_SIZE;
|
||||||
|
|
||||||
map_heap(active_table, offset, size);
|
map_heap(active_table);
|
||||||
|
|
||||||
Allocator::init(offset as usize, size as usize);
|
//slab allocator
|
||||||
|
Allocator::init(offset.as_u32() as usize, size as usize);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ set_up_page_tables:
|
||||||
or eax, 0b10000011 ; huge + present + writable
|
or eax, 0b10000011 ; huge + present + writable
|
||||||
mov [p2_table + 4], eax
|
mov [p2_table + 4], eax
|
||||||
|
|
||||||
|
mov eax, 0x800000 ; 8MB -> 12Mb (second page)
|
||||||
|
or eax, 0b10000011 ; huge + present + writable
|
||||||
|
mov [p2_table + 8], eax
|
||||||
|
|
||||||
mov eax, p2_table
|
mov eax, p2_table
|
||||||
mov cr3, eax
|
mov cr3, eax
|
||||||
ret
|
ret
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,52 @@
|
||||||
//layout looks like this:
|
// p2 layout looks like this:
|
||||||
// [kernel 0->4MiB]
|
// [kernel 0->4MiB]
|
||||||
// [kernel 4->8MiB]
|
// [kernel 4->8MiB]
|
||||||
|
// [start of no man's land]
|
||||||
|
// .
|
||||||
|
// .
|
||||||
|
// .
|
||||||
|
// [end of no man's land]
|
||||||
// [user stack]
|
// [user stack]
|
||||||
// [start of userheap]
|
|
||||||
// .
|
|
||||||
// .
|
|
||||||
// .
|
|
||||||
// [end of userheap]
|
|
||||||
// [kernel heap]
|
// [kernel heap]
|
||||||
// [recursive map] points to first entry
|
// [recursive map] points to first entry
|
||||||
//
|
//
|
||||||
// which makes userheap = 4GiB - 4*4MiB (~= 4GiB)
|
// no man's land should be used in the future for mmap() I guess
|
||||||
macro_rules! p2 { ($i:expr) => {($i & P2_MASK) / P1_SIZE}}
|
// the kernel right now takes up 2 pages with debug symbols,
|
||||||
pub const P2_MASK: u32 = 0xFFC0_0000; //top 10 bits
|
// if it gets to 3 pages everything will crash and i'll have
|
||||||
pub const P1_SIZE: u32 = 0x0040_0000; //4MiB (2**22)
|
// to hardcode the third page here and in `boot.asm` also!
|
||||||
|
//
|
||||||
|
// TODO
|
||||||
|
// kernel is mapped identically (start of memory) but in
|
||||||
|
// the future it should be higher-half mapped so that
|
||||||
|
// user memory starts at 0
|
||||||
|
|
||||||
pub const RECURSIVE_PAGE_OFFSET: u32 = (-(P1_SIZE as isize)) as u32;
|
use x86::structures::paging::*;
|
||||||
///1023
|
use x86::*;
|
||||||
pub const RECURSIVE_PAGE_P2: u32 = p2!(RECURSIVE_PAGE_OFFSET);
|
use core::ops::Range;
|
||||||
|
|
||||||
pub const KERNEL_HEAP_OFFSET: u32 = RECURSIVE_PAGE_OFFSET - P1_SIZE;
|
// macro_rules! prange { ($i:expr, $s:expr) => {$i..$i+$s+1}}
|
||||||
///1022
|
|
||||||
pub const KERNEL_HEAP_P2: u32 = p2!(KERNEL_HEAP_OFFSET);
|
|
||||||
pub const KERNEL_HEAP_SIZE: u32 = 4 * 1024 * 1024; //4MiB (1 huge page)
|
|
||||||
|
|
||||||
pub const USER_OFFSET: u32 = 0x00a0_0000; //3rd page (kernel takes 2 first pages)
|
// all of this is fucking contrived
|
||||||
pub const USER_P2: u32 = p2!(USER_OFFSET);
|
// the rust compiler should be able to evaluate const expressions
|
||||||
|
// by using the impl for my structs, what i'm doing here is obvious
|
||||||
|
// to me but not to the compiler
|
||||||
|
|
||||||
pub const USER_STACK_OFFSET: u32 = USER_OFFSET + P1_SIZE;
|
pub const RECURSIVE_PAGE_OFFSET: VirtAddr = VirtAddr(0xffc0_000); // first 10 bits
|
||||||
pub const USER_STACK_2: u32 = p2!(USER_STACK_OFFSET);
|
pub const RECURSIVE_PAGE: Page = Page::containing_address(RECURSIVE_PAGE_OFFSET);
|
||||||
|
pub const RECURSIVE_PAGE_SIZE: u32 = 0x0040_0000; // the whole p2 entry
|
||||||
|
|
||||||
|
pub const KERNEL_HEAP_OFFSET: VirtAddr = VirtAddr(RECURSIVE_PAGE_OFFSET.0 - RECURSIVE_PAGE_SIZE);
|
||||||
|
// should be
|
||||||
|
// pub const KERNEL_HEAP_OFFSET: VirtAddr = RECURSIVE_PAGE_OFFSET - RECURSIVE_PAGE_SIZE);
|
||||||
|
pub const KERNEL_HEAP_SIZE: u32 = 0x0040_0000; //4MiB (1 huge page)
|
||||||
|
pub const KERNEL_HEAP_START: Page = Page::containing_address(KERNEL_HEAP_OFFSET);
|
||||||
|
pub const KERNEL_HEAP_END: Page =
|
||||||
|
Page::containing_address(VirtAddr(KERNEL_HEAP_OFFSET.0 + KERNEL_HEAP_SIZE));
|
||||||
|
pub const KERNEL_HEAP_RANGE: Range<Page> = KERNEL_HEAP_START..KERNEL_HEAP_END;
|
||||||
|
|
||||||
|
pub const USER_STACK_OFFSET: VirtAddr = VirtAddr(KERNEL_HEAP_OFFSET.0 - KERNEL_HEAP_SIZE);
|
||||||
|
pub const USER_STACK_START: Page = Page::containing_address(USER_STACK_OFFSET);
|
||||||
|
pub const USER_STACK_SIZE: u32 = 0x0040_0000; //4MiB (1 huge page)
|
||||||
|
pub const USER_STACK_END: Page =
|
||||||
|
Page::containing_address(VirtAddr(USER_STACK_OFFSET.0 + USER_STACK_SIZE));
|
||||||
|
pub const USER_STACK_RANGE: Range<Page> = USER_STACK_START..USER_STACK_END;
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,41 @@
|
||||||
use x86::structures::gdt;
|
use x86::structures::gdt;
|
||||||
use x86::structures::tss;
|
use x86::structures::tss;
|
||||||
|
use x86::structures::gdt::{Descriptor, SegmentSelector};
|
||||||
use x86::instructions::segmentation::*;
|
use x86::instructions::segmentation::*;
|
||||||
use x86::instructions::tables::load_tss;
|
use x86::instructions::tables::load_tss;
|
||||||
|
use x86::PrivilegeLevel::{Ring0, Ring3};
|
||||||
use x86::*;
|
use x86::*;
|
||||||
use spin::Once;
|
|
||||||
|
|
||||||
pub static mut GDT: gdt::Gdt = gdt::Gdt::new();
|
pub static mut GDT: gdt::Gdt = gdt::Gdt::new();
|
||||||
pub static mut TSS: tss::TaskStateSegment = tss::TaskStateSegment::new();
|
pub static mut TSS: tss::TaskStateSegment = tss::TaskStateSegment::new();
|
||||||
|
|
||||||
pub static GDT_KERNEL_CODE: u16 = 1;
|
pub static GDT_KERNEL_CODE: u16 = 1;
|
||||||
pub static GDT_KERNEL_DATA: u16 = 1;
|
pub static GDT_KERNEL_DATA: u16 = 2;
|
||||||
pub static GDT_USER_CODE: u16 = 2;
|
pub static GDT_USER_CODE: u16 = 3;
|
||||||
pub static GDT_USER_DATA: u16 = 3;
|
pub static GDT_USER_DATA: u16 = 4;
|
||||||
|
// tss takes 2 spots;
|
||||||
|
pub static GDT_TSS: u16 = 5;
|
||||||
|
|
||||||
pub unsafe fn init() {
|
pub unsafe fn init() {
|
||||||
TSS.ss0 = gdt::SegmentSelector::new(GDT_KERNEL_CODE, PrivilegeLevel::Ring0).0;
|
TSS.ss0 = gdt::SegmentSelector::new(GDT_KERNEL_CODE, PrivilegeLevel::Ring0).0;
|
||||||
asm!("mov %ebp, $0" : "=r" (TSS.esp0));
|
asm!("mov %esp, $0" : "=r" (TSS.esp0));
|
||||||
|
|
||||||
// the following order is important
|
// the following *order* is important
|
||||||
let kcode_selector = GDT.add_entry(gdt::Descriptor::kernel_code_segment());
|
let kcode_selector = GDT.add_entry(gdt::Descriptor::kernel_code_segment());
|
||||||
let kdata_selector = GDT.add_entry(gdt::Descriptor::kernel_data_segment());
|
let kdata_selector = GDT.add_entry(gdt::Descriptor::kernel_data_segment());
|
||||||
let tss_selector = GDT.add_entry(gdt::Descriptor::tss_segment(&TSS));
|
|
||||||
//I read that the tss should be twice as long
|
|
||||||
//fuck knows why...
|
|
||||||
//also this doesnt work if the tss is after 3rd spot
|
|
||||||
//once again: fuck knows why...
|
|
||||||
GDT.add_entry(gdt::Descriptor(0));
|
|
||||||
let ucode_selector = GDT.add_entry(gdt::Descriptor::user_code_segment());
|
let ucode_selector = GDT.add_entry(gdt::Descriptor::user_code_segment());
|
||||||
let udata_selector = GDT.add_entry(gdt::Descriptor::user_data_segment());
|
let udata_selector = GDT.add_entry(gdt::Descriptor::user_data_segment());
|
||||||
|
//I read that the tss should be twice as long
|
||||||
|
//fuck knows why...
|
||||||
|
let tss_selector = GDT.add_entry(gdt::Descriptor::tss_segment(&TSS));
|
||||||
|
GDT.add_entry(gdt::Descriptor(0));
|
||||||
|
|
||||||
|
// println!(
|
||||||
|
// "tr({:#x}):\n {:#?}",
|
||||||
|
// tss_selector.0,
|
||||||
|
// gdt::Descriptor(GDT.table[tss_selector.index() as usize])
|
||||||
|
// );
|
||||||
|
// flush!();
|
||||||
|
|
||||||
GDT.load();
|
GDT.load();
|
||||||
set_cs(kcode_selector);
|
set_cs(kcode_selector);
|
||||||
|
|
@ -35,4 +43,5 @@ pub unsafe fn init() {
|
||||||
load_es(kdata_selector);
|
load_es(kdata_selector);
|
||||||
load_ss(kdata_selector);
|
load_ss(kdata_selector);
|
||||||
load_tss(tss_selector);
|
load_tss(tss_selector);
|
||||||
|
// unreachable!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,4 +66,16 @@ SECTIONS {
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
. = ALIGN(4K);
|
. = ALIGN(4K);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stab :
|
||||||
|
{
|
||||||
|
*(.stab)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stabstr :
|
||||||
|
{
|
||||||
|
*(.stabstr)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,35 +53,39 @@ pub unsafe extern "C" fn x86_rust_start(multiboot_info_addr: usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn usermode(ip: u32, sp: u32, arg: u32) -> ! {
|
pub unsafe fn usermode(ip: u32, sp: u32, arg: u32) -> ! {
|
||||||
asm!("push r10
|
use x86::structures::gdt::{Descriptor, SegmentSelector};
|
||||||
push r11
|
use x86::instructions::segmentation::*;
|
||||||
push r12
|
use x86::PrivilegeLevel::{Ring0, Ring3};
|
||||||
push r13
|
|
||||||
push r14
|
x86::instructions::interrupts::disable();
|
||||||
push r15
|
|
||||||
"
|
// println!("sp: {:#x}", sp);
|
||||||
|
// println!("ip: {:#x}", ip);
|
||||||
|
|
||||||
|
let udata_selector = SegmentSelector::new(gdt::GDT_USER_DATA, Ring0);
|
||||||
|
let ucode_selector = SegmentSelector::new(gdt::GDT_USER_CODE, Ring3);
|
||||||
|
load_ds(udata_selector);
|
||||||
|
load_es(udata_selector);
|
||||||
|
load_fs(udata_selector);
|
||||||
|
load_gs(udata_selector);
|
||||||
|
|
||||||
|
asm!("
|
||||||
|
push $0; \
|
||||||
|
push $1; \
|
||||||
|
push $2; \
|
||||||
|
push $3; \
|
||||||
|
push $4"
|
||||||
: //no output
|
: //no output
|
||||||
: "{r10}"(gdt::GDT_USER_DATA << 3 | 3),
|
: "r"(udata_selector),
|
||||||
"{r11}"(sp),
|
"r"(sp),
|
||||||
"{r12}"(1 << 9) // interrupt enable flag
|
"r"(1 << 9) // interrupt enable flag
|
||||||
"{r13}"(gdt::GDT_USER_CODE << 3 | 3),
|
"r"(ucode_selector),
|
||||||
"{r14}"(ip),
|
"r"(ip)
|
||||||
"{r15}"(arg)
|
|
||||||
: //no clobbers
|
: //no clobbers
|
||||||
: "intel", "volatile"
|
: "intel", "volatile"
|
||||||
);
|
);
|
||||||
|
|
||||||
asm!("mov ds, r14d
|
asm!("iret");
|
||||||
mov es, r14d
|
|
||||||
mov fs, r15d
|
|
||||||
mov gs, r14d
|
|
||||||
fninit
|
|
||||||
iret"
|
|
||||||
: //no output (never returns)
|
|
||||||
: "{r14}"(gdt::GDT_USER_DATA << 3 | 3),
|
|
||||||
"{r15}"(gdt::GDT_USER_CODE << 3 | 3)
|
|
||||||
: //no clobbers (never returns)
|
|
||||||
: "intel", "volatile"
|
|
||||||
);
|
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@ impl Mapper {
|
||||||
let frame = p1[page.p1_index()].pointed_frame().unwrap();
|
let frame = p1[page.p1_index()].pointed_frame().unwrap();
|
||||||
p1[page.p1_index()].set_unused();
|
p1[page.p1_index()].set_unused();
|
||||||
tlb::flush(page.start_address());
|
tlb::flush(page.start_address());
|
||||||
// TODO
|
|
||||||
::memory::deallocate_frames(frame, 1);
|
::memory::deallocate_frames(frame, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,17 +188,19 @@ pub fn regs() -> Result<(), &'static str> {
|
||||||
use x86::registers::control::*;
|
use x86::registers::control::*;
|
||||||
use x86::instructions::tables::tr;
|
use x86::instructions::tables::tr;
|
||||||
use x86::instructions::segmentation::*;
|
use x86::instructions::segmentation::*;
|
||||||
|
use x86::registers::flags::*;
|
||||||
use x86::structures::gdt;
|
use x86::structures::gdt;
|
||||||
println!("cr0 = {:?}", Cr0::read());
|
println!("cr0 = {:?}", Cr0::read());
|
||||||
println!("cr3 = {:?}", Cr3::read());
|
println!("cr3 = {:?}", Cr3::read());
|
||||||
println!("cr4 = {:?}", Cr4::read());
|
println!("cr4 = {:?}", Cr4::read());
|
||||||
println!("tr = {:?}", tr());
|
println!("flags= {:?}", flags());
|
||||||
println!("ss = {:?}", ss());
|
println!("tr = {:?}", tr());
|
||||||
println!("cs = {:?}", cs());
|
println!("ss = {:?}", ss());
|
||||||
println!("ds = {:?}", ds());
|
println!("cs = {:?}", cs());
|
||||||
println!("es = {:?}", es());
|
println!("ds = {:?}", ds());
|
||||||
println!("fs = {:?}", fs());
|
println!("es = {:?}", es());
|
||||||
println!("gs = {:?}", gs());
|
println!("fs = {:?}", fs());
|
||||||
|
println!("gs = {:?}", gs());
|
||||||
unsafe {
|
unsafe {
|
||||||
println!(
|
println!(
|
||||||
"tss = {:#?}",
|
"tss = {:#?}",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// nightly stuff we need
|
// nightly stuff we need
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
|
#![feature(naked_functions)]
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
#![feature(ptr_internals)]
|
#![feature(ptr_internals)]
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
|
|
@ -67,6 +68,26 @@ pub fn kmain() -> ! {
|
||||||
|
|
||||||
// x86::instructions::interrupts::int3();
|
// x86::instructions::interrupts::int3();
|
||||||
|
|
||||||
|
// println!("flags: {:?}", x86::registers::flags::flags());
|
||||||
|
// flush!();
|
||||||
|
|
||||||
|
let sp = (::USER_STACK_OFFSET + ::USER_STACK_SIZE).as_u32();
|
||||||
|
// let sp: u32;
|
||||||
|
// unsafe {
|
||||||
|
// asm!("mov %ebp, $0" : "=r" (sp));
|
||||||
|
// }
|
||||||
|
let ip = self::init as *const () as u32;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
arch::x86::usermode(ip, sp, 0);
|
||||||
|
}
|
||||||
|
unreachable!()
|
||||||
|
// loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
println!("inside init function!!!!!");
|
||||||
|
flush!();
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use multiboot2;
|
||||||
use x86::structures::paging::*;
|
use x86::structures::paging::*;
|
||||||
use arch::x86::paging::ActivePageTable;
|
use arch::x86::paging::ActivePageTable;
|
||||||
use x86::*;
|
use x86::*;
|
||||||
// use spin::Mutex;
|
|
||||||
|
|
||||||
use self::bump::BumpFrameAllocator;
|
use self::bump::BumpFrameAllocator;
|
||||||
use self::recycle::RecycleAllocator;
|
use self::recycle::RecycleAllocator;
|
||||||
|
|
@ -19,7 +18,7 @@ pub trait FrameAllocator {
|
||||||
|
|
||||||
pub struct MemoryControler {
|
pub struct MemoryControler {
|
||||||
frame_allocator: RecycleAllocator<BumpFrameAllocator>,
|
frame_allocator: RecycleAllocator<BumpFrameAllocator>,
|
||||||
stack_allocator: StackAllocator,
|
// stack_allocator: StackAllocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut MEMORY_CONTROLER: Option<MemoryControler> = None;
|
static mut MEMORY_CONTROLER: Option<MemoryControler> = None;
|
||||||
|
|
@ -51,21 +50,12 @@ pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
);
|
);
|
||||||
|
|
||||||
let frame_allocator = RecycleAllocator::new(bump_allocator);
|
let frame_allocator = RecycleAllocator::new(bump_allocator);
|
||||||
|
// let stack_allocator = StackAllocator::new(::USER_STACK_RANGE);
|
||||||
let heap_end_page =
|
|
||||||
Page::containing_address(VirtAddr::new(::KERNEL_HEAP_OFFSET + ::KERNEL_HEAP_SIZE - 1));
|
|
||||||
|
|
||||||
let stack_allocator = {
|
|
||||||
let stack_alloc_start = heap_end_page + 1;
|
|
||||||
let stack_alloc_end = stack_alloc_start + 100;
|
|
||||||
let stack_alloc_range = stack_alloc_start..stack_alloc_end + 1;
|
|
||||||
StackAllocator::new(stack_alloc_range)
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
MEMORY_CONTROLER = Some(MemoryControler {
|
MEMORY_CONTROLER = Some(MemoryControler {
|
||||||
frame_allocator,
|
frame_allocator,
|
||||||
stack_allocator,
|
// stack_allocator,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,17 +80,17 @@ pub fn deallocate_frames(frame: PhysFrame, count: usize) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate_stack(mut active_table: &mut ActivePageTable) -> Option<Stack> {
|
// pub fn allocate_stack(mut active_table: &mut ActivePageTable) -> Option<Stack> {
|
||||||
unsafe {
|
// unsafe {
|
||||||
if let Some(ref mut controler) = MEMORY_CONTROLER {
|
// if let Some(ref mut controler) = MEMORY_CONTROLER {
|
||||||
controler
|
// controler
|
||||||
.stack_allocator
|
// .stack_allocator
|
||||||
.allocate_stack(&mut active_table, 4)
|
// .allocate_stack(&mut active_table, 4)
|
||||||
} else {
|
// } else {
|
||||||
panic!("frame allocator not initialized!");
|
// panic!("frame allocator not initialized!");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Init memory module after core
|
/// Init memory module after core
|
||||||
/// Must be called once, and only once,
|
/// Must be called once, and only once,
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 73a83239073de4acb5b18bacad049553a086ce3f
|
Subproject commit 3a6ff64c5fb9a4bdeb8b6b4c83328278c551dbad
|
||||||
Loading…
Reference in a new issue