aboutsummaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorAleksa Vuckovic <aleksa@vuckovic.cc>2023-12-13 01:38:14 +0100
committerAleksa Vuckovic <aleksa@vuckovic.cc>2024-04-02 23:17:31 +0200
commit36137438446c1754a522c5b3cc3aff92c43ac1ee (patch)
treef7358ef0aec7023321e52e116f94fba95e52611f /src/arch/x86
Initial commitHEADmaster
X86/X86_64 debug/release WORKING riscv64 WORKING uart idk
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/boot/boot.S126
-rw-r--r--src/arch/x86/common/boot/mod.rs2
-rw-r--r--src/arch/x86/common/boot/multiboot.S11
-rw-r--r--src/arch/x86/common/boot/multiboot.rs79
-rw-r--r--src/arch/x86/common/boot/multiboot2.S42
-rw-r--r--src/arch/x86/common/forall.rs5
-rw-r--r--src/arch/x86/common/io/mod.rs2
-rw-r--r--src/arch/x86/common/io/writer.rs72
-rw-r--r--src/arch/x86/common/mod.rs8
-rw-r--r--src/arch/x86/mod.rs10
-rw-r--r--src/arch/x86/once.rs6
11 files changed, 363 insertions, 0 deletions
diff --git a/src/arch/x86/boot/boot.S b/src/arch/x86/boot/boot.S
new file mode 100644
index 0000000..02f6e91
--- /dev/null
+++ b/src/arch/x86/boot/boot.S
@@ -0,0 +1,126 @@
+.section .bootstrap_stack, "aw", @nobits
+stack_bottom:
+.skip 16384
+stack_top:
+
+.section .bss, "aw", @nobits
+ .align 4096
+page_directory:
+ .skip 4096
+page_table1:
+ .skip 4096
+page_table2:
+ .skip 4096
+
+
+.set P, 1<<0
+.set RW, 1<<1
+.set FLAGS, P | RW
+.set KERNEL_VM, 0xC0000000
+
+
+.section .multiboot.text, "a"
+.global _start
+.type _start, @function
+_start:
+_start:
+ cli
+ mov $stack_top - KERNEL_VM, %esp
+ pushl %eax
+ pushl %ebx
+
+ movl $page_table1 - KERNEL_VM + FLAGS, page_directory - KERNEL_VM + 0 * 4
+ movl $page_table2 - KERNEL_VM + FLAGS, page_directory - KERNEL_VM + 1 * 4
+ movl $page_table1 - KERNEL_VM + FLAGS, page_directory - KERNEL_VM + 768 * 4
+ movl $page_table2 - KERNEL_VM + FLAGS, page_directory - KERNEL_VM + 769 * 4
+
+ mov $0, %ecx
+not_done:
+ mov $0x1000, %eax
+ mul %ecx
+ orl $FLAGS, %eax
+ mov %eax, %edi
+
+ // page_table1[%ecx] = 0x1000 * %ecx | 0x3
+ mov $4, %eax
+ mul %ecx
+ add $page_table1 - KERNEL_VM, %eax
+ movl %edi, (%eax)
+
+ // page_table2[%ecx] = 0x1000 * %ecx | 0x3
+ mov $4, %eax
+ mul %ecx
+ add $1024 * 0x1000, %edi
+ add $page_table2 - KERNEL_VM, %eax
+ movl %edi, (%eax)
+
+ inc %ecx
+ cmp $1024, %ecx
+ je done
+ jmp not_done
+done:
+
+ movl $(page_directory - KERNEL_VM), %ecx
+ movl %ecx, %cr3
+
+ movl %cr0, %ecx
+ orl $0x80001000, %ecx
+ movl %ecx, %cr0
+
+ lea 7f, %ecx
+ jmp *%ecx
+
+
+.section .boot32.rodata
+
+gdt:
+gdt_null = . - gdt
+ .quad 0
+kernel_code = . - gdt
+ .long 0xFFFF
+ .byte 0
+ .byte 0x9A
+ .byte 0xCF
+ .byte 0
+kernel_data = . - gdt
+ .long 0xFFFF
+ .byte 0
+ .byte 0x92
+ .byte 0xCF
+ .byte 0
+user_code = . - gdt
+ .long 0xFFFF
+ .byte 0
+ .byte 0xFA
+ .byte 0xCF
+ .byte 0
+user_data = . - gdt
+ .long 0xFFFF
+ .byte 0
+ .byte 0xF2
+ .byte 0xCF
+ .byte 0
+
+.global gdtp
+gdtp:
+ .word . - gdt - 1
+ .long gdt
+
+
+.section .text
+
+7:
+ addl $KERNEL_VM, %esp
+ lgdtl gdtp
+ ljmp $0x08, $code
+
+code:
+ movw $0x10, %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ movw %ax, %ss
+
+ call kernel_main
+ hlt
diff --git a/src/arch/x86/common/boot/mod.rs b/src/arch/x86/common/boot/mod.rs
new file mode 100644
index 0000000..b6aebe5
--- /dev/null
+++ b/src/arch/x86/common/boot/mod.rs
@@ -0,0 +1,2 @@
+mod multiboot;
+pub use multiboot::*;
diff --git a/src/arch/x86/common/boot/multiboot.S b/src/arch/x86/common/boot/multiboot.S
new file mode 100644
index 0000000..8773b1f
--- /dev/null
+++ b/src/arch/x86/common/boot/multiboot.S
@@ -0,0 +1,11 @@
+.set ALIGN, 1<<0
+.set MEMINFO, 1<<1
+.set FLAGS, ALIGN | MEMINFO
+.set MAGIC, 0x1BADB002
+.set CHECKSUM, -(MAGIC + FLAGS)
+
+.section .multiboot.header, "aw"
+.align 4
+.long MAGIC
+.long FLAGS
+.long CHECKSUM
diff --git a/src/arch/x86/common/boot/multiboot.rs b/src/arch/x86/common/boot/multiboot.rs
new file mode 100644
index 0000000..09789ce
--- /dev/null
+++ b/src/arch/x86/common/boot/multiboot.rs
@@ -0,0 +1,79 @@
+pub const MULTIBOOT2_BOOTLOADER_MAGIC: u32 = 0x36d76289;
+pub const MULTIBOOT_TAG_TYPE_END: u32 = 0;
+pub const MULTIBOOT_TAG_TYPE_MMAP: u32 = 6;
+pub const MULTIBOOT_TAG_TYPE_FB: u32 = 8;
+
+use crate::{print, println};
+
+pub fn parse_fb_multiboot(mut mem: *mut u32) {
+ let framebuffer_addr: u64 = unsafe { *(mem as *mut u64) };
+ let framebuffer_pitch: u32 = unsafe { *mem.wrapping_add(2) };
+ let framebuffer_width: u32 = unsafe { *mem.wrapping_add(3) };
+ let framebuffer_height: u32 = unsafe { *mem.wrapping_add(4) };
+ let framebuffer_bpp: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8) };
+ let framebuffer_type: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) };
+ let reserved: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) };
+
+ println!(
+ "0x{:x} {:x} {:x} {:x}",
+ framebuffer_addr, framebuffer_pitch, framebuffer_width, framebuffer_height
+ );
+}
+
+pub fn parse_mem_multiboot(mut mem: *mut u32, _size: u32) {
+ let mut curr_size: u32 = 16;
+
+ while curr_size < _size {
+ let base_addr: u64 = unsafe { *(mem as *mut u64) };
+ let length: u64 = unsafe { *(mem.wrapping_add(2) as *mut u64) };
+ let _type: u32 = unsafe { *mem.wrapping_add(4) };
+ let reserved: u32 = unsafe { *mem.wrapping_add(5) };
+ assert_eq!(reserved, 0, "reserved not 0");
+
+ //println!("{:x} {:x} {:x}", base_addr, length, _type);
+
+ mem = mem.wrapping_add(6);
+ curr_size += 24;
+ }
+}
+
+pub fn parse_multiboot(mut multiboot_bootinfo: *mut u32, multiboot_magic: u32) {
+ assert_eq!(
+ multiboot_magic, MULTIBOOT2_BOOTLOADER_MAGIC,
+ "MULTIBOOT2_BOOTLOADER_MAGIC"
+ );
+
+ let total_size: u32 = unsafe { *multiboot_bootinfo };
+ let mut size = 8;
+ multiboot_bootinfo = multiboot_bootinfo.wrapping_add(2);
+
+ while size < total_size {
+ let _type: u32 = unsafe { *multiboot_bootinfo };
+ let _size: u32 = unsafe { *(multiboot_bootinfo.wrapping_add(1)) };
+ let mem: *mut u32 = multiboot_bootinfo.wrapping_add(4);
+ let mem2: *mut u32 = multiboot_bootinfo.wrapping_add(2);
+
+ match _type {
+ MULTIBOOT_TAG_TYPE_FB => {
+ parse_fb_multiboot(mem2);
+ }
+ MULTIBOOT_TAG_TYPE_MMAP => {
+ parse_mem_multiboot(mem, _size);
+ }
+ _ => {}
+ }
+
+ let inc_size = (_size / 8 + (_size % 8 != 0) as u32) * 8;
+ size += inc_size;
+
+ println!("{} {} {}", _type, _size, inc_size);
+ multiboot_bootinfo = multiboot_bootinfo.wrapping_add((inc_size / 4).try_into().unwrap());
+
+ if _type == MULTIBOOT_TAG_TYPE_END {
+ assert_eq!(_size, 8, "MULTIBOOT_TAG_TYPE_END");
+ break;
+ }
+ }
+
+ assert_eq!(total_size, size, "Multiboot");
+}
diff --git a/src/arch/x86/common/boot/multiboot2.S b/src/arch/x86/common/boot/multiboot2.S
new file mode 100644
index 0000000..d767ca0
--- /dev/null
+++ b/src/arch/x86/common/boot/multiboot2.S
@@ -0,0 +1,42 @@
+/* multiboot tags */
+.set TAG_END, 0
+.set TAG_FRAMEBUFFER, 5
+
+/* multiboot flags */
+.set TAG_REQUIRED, 0
+.set TAG_OPTIONAL, 1
+
+/* multiboot2 header constants */
+.set MAGIC, 0xe85250d6
+.set ARCH, 0
+.set HEADER_LENGTH, (header_end - header_start)
+.set CHECKSUM, 0x100000000 - (MAGIC + ARCH + HEADER_LENGTH)
+
+.section .multiboot2.header, "a"
+.align 4
+header_start:
+ /* magic */
+ .align 8
+ .long MAGIC
+ .long ARCH
+ .long HEADER_LENGTH
+ .long CHECKSUM
+
+/*
+ // framebuffer
+ .align 8
+ .word TAG_FRAMEBUFFER
+ .word TAG_REQUIRED
+ .long 20
+ .long 1024
+ .long 768
+ .long 32
+*/
+
+ /* end tag */
+ .align 8
+ .word TAG_END
+ .word TAG_REQUIRED
+ .long 8
+
+header_end:
diff --git a/src/arch/x86/common/forall.rs b/src/arch/x86/common/forall.rs
new file mode 100644
index 0000000..39988e6
--- /dev/null
+++ b/src/arch/x86/common/forall.rs
@@ -0,0 +1,5 @@
+use crate::{print, println};
+
+pub fn forall() {
+ println!("forall");
+}
diff --git a/src/arch/x86/common/io/mod.rs b/src/arch/x86/common/io/mod.rs
new file mode 100644
index 0000000..604e84c
--- /dev/null
+++ b/src/arch/x86/common/io/mod.rs
@@ -0,0 +1,2 @@
+mod writer;
+pub use writer::*;
diff --git a/src/arch/x86/common/io/writer.rs b/src/arch/x86/common/io/writer.rs
new file mode 100644
index 0000000..7361693
--- /dev/null
+++ b/src/arch/x86/common/io/writer.rs
@@ -0,0 +1,72 @@
+use core::fmt;
+use core::fmt::Write;
+use lazy_static::lazy_static;
+use spin::Mutex;
+
+#[doc(hidden)]
+pub fn _print(args: fmt::Arguments) {
+ WRITER.lock().write_fmt(args).unwrap();
+}
+
+lazy_static! {
+ pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer::new());
+}
+
+#[derive(Default)]
+pub struct Writer {
+ max_y: isize,
+ max_x: isize,
+ x: isize,
+ y: isize,
+ addr: u32,
+}
+
+impl Writer {
+ pub fn new() -> Self {
+ Self {
+ x: 0,
+ y: 0,
+ max_y: 25,
+ max_x: 80,
+ addr: 0xb8000,
+ }
+ }
+
+ pub fn write(&mut self, c: char, b: u8) {
+ let off: isize = self.y * self.max_x + self.x;
+ let vga_buffer = self.addr as *mut u8;
+
+ if c != '\n' {
+ unsafe {
+ *vga_buffer.offset(2 * off) = c as u8;
+ *vga_buffer.offset(2 * off + 1) = b;
+ }
+ self.x += 1;
+ } else {
+ self.x = 0;
+ self.y += 1;
+ }
+
+ if self.x >= self.max_x {
+ self.x = 0;
+ self.y += 1;
+ }
+
+ if self.y >= self.max_y {
+ self.y = 0;
+ }
+ }
+
+ pub fn print(&mut self, s: &str, b: u8) {
+ for i in s.chars() {
+ self.write(i, b);
+ }
+ }
+}
+
+impl fmt::Write for Writer {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ self.print(s, 0xb);
+ Ok(())
+ }
+}
diff --git a/src/arch/x86/common/mod.rs b/src/arch/x86/common/mod.rs
new file mode 100644
index 0000000..d1d4d98
--- /dev/null
+++ b/src/arch/x86/common/mod.rs
@@ -0,0 +1,8 @@
+mod forall;
+pub use forall::*;
+
+mod io;
+pub use io::*;
+
+mod boot;
+pub use boot::*;
diff --git a/src/arch/x86/mod.rs b/src/arch/x86/mod.rs
new file mode 100644
index 0000000..c47ad74
--- /dev/null
+++ b/src/arch/x86/mod.rs
@@ -0,0 +1,10 @@
+#[cfg(target_arch = "x86")]
+mod common;
+#[cfg(target_arch = "x86")]
+pub use common::*;
+
+#[cfg(target_arch = "x86_64")]
+pub mod common;
+
+mod once;
+pub use once::*;
diff --git a/src/arch/x86/once.rs b/src/arch/x86/once.rs
new file mode 100644
index 0000000..9397afb
--- /dev/null
+++ b/src/arch/x86/once.rs
@@ -0,0 +1,6 @@
+use crate::{print, println};
+
+pub fn once()
+{
+ println!("x86");
+}