fixed the interrupts issue
This commit is contained in:
+3
-1
@@ -20,7 +20,9 @@ pub extern "C" fn kmain() -> ! {
|
|||||||
GoofyAhhOS::init();
|
GoofyAhhOS::init();
|
||||||
|
|
||||||
println!("Hello from GoofyAhhOS!");
|
println!("Hello from GoofyAhhOS!");
|
||||||
serial_println!("SERIAL OUT ACHIEVED :check:");
|
// serial_println!("SERIAL OUT ACHIEVED :check:");
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let input: &str = serial_read();
|
let input: &str = serial_read();
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// use core::arch::x86_64::__cpuid;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// static IA32_APIC_BASE_MSR: u32 = 0x1b;
|
||||||
|
// static IA32_APIC_BASE_MSR_BSP: u32 = 0x100;
|
||||||
|
// static IA32_APIC_BASE_MSR_ENABLE: u32 = 0x800;
|
||||||
|
|
||||||
|
// fn check_apic() -> bool {
|
||||||
|
// let edx = unsafe {
|
||||||
|
// __cpuid(1,)
|
||||||
|
// }.edx;
|
||||||
|
// return edx & CPU_ID_FEAT_EDX_APIC != 0
|
||||||
|
// }
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use x86_64::{
|
use x86_64::{
|
||||||
instructions::tables::load_tss, registers::segmentation::{Segment, CS}, structures::{
|
instructions::tables::load_tss, registers::segmentation::{Segment, CS, DS, ES, SS}, structures::{
|
||||||
gdt::{
|
gdt::{
|
||||||
Descriptor, GlobalDescriptorTable, SegmentSelector
|
Descriptor, GlobalDescriptorTable, SegmentSelector
|
||||||
},
|
},
|
||||||
@@ -17,7 +17,7 @@ lazy_static! {
|
|||||||
static ref TSS: TaskStateSegment = {
|
static ref TSS: TaskStateSegment = {
|
||||||
let mut tss = TaskStateSegment::new();
|
let mut tss = TaskStateSegment::new();
|
||||||
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
|
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
|
||||||
const STACK_SIZE: usize = 4096 * 5;
|
const STACK_SIZE: usize = 4096 * 8;
|
||||||
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
|
||||||
|
|
||||||
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
|
||||||
@@ -30,16 +30,36 @@ lazy_static! {
|
|||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref GDT: (GlobalDescriptorTable, Selectors) = {
|
static ref GDT: (GlobalDescriptorTable, Selectors) = {
|
||||||
|
x86_64::instructions::interrupts::disable();
|
||||||
let mut gdt = GlobalDescriptorTable::new();
|
let mut gdt = GlobalDescriptorTable::new();
|
||||||
|
// Kernel code segment
|
||||||
let code_selector = gdt.append(Descriptor::kernel_code_segment());
|
let code_selector = gdt.append(Descriptor::kernel_code_segment());
|
||||||
|
// Kernel data segment (needed for proper interrupt handling)
|
||||||
|
let data_selector = gdt.append(Descriptor::kernel_data_segment());
|
||||||
|
// User segments (even if not used, helps with some hardware)
|
||||||
|
let user_data_selector = gdt.append(Descriptor::user_data_segment());
|
||||||
|
let user_code_selector = gdt.append(Descriptor::user_code_segment());
|
||||||
|
// TSS segment for interrupt stack switching
|
||||||
let tss_selector = gdt.append(Descriptor::tss_segment(&TSS));
|
let tss_selector = gdt.append(Descriptor::tss_segment(&TSS));
|
||||||
(gdt, Selectors { code_selector, tss_selector })
|
(
|
||||||
|
gdt,
|
||||||
|
Selectors {
|
||||||
|
code_selector,
|
||||||
|
data_selector,
|
||||||
|
// user_code_selector,
|
||||||
|
// user_data_selector,
|
||||||
|
tss_selector,
|
||||||
|
}
|
||||||
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Selectors {
|
struct Selectors {
|
||||||
code_selector: SegmentSelector,
|
code_selector: SegmentSelector,
|
||||||
tss_selector: SegmentSelector
|
data_selector: SegmentSelector,
|
||||||
|
// user_code_selector: SegmentSelector,
|
||||||
|
// user_data_selector: SegmentSelector,
|
||||||
|
tss_selector: SegmentSelector,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
@@ -47,8 +67,13 @@ pub fn init() {
|
|||||||
println_log!("Loaded GDT...");
|
println_log!("Loaded GDT...");
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// Load the segment selectors
|
||||||
CS::set_reg(GDT.1.code_selector);
|
CS::set_reg(GDT.1.code_selector);
|
||||||
load_tss(GDT.1.tss_selector);
|
load_tss(GDT.1.tss_selector);
|
||||||
|
|
||||||
|
// // Set up data segments
|
||||||
|
// DS::set_reg(GDT.1.data_selector);
|
||||||
|
// ES::set_reg(GDT.1.data_selector);
|
||||||
|
SS::set_reg(GDT.1.data_selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ use core::arch::asm;
|
|||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use spin::lazy;
|
use spin::lazy;
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
use x86_64::{instructions::{self, hlt, interrupts}, structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}};
|
||||||
|
|
||||||
use crate::{println_log, serial_println, sys::kernel::cpu::gdt};
|
use crate::{println_log, serial_println, sys::kernel::cpu::gdt};
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@ pub static PICS: spin::Mutex<ChainedPics> = spin::Mutex::new(
|
|||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum InterruptIndex {
|
pub enum InterruptIndex {
|
||||||
Timer = PIC_1_OFFSET,
|
Timer = PIC_1_OFFSET,
|
||||||
|
Keyboard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InterruptIndex {
|
impl InterruptIndex {
|
||||||
@@ -39,6 +40,9 @@ 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);
|
||||||
|
idt.page_fault.set_handler_fn(page_fault_handler);
|
||||||
|
idt.general_protection_fault.set_handler_fn(general_protection_fault_handler);
|
||||||
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
idt.double_fault.set_handler_fn(double_fault_handler)
|
idt.double_fault.set_handler_fn(double_fault_handler)
|
||||||
@@ -46,6 +50,10 @@ lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
idt[InterruptIndex::Timer.as_u8()].set_handler_fn(timer_interrupt_handler);
|
idt[InterruptIndex::Timer.as_u8()].set_handler_fn(timer_interrupt_handler);
|
||||||
|
|
||||||
|
idt[InterruptIndex::Keyboard.as_u8()]
|
||||||
|
.set_handler_fn(keyboard_interrupt_handler);
|
||||||
|
|
||||||
idt
|
idt
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -56,33 +64,112 @@ pub fn init() {
|
|||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
PICS.lock().initialize();
|
PICS.lock().initialize();
|
||||||
|
PICS.lock().write_masks(0xfc, 0xff);
|
||||||
|
// println_log!("PIC initialized with masks: {:02x}, {:02x}",
|
||||||
|
// PICS.lock().read_masks()[0],
|
||||||
|
// PICS.lock().read_masks()[1]
|
||||||
|
// );
|
||||||
|
println_log!("weird");
|
||||||
}
|
}
|
||||||
|
|
||||||
x86_64::instructions::interrupts::enable();
|
unsafe { asm!("sti"); }
|
||||||
println_log!("Enabled interrupts...");
|
println_log!("Enabled interrupts...");
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn timer_interrupt_handler(stack_frame: InterruptStackFrame) {
|
extern "x86-interrupt" fn timer_interrupt_handler(stack_frame: InterruptStackFrame) {
|
||||||
serial_println!("clock");
|
without(|| {
|
||||||
println_log!("clock");
|
println_log!("Timer interrupt!");
|
||||||
|
});
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "x86-interrupt" fn general_protection_fault_handler(
|
||||||
|
stack_frame: InterruptStackFrame,
|
||||||
|
error_code: u64,
|
||||||
|
) {
|
||||||
|
without(|| {
|
||||||
|
// hlt();
|
||||||
|
|
||||||
|
let rsp: u64;
|
||||||
|
unsafe {
|
||||||
|
asm!("mov {}, rsp", out(reg) rsp);
|
||||||
|
}
|
||||||
|
serial_println!("EXCEPTION: GENERAL PROTECTION FAULT");
|
||||||
|
serial_println!("Error Code: {:#x}", error_code);
|
||||||
|
serial_println!("RSP: {:#x}", rsp);
|
||||||
|
serial_println!("Instruction Pointer: {:#x}", stack_frame.instruction_pointer.as_u64());
|
||||||
|
serial_println!("Stack Pointer: {:#x}", stack_frame.stack_pointer.as_u64());
|
||||||
|
serial_println!("CPU Flags: {:#x}", stack_frame.cpu_flags.bits());
|
||||||
|
serial_println!("Code Segment: {:?}", stack_frame.code_segment);
|
||||||
|
serial_println!("Stack Segment: {:?}", stack_frame.stack_segment);
|
||||||
|
});
|
||||||
|
|
||||||
|
panic!("EXCEPTION: GENERAL PROTECTION FAULT");
|
||||||
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
||||||
println_log!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
without(|| {
|
||||||
serial_println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
println_log!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
||||||
|
serial_println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);
|
||||||
|
});
|
||||||
|
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame, _error_code: u64) -> ! {
|
extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame, _error_code: u64) -> ! {
|
||||||
serial_println!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
without(|| {
|
||||||
|
serial_println!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
|
||||||
|
});
|
||||||
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame)
|
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable(func: impl Fn()) {
|
extern "x86-interrupt" fn page_fault_handler(
|
||||||
x86_64::instructions::interrupts::disable();
|
stack_frame: InterruptStackFrame,
|
||||||
func();
|
error_code: PageFaultErrorCode,
|
||||||
x86_64::instructions::interrupts::enable();
|
) {
|
||||||
|
use x86_64::registers::control::Cr2;
|
||||||
|
|
||||||
|
without(|| {
|
||||||
|
serial_println!("EXCEPTION: PAGE FAULT");
|
||||||
|
serial_println!("Accessed Address: {:?}", Cr2::read());
|
||||||
|
serial_println!("Error Code: {:?}", error_code);
|
||||||
|
serial_println!("Stack Frame: {:#?}", stack_frame);
|
||||||
|
});
|
||||||
|
|
||||||
|
panic!("EXCEPTION: PAGE FAULT");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn without(func: impl Fn()) {
|
||||||
|
if are_enabled() {
|
||||||
|
unsafe { asm!("cli"); }
|
||||||
|
func();
|
||||||
|
unsafe { asm!("sti"); }
|
||||||
|
} else {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn are_enabled() -> bool {
|
||||||
|
let flags: u64;
|
||||||
|
unsafe {
|
||||||
|
asm!("pushfq; pop {}", out(reg) flags);
|
||||||
|
}
|
||||||
|
flags & (1 << 9) != 0 // Bit 9 is the Interrupt Flag (IF)
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||||
|
use x86_64::instructions::port::Port;
|
||||||
|
|
||||||
|
let mut port = Port::new(0x60);
|
||||||
|
|
||||||
|
serial_println!("KEYBOARD INTERRUPT");
|
||||||
|
|
||||||
|
let scancode: u8 = unsafe { port.read() };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
PICS.lock().notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
|
pub mod apic;
|
||||||
|
|
||||||
mod pics;
|
mod pics;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use core::fmt;
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use crate::sys::kernel::cpu::interrupts;
|
use crate::sys::kernel::cpu::x86_64::interrupts;
|
||||||
|
|
||||||
use super::{font::FONT, render::FRAMEBUFFER_WRITER};
|
use super::{font::FONT, render::FRAMEBUFFER_WRITER};
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ impl core::fmt::Write for TextWriter {
|
|||||||
fn write(args: fmt::Arguments, fg_color: u32, bg_color: u32) {
|
fn write(args: fmt::Arguments, fg_color: u32, bg_color: u32) {
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
interrupts::disable(|| {
|
interrupts::without(|| {
|
||||||
let mut writer = TEXT_WRITER.lock();
|
let mut writer = TEXT_WRITER.lock();
|
||||||
writer.set_colour((fg_color, bg_color));
|
writer.set_colour((fg_color, bg_color));
|
||||||
writer.write_fmt(args).unwrap();
|
writer.write_fmt(args).unwrap();
|
||||||
@@ -146,13 +146,15 @@ pub fn _log(args: fmt::Arguments) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_screen() {
|
pub fn clear_screen() {
|
||||||
let mut writer = TEXT_WRITER.lock();
|
interrupts::without(|| {
|
||||||
writer.text_line = 0;
|
let mut writer = TEXT_WRITER.lock();
|
||||||
writer.text_col = 0;
|
writer.text_line = 0;
|
||||||
|
writer.text_col = 0;
|
||||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
|
||||||
writer.clear();
|
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||||
}
|
writer.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
use core::fmt;
|
use core::{fmt, sync::atomic::{AtomicUsize, Ordering}};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::sys::kernel::cpu::{inb, outb};
|
use crate::sys::kernel::cpu::{inb, outb};
|
||||||
|
use crate::sys::kernel::cpu::x86_64::interrupts;
|
||||||
|
|
||||||
static PORT: u16 = 0x3f8;
|
static PORT: u16 = 0x3f8;
|
||||||
static mut BUFFER: [u8; 256] = [0; 256];
|
static mut BUFFER: [u8; 256] = [0; 256];
|
||||||
|
static BUFFER_LEN: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
lazy_static!{
|
lazy_static!{
|
||||||
static ref SERIAL_WRITER: Mutex<SerialWriter> = Mutex::new(SerialWriter::new());
|
static ref SERIAL_WRITER: Mutex<SerialWriter> = Mutex::new(SerialWriter::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SerialWriter {
|
struct SerialWriter;
|
||||||
buffer_len: usize
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Write for SerialWriter {
|
impl fmt::Write for SerialWriter {
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
@@ -45,9 +45,7 @@ impl SerialWriter {
|
|||||||
outb(PORT + 4, 0x0F);
|
outb(PORT + 4, 0x0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
SerialWriter {
|
SerialWriter
|
||||||
buffer_len: 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// returnstrue if there is new data on the serial port
|
// returnstrue if there is new data on the serial port
|
||||||
@@ -68,15 +66,15 @@ impl SerialWriter {
|
|||||||
pub fn read_str_to_buffer(&mut self) { unsafe {
|
pub fn read_str_to_buffer(&mut self) { unsafe {
|
||||||
while !self.serial_recieved() {};
|
while !self.serial_recieved() {};
|
||||||
|
|
||||||
self.buffer_len = 0;
|
BUFFER_LEN.store(0, Ordering::SeqCst);
|
||||||
|
|
||||||
while self.serial_recieved() && self.buffer_len < 256 {
|
while self.serial_recieved() && BUFFER_LEN.load(Ordering::SeqCst) < 256 {
|
||||||
let c = inb(PORT + 0);
|
let c = inb(PORT + 0);
|
||||||
BUFFER[self.buffer_len] = c;
|
BUFFER[BUFFER_LEN.load(Ordering::SeqCst)] = c;
|
||||||
if c == b'\n' {
|
if c == b'\n' {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self.buffer_len += 1;
|
BUFFER_LEN.fetch_add(1, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -89,19 +87,31 @@ impl SerialWriter {
|
|||||||
pub fn _serial_write(args: fmt::Arguments) {
|
pub fn _serial_write(args: fmt::Arguments) {
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
SERIAL_WRITER.lock().write_fmt(args).unwrap();
|
interrupts::without(|| {
|
||||||
|
SERIAL_WRITER.lock().write_fmt(args).unwrap();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serial_println {
|
||||||
|
() => ($crate::serial_print!("\n"));
|
||||||
|
($($arg:tt)*) => ($crate::serial_print!("{}\n", format_args!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serial_read() -> &'static str {
|
pub fn serial_read() -> &'static str {
|
||||||
SERIAL_WRITER.lock().read_str_to_buffer();
|
serial_println!("getting value!");
|
||||||
let i = SERIAL_WRITER.lock().buffer_len;
|
|
||||||
|
|
||||||
if i == 0 {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
interrupts::without(|| {
|
||||||
return core::str::from_utf8(&BUFFER[..i - 1]).unwrap();
|
SERIAL_WRITER.lock().read_str_to_buffer();
|
||||||
|
});
|
||||||
|
|
||||||
|
let i = BUFFER_LEN.load(Ordering::SeqCst);
|
||||||
|
|
||||||
|
return unsafe {
|
||||||
|
if i != 0 {
|
||||||
|
core::str::from_utf8(&BUFFER[..i - 1]).unwrap()
|
||||||
|
} else { "" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,8 +120,3 @@ macro_rules! serial_print {
|
|||||||
($($arg:tt)*) => ($crate::_serial_write(format_args!($($arg)*)));
|
($($arg:tt)*) => ($crate::_serial_write(format_args!($($arg)*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! serial_println {
|
|
||||||
() => ($crate::serial_print!("\n"));
|
|
||||||
($($arg:tt)*) => ($crate::serial_print!("{}\n", format_args!($($arg)*)));
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
"code-model": "kernel",
|
"code-model": "kernel",
|
||||||
"pre-link-args": {
|
"pre-link-args": {
|
||||||
"ld.lld": [
|
"ld.lld": [
|
||||||
"--script=/home/fantasypvp/Projects/OSDev/GoofyAhhOS/kernel/linker.ld",
|
"--script=kernel/linker.ld",
|
||||||
"-nostdlib",
|
"-nostdlib",
|
||||||
"--no-dynamic-linker",
|
"--no-dynamic-linker",
|
||||||
"-static",
|
"-static",
|
||||||
|
|||||||
+4
-1
@@ -127,7 +127,7 @@ if [ $is_test -eq 1 ]; then
|
|||||||
serial_flags="-serial stdio"
|
serial_flags="-serial stdio"
|
||||||
else
|
else
|
||||||
test_flags=""
|
test_flags=""
|
||||||
# serial_flags="-serial tcp:127.0.0.1:1234,server,nowait"
|
# serial_flags="-serial tcp:127.0.0.1:1234,server -monitor telnet:127.0.0.1:1235,server"
|
||||||
serial_flags="-serial stdio"
|
serial_flags="-serial stdio"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -158,6 +158,8 @@ check_test_res() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
kvm_flag=""
|
||||||
|
|
||||||
trap 'check_test_res "tests completed"' ERR
|
trap 'check_test_res "tests completed"' ERR
|
||||||
|
|
||||||
cd "$project_root"
|
cd "$project_root"
|
||||||
@@ -171,3 +173,4 @@ qemu-system-x86_64 -M q35 \
|
|||||||
${test_flags} \
|
${test_flags} \
|
||||||
${debug_flags} \
|
${debug_flags} \
|
||||||
${QEMU_FLAGS:-}
|
${QEMU_FLAGS:-}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user