Fix the rust setup machine state

This commit is contained in:
Zhang Junyang 2023-10-23 14:43:11 +08:00 committed by Tate, Hongliang Tian
parent 052fc795a5
commit 9d0e0bbc70
7 changed files with 48 additions and 21 deletions

1
Cargo.lock generated
View File

@ -654,7 +654,6 @@ dependencies = [
name = "jinux-frame-x86-boot-setup"
version = "0.1.0"
dependencies = [
"spin 0.9.8",
"uart_16550",
]

View File

@ -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 {

View File

@ -7,4 +7,3 @@ edition = "2021"
[dependencies]
uart_16550 = "0.3.0"
spin = "0.9.4"

View File

@ -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.*) }

View File

@ -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();
}
}

View File

@ -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:

View File

@ -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 {}
}