Fix the rust setup machine state
This commit is contained in:
parent
052fc795a5
commit
9d0e0bbc70
|
|
@ -654,7 +654,6 @@ dependencies = [
|
|||
name = "jinux-frame-x86-boot-setup"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"spin 0.9.8",
|
||||
"uart_16550",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ use std::{
|
|||
|
||||
use xmas_elf::program::{ProgramHeader, SegmentData};
|
||||
|
||||
// We chose the legacy setup sections to be 7 so that the setup header
|
||||
// is page-aligned and the legacy setup section size would be 0x1000.
|
||||
const LEGACY_SETUP_SECS: usize = 7;
|
||||
const LEGACY_SETUP_SEC_SIZE: usize = 0x200 * (LEGACY_SETUP_SECS + 1);
|
||||
const SETUP32_LMA: usize = 0x100000;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
|
|
@ -87,7 +91,7 @@ fn copy_to_raw_binary(out_dir: &Path) -> Result<(), Box<dyn Error + Send + Sync>
|
|||
return Err("Unexpected program header type".into());
|
||||
};
|
||||
if program.get_type().unwrap() == xmas_elf::program::Type::Load {
|
||||
let dest_file_offset = program.virtual_addr as usize - SETUP32_LMA;
|
||||
let dest_file_offset = program.virtual_addr as usize + LEGACY_SETUP_SEC_SIZE - SETUP32_LMA;
|
||||
bin_writer.seek(std::io::SeekFrom::End(0))?;
|
||||
let cur_file_offset = bin_writer.stream_position().unwrap() as usize;
|
||||
if cur_file_offset < dest_file_offset {
|
||||
|
|
|
|||
|
|
@ -7,4 +7,3 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
uart_16550 = "0.3.0"
|
||||
spin = "0.9.4"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ENTRY(start_of_setup)
|
||||
ENTRY(start_of_setup32)
|
||||
OUTPUT_ARCH(i386:x86)
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
|
||||
|
|
@ -6,10 +6,13 @@ SETUP32_LMA = 0x100000;
|
|||
|
||||
SECTIONS
|
||||
{
|
||||
. = SETUP32_LMA;
|
||||
|
||||
. = SETUP32_LMA - 0x1000;
|
||||
.header : { KEEP(*(.header)) }
|
||||
|
||||
. = SETUP32_LMA;
|
||||
.header.text : { KEEP(*(.header)) }
|
||||
.stack : { KEEP(*(.stack)) }
|
||||
|
||||
.text : { *(.text .text.*) }
|
||||
.rodata : { *(.rodata .rodata.*) }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
use core::fmt::{self, Write};
|
||||
|
||||
use spin::Once;
|
||||
use uart_16550::SerialPort;
|
||||
|
||||
struct Stdout {
|
||||
serial_port: SerialPort,
|
||||
}
|
||||
|
||||
static mut STDOUT: Once<Stdout> = Once::new();
|
||||
static mut STDOUT: Stdout = Stdout { serial_port: unsafe { SerialPort::new(0x0) } };
|
||||
|
||||
/// safety: this function must only be called once
|
||||
pub unsafe fn init() {
|
||||
STDOUT.call_once(|| Stdout::init());
|
||||
STDOUT = Stdout::init();
|
||||
}
|
||||
|
||||
impl Stdout {
|
||||
|
|
@ -33,7 +32,7 @@ impl Write for Stdout {
|
|||
pub fn print(args: fmt::Arguments) {
|
||||
// safety: init() must be called before print() and there is no race condition
|
||||
unsafe {
|
||||
STDOUT.get_mut().unwrap().write_fmt(args).unwrap();
|
||||
STDOUT.write_fmt(args).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
// See https://www.kernel.org/doc/html/v5.6/x86/boot.html for
|
||||
// more information on the Linux x86 Boot Protocol.
|
||||
|
||||
// The section name is used by the build script to strip and make
|
||||
// the binary file.
|
||||
.section ".header", "ax"
|
||||
.section ".header", "a"
|
||||
|
||||
// The Linux x86 Boot Protocol header.
|
||||
//
|
||||
|
|
@ -14,11 +12,12 @@
|
|||
// Jinux will use only a few of these fields, and some of them
|
||||
// are filled by the loader and will be read by Jinux.
|
||||
|
||||
CODE32_START = 0x100000
|
||||
|
||||
.code16
|
||||
.org 0x01f1
|
||||
hdr_start:
|
||||
SETUP_SECTS = 4
|
||||
setup_sects: .byte SETUP_SECTS
|
||||
setup_sects: .byte 7 # so that the legacy setup could occupy a page
|
||||
root_flags: .word 1
|
||||
syssize: .long 0
|
||||
ram_size: .word 0
|
||||
|
|
@ -35,7 +34,7 @@ start_sys_seg: .word 0
|
|||
type_of_loader: .byte 0
|
||||
loadflags: .byte (1 << 0)
|
||||
setup_move_size: .word 0
|
||||
code32_start: .long 0x100000
|
||||
code32_start: .long CODE32_START
|
||||
ramdisk_image: .long 0
|
||||
ramdisk_size: .long 0
|
||||
bootsect_kludge: .long 0
|
||||
|
|
@ -61,9 +60,33 @@ kernel_info_offset: .long 0
|
|||
hdr_end:
|
||||
// End of header.
|
||||
|
||||
// 32-bit setup code starts here, and will be loaded at code32_start (0x100000).
|
||||
// 32-bit setup code starts here, and will be loaded at CODE32_START.
|
||||
.section ".header.text", "ax"
|
||||
.code32
|
||||
.org 0x200 * (SETUP_SECTS + 1)
|
||||
.global start_of_setup32
|
||||
start_of_setup32:
|
||||
mov eax, offset stack_bottom
|
||||
mov esp, eax
|
||||
mov eax, offset halt
|
||||
push eax # the return address
|
||||
mov ebp, esp
|
||||
add ebp, -4
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
.extern _rust_setup_entry
|
||||
jmp _rust_setup_entry
|
||||
push esi # the boot_params pointer
|
||||
call _rust_setup_entry
|
||||
|
||||
// Unreachable here.
|
||||
halt:
|
||||
hlt
|
||||
jmp halt
|
||||
|
||||
// A small stack for the setup code.
|
||||
.section ".stack", "aw"
|
||||
SETUP_STACK_SIZE = 0x1000
|
||||
.align 16
|
||||
stack_top:
|
||||
.skip SETUP_STACK_SIZE
|
||||
stack_bottom:
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ use core::arch::global_asm;
|
|||
global_asm!(include_str!("header.S"));
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _rust_setup_entry() -> ! {
|
||||
pub extern "cdecl" fn _rust_setup_entry(boot_params_ptr: u32) -> ! {
|
||||
// safety: this init function is only called once
|
||||
unsafe { console::init() };
|
||||
println!("Hello, world!");
|
||||
println!("[setup] boot_params_ptr: {:#x}", boot_params_ptr);
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue