Compare commits

...

80 Commits

Author SHA1 Message Date
Philipp Oppermann
e3e8a3e112 Align the double fault stack through a new wrapper type 2020-02-19 10:27:26 +01:00
Philipp Oppermann
c211412ce2 Update Github Actions badge for post-06 2019-12-12 09:30:51 +01:00
Philipp Oppermann
93d3de6feb Merge branch 'post-05' into post-06 2019-12-12 09:30:37 +01:00
Philipp Oppermann
651c629ffd Merge branch 'post-05' into post-06 2019-12-12 09:23:30 +01:00
Philipp Oppermann
8d8a7e0973 Merge branch 'post-05' into post-06 2019-12-10 17:31:24 +01:00
Philipp Oppermann
423b6e49cc Merge pull request #702 from phil-opp/post-06-fix
Make double fault handlers diverging
2019-12-10 17:17:00 +01:00
Philipp Oppermann
d1cf8000a3 Make double fault handlers diverging
Required by x86_64 0.8.0.
2019-12-10 17:02:46 +01:00
Philipp Oppermann
16c499f966 Merge branch 'post-05' into post-06 2019-12-10 16:55:41 +01:00
Philipp Oppermann
9d6ba0d31e Merge branch 'post-05' into post-06 2019-11-28 14:06:28 +01:00
Philipp Oppermann
590585da33 Merge branch 'post-05' into post-06 2019-11-25 13:24:09 +01:00
Philipp Oppermann
a604e1fa14 Merge branch 'post-06' of github.com:phil-opp/blog_os into post-06 2019-11-22 16:04:09 +01:00
Philipp Oppermann
05c3a17c49 Merge branch 'post-05' into post-06 2019-11-22 15:57:18 +01:00
Philipp Oppermann
3470636653 Use panic! instead of println! + loop in double fault handler (#687)
This avoids an endless loop when a double fault occurs while running `cargo xtest`.
2019-11-22 15:56:56 +01:00
Philipp Oppermann
1a1ce5120f Merge branch 'post-05' into post-06 2019-10-08 19:44:38 +02:00
Philipp Oppermann
78fdba7606 Merge branch 'post-05' into post-06 2019-09-25 13:20:13 +02:00
Philipp Oppermann
8d6915beba Merge branch 'post-05' into post-06 2019-09-13 17:43:25 +02:00
Philipp Oppermann
0eaaa3ff2b Merge branch 'post-05' into post-06 2019-09-13 10:53:50 +02:00
Philipp Oppermann
086304c9c4 Merge branch 'post-05' into post-06 2019-09-11 13:18:19 +02:00
Philipp Oppermann
2e27b91220 Merge branch 'post-05' into post-06 2019-09-11 11:21:15 +02:00
Philipp Oppermann
cb77074476 Merge branch 'post-05' into post-06 2019-09-11 10:58:02 +02:00
Philipp Oppermann
d0afb95b50 Merge branch 'post-05' into post-06 2019-09-11 10:32:57 +02:00
Philipp Oppermann
1b0378f87e Merge branch 'post-05' into post-06 2019-09-11 10:12:46 +02:00
Philipp Oppermann
b91f71784d Merge branch 'post-05' into post-06 2019-09-11 10:11:25 +02:00
Philipp Oppermann
6316a0e1df Merge branch 'post-05' into post-06 2019-09-11 10:02:41 +02:00
Philipp Oppermann
38cfb5e324 Merge branch 'post-05' into post-06 2019-09-10 11:12:54 +02:00
Philipp Oppermann
a9921e9448 Merge branch 'post-05' into post-06 2019-09-10 10:21:14 +02:00
Philipp Oppermann
9770d481f2 Merge branch 'post-05' into post-06 2019-08-07 12:40:04 +02:00
Philipp Oppermann
7baa3b0155 Merge branch 'post-05' into post-06 2019-07-22 10:36:23 +02:00
Philipp Oppermann
08bf4405a9 Merge branch 'post-05' into post-06 2019-07-18 10:17:05 +02:00
Philipp Oppermann
9d5b5f33f1 Merge branch 'post-05' into post-06 2019-06-23 18:07:34 +02:00
Philipp Oppermann
9b4b810bd3 Merge branch 'post-05' into post-06 2019-06-17 17:28:32 +02:00
Philipp Oppermann
7a45083975 Merge branch 'post-05' into post-06 2019-05-23 12:39:35 +02:00
Philipp Oppermann
01040fc643 Merge branch 'post-05' into post-06 2019-05-09 14:59:55 +02:00
Philipp Oppermann
5a68816b45 Merge branch 'post-05' into post-06 2019-05-03 18:36:45 +02:00
Philipp Oppermann
111c3e1029 Comment out stack_overflow() call to keep cargo xtest working 2019-04-26 15:48:59 +02:00
Philipp Oppermann
70d981e179 Simplify stack_overflow test 2019-04-26 15:14:38 +02:00
Philipp Oppermann
ee3d2219ab Disable test harness for stack_overflow test 2019-04-26 15:14:38 +02:00
Philipp Oppermann
c5a39e0902 Add a stack overflow integration test 2019-04-26 15:14:38 +02:00
Philipp Oppermann
4774893a93 Call gdt::init from blog_os::init 2019-04-26 15:14:38 +02:00
Philipp Oppermann
3c59321b54 Remove old bootimage test integration test 2019-04-26 15:14:38 +02:00
Philipp Oppermann
f5345db3e6 Update post number for Readme badge 2019-04-26 15:11:49 +02:00
Philipp Oppermann
94622ebfd5 Merge branch 'post-05-new' into post-06-new-rebased 2019-04-26 15:11:24 +02:00
Philipp Oppermann
82014268da Merge branch 'post-05-new' into post-06-new-rebased 2019-04-26 15:05:55 +02:00
Philipp Oppermann
e0d68fee24 Merge branch 'post-06' into post-07 2019-04-25 11:08:11 +02:00
Philipp Oppermann
6f623dc7b4 Merge branch 'post-06' into post-07 2019-04-11 15:32:21 +02:00
Philipp Oppermann
dc1f862177 Merge branch 'post-06' into post-07 2019-04-06 17:35:17 +02:00
Philipp Oppermann
fdf0fe617b Merge branch 'post-06' into post-07 2019-04-06 17:31:13 +02:00
Philipp Oppermann
23fcb9f20b Merge branch 'post-06' into post-07 2019-04-06 16:49:01 +02:00
Philipp Oppermann
ffb76038bc Merge branch 'post-06' into post-07
# Conflicts:
#	README.md
2019-04-03 10:46:46 +02:00
Philipp Oppermann
f42461b99b Merge branch 'post-06' into post-07 2019-03-26 13:26:56 +01:00
Philipp Oppermann
701823742e Merge branch 'post-06' into post-07 2019-03-14 11:18:22 +01:00
Philipp Oppermann
b533bf6596 Merge branch 'post-06' into post-07 2019-03-12 17:48:11 +01:00
Philipp Oppermann
1ed76411f7 Fix remaining use of ExceptionStackFrame in test 2019-03-09 14:21:03 +01:00
Philipp Oppermann
8e5b6a3e3f Update post-07 code for changes in x86_64 0.5.0 2019-03-09 12:34:49 +01:00
Philipp Oppermann
be0ed3a54d Merge branch 'post-06' into post-07 2019-03-09 12:32:03 +01:00
Philipp Oppermann
f5b6094521 Merge branch 'post-06' into post-07 2019-02-25 16:37:30 +01:00
Philipp Oppermann
38bd9a65b6 Merge branch 'post-06' into post-07 2019-02-07 18:46:32 +01:00
Philipp Oppermann
b3e94470e4 Merge branch 'post-06' into post-07 2019-02-07 16:15:10 +01:00
Philipp Oppermann
7b01e9c862 Merge branch 'post-06' into post-07 2019-02-05 15:23:49 +01:00
Philipp Oppermann
5452e0f455 Merge branch 'post-06' into post-07 2019-02-05 14:59:15 +01:00
Philipp Oppermann
202902f30d Merge branch 'post-06' into post-07 2019-02-05 10:46:08 +01:00
Philipp Oppermann
3bb30fd1e8 Merge branch 'post-06' into post-07 2019-02-05 10:45:12 +01:00
Philipp Oppermann
41e36b4afa Merge branch 'post-06' into post-07 2019-01-29 12:16:54 +01:00
Philipp Oppermann
f76ec1ae32 Only set double fault handler once 2019-01-28 11:50:59 +01:00
Philipp Oppermann
efe92e5004 Merge branch 'post-06' into post-07 2019-01-28 11:44:14 +01:00
Philipp Oppermann
233943310c Update Readme for Double Faults post 2019-01-27 17:12:21 +01:00
Philipp Oppermann
ef6d69f82b Merge branch 'post-06' into post-07 2019-01-27 17:11:38 +01:00
Philipp Oppermann
637b517f47 Merge branch 'post-06' into post-07 2019-01-27 16:33:54 +01:00
Philipp Oppermann
5802c97938 Merge branch 'z_post_06' into z_post_07 2019-01-27 15:46:59 +01:00
Philipp Oppermann
29ee6b15dd Merge branch 'z_post_06' into z_post_07 2019-01-27 14:28:55 +01:00
Philipp Oppermann
90ad333e90 Merge branch 'z_post_06' into z_post_07 2019-01-25 14:46:29 +01:00
Philipp Oppermann
afe8dc3dcf Add stack overflow integration test 2019-01-25 14:45:02 +01:00
Philipp Oppermann
8bb0187f35 Run rustfmt 2019-01-25 14:44:42 +01:00
Philipp Oppermann
d8edfccca4 Set the stack_index for the double fault handler 2019-01-25 14:01:29 +01:00
Philipp Oppermann
ff25a7d86c Reload code and TSS selector registers 2019-01-25 13:59:09 +01:00
Philipp Oppermann
b5202e26a1 Load the GDT 2019-01-25 13:57:40 +01:00
Philipp Oppermann
ea1b031fd3 Create a static GDT 2019-01-25 13:57:08 +01:00
Philipp Oppermann
db4e879c34 Create a new GDT module and a static TSS 2019-01-25 13:56:40 +01:00
Philipp Oppermann
7fd29c9cbe Trigger a double fault through a stack overflow -> triple fault 2019-01-25 13:55:42 +01:00
Philipp Oppermann
218cb9399e Add a double fault handler and test it 2019-01-25 13:54:44 +01:00
7 changed files with 142 additions and 7 deletions

View File

@@ -8,6 +8,10 @@ edition = "2018"
name = "should_panic" name = "should_panic"
harness = false harness = false
[[test]]
name = "stack_overflow"
harness = false
[dependencies] [dependencies]
bootloader = "0.8.0" bootloader = "0.8.0"
volatile = "0.2.6" volatile = "0.2.6"

View File

@@ -1,10 +1,10 @@
# Blog OS (CPU Exceptions) # Blog OS (Double Faults)
[![Build Status](https://github.com/phil-opp/blog_os/workflows/Build%20Code/badge.svg?branch=post-05)](https://github.com/phil-opp/blog_os/actions?query=workflow%3A%22Build+Code%22+branch%3Apost-05) [![Build Status](https://github.com/phil-opp/blog_os/workflows/Build%20Code/badge.svg?branch=post-06)](https://github.com/phil-opp/blog_os/actions?query=workflow%3A%22Build+Code%22+branch%3Apost-06)
This repository contains the source code for the [CPU Exceptions][post] post of the [Writing an OS in Rust](https://os.phil-opp.com) series. This repository contains the source code for the [Double Faults][post] post of the [Writing an OS in Rust](https://os.phil-opp.com) series.
[post]: https://os.phil-opp.com/cpu-exceptions/ [post]: https://os.phil-opp.com/double-fault-exceptions/
**Check out the [master branch](https://github.com/phil-opp/blog_os) for more information.** **Check out the [master branch](https://github.com/phil-opp/blog_os) for more information.**

56
src/gdt.rs Normal file
View File

@@ -0,0 +1,56 @@
use lazy_static::lazy_static;
use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
use x86_64::structures::tss::TaskStateSegment;
use x86_64::VirtAddr;
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;
lazy_static! {
static ref TSS: TaskStateSegment = {
let mut tss = TaskStateSegment::new();
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
const STACK_SIZE: usize = 4096;
#[repr(align(16))]
struct Stack([u8; STACK_SIZE]);
static mut STACK: Stack = Stack([0; STACK_SIZE]);
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
let stack_end = stack_start + STACK_SIZE;
stack_end
};
tss
};
}
lazy_static! {
static ref GDT: (GlobalDescriptorTable, Selectors) = {
let mut gdt = GlobalDescriptorTable::new();
let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
(
gdt,
Selectors {
code_selector,
tss_selector,
},
)
};
}
struct Selectors {
code_selector: SegmentSelector,
tss_selector: SegmentSelector,
}
pub fn init() {
use x86_64::instructions::segmentation::set_cs;
use x86_64::instructions::tables::load_tss;
GDT.0.load();
unsafe {
set_cs(GDT.1.code_selector);
load_tss(GDT.1.tss_selector);
}
}

View File

@@ -1,4 +1,4 @@
use crate::println; use crate::{gdt, println};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
@@ -6,6 +6,11 @@ lazy_static! {
static ref IDT: InterruptDescriptorTable = { static ref IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new(); let mut idt = InterruptDescriptorTable::new();
idt.breakpoint.set_handler_fn(breakpoint_handler); idt.breakpoint.set_handler_fn(breakpoint_handler);
unsafe {
idt.double_fault
.set_handler_fn(double_fault_handler)
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
}
idt idt
}; };
} }
@@ -18,6 +23,13 @@ extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFra
println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
} }
extern "x86-interrupt" fn double_fault_handler(
stack_frame: &mut InterruptStackFrame,
_error_code: u64,
) -> ! {
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
}
#[cfg(test)] #[cfg(test)]
use crate::{serial_print, serial_println}; use crate::{serial_print, serial_println};

View File

@@ -7,11 +7,13 @@
use core::panic::PanicInfo; use core::panic::PanicInfo;
pub mod gdt;
pub mod interrupts; pub mod interrupts;
pub mod serial; pub mod serial;
pub mod vga_buffer; pub mod vga_buffer;
pub fn init() { pub fn init() {
gdt::init();
interrupts::init_idt(); interrupts::init_idt();
} }

View File

@@ -13,8 +13,12 @@ pub extern "C" fn _start() -> ! {
blog_os::init(); blog_os::init();
// invoke a breakpoint exception fn stack_overflow() {
x86_64::instructions::interrupts::int3(); stack_overflow(); // for each recursion, the return address is pushed
}
// uncomment line below to trigger a stack overflow
// stack_overflow();
#[cfg(test)] #[cfg(test)]
test_main(); test_main();

57
tests/stack_overflow.rs Normal file
View File

@@ -0,0 +1,57 @@
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode};
use core::panic::PanicInfo;
use lazy_static::lazy_static;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
#[no_mangle]
pub extern "C" fn _start() -> ! {
serial_print!("stack_overflow... ");
blog_os::gdt::init();
init_test_idt();
// trigger a stack overflow
stack_overflow();
panic!("Execution continued after stack overflow");
}
#[allow(unconditional_recursion)]
fn stack_overflow() {
stack_overflow(); // for each recursion, the return address is pushed
}
lazy_static! {
static ref TEST_IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new();
unsafe {
idt.double_fault
.set_handler_fn(test_double_fault_handler)
.set_stack_index(blog_os::gdt::DOUBLE_FAULT_IST_INDEX);
}
idt
};
}
pub fn init_test_idt() {
TEST_IDT.load();
}
extern "x86-interrupt" fn test_double_fault_handler(
_stack_frame: &mut InterruptStackFrame,
_error_code: u64,
) -> ! {
serial_println!("[ok]");
exit_qemu(QemuExitCode::Success);
loop {}
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
blog_os::test_panic_handler(info)
}