Skip to content
Permalink
Browse files

[add] serial port support

EFIでフォントが描写できなかったので代替処置
あと、それに対する初期化コードの変更
  • Loading branch information
PG-MANA committed Mar 15, 2019
1 parent 18fa6fa commit 8a15bd11ddea05f03571a764e5060eccfafc642d
@@ -2,6 +2,7 @@
デバイスを扱い(ここはサブモジュールを読み込むだけ、共通関数実装)
*/

pub mod cpu;
pub mod keyboard;
pub mod pic;
pub mod cpu;
pub mod serial_port;
@@ -0,0 +1,60 @@
// EFIブートでテキストフレームバッファが使えないので
// TODO: UEFIでシリアルポート
// TODO: 割り込みハンドラ

//use
use super::cpu::{in_byte, out_byte};

pub struct SerialPortManager {
port: u16,
}

impl SerialPortManager {
pub fn new(port: u16) -> SerialPortManager {
SerialPortManager { port: port }
}

pub const fn new_static() -> SerialPortManager {
SerialPortManager { port: 0 }
}

pub fn get_port(&self) -> u16 {
self.port //あとから変更できないようにする
}

pub fn init_serial_port(&self) {
unsafe {
out_byte(self.port + 1, 0x00); // FIFOをオフ
out_byte(self.port + 3, 0x80); // DLABを有効化して設定できるようにする?
out_byte(self.port + 0, 0x03); // rateを設定
out_byte(self.port + 1, 0x00); // rate上位
out_byte(self.port + 3, 0x03); // 8bit単位のパリティビットなし
out_byte(self.port + 1, 0x05); // データ到着とエラーで割り込み
out_byte(self.port + 2, 0xC7); // FIFOをオン、割り込みを許可
}
}

pub fn send(&self, data: u8) {
loop {
if self.is_completed_transmitter() {
break;
}
} // ちょっと危なっかしい
unsafe {
out_byte(self.port, data);
}
}

pub fn read(&self) -> u8 {
unsafe { in_byte(self.port) }
}
fn is_completed_transmitter(&self) -> bool {
unsafe {
if in_byte(self.port + 5) & 0x40 != 0 {
true
} else {
false
}
}
}
}
@@ -1,89 +1,69 @@
pub mod mbi; //Multi Boot Information
pub mod memman;
//mod paging;
#[macro_use]
pub mod interrupt;
pub mod device;

use arch::target_arch::device::{cpu, keyboard};
use arch::target_arch::mbi::*;
use arch::target_arch::memman::MemoryManager;
use self::device::serial_port::SerialPortManager;
use self::device::{cpu, keyboard};

use usr::graphic;

#[allow(unused_imports)]
use core::fmt;
use kernel::drivers::efi::EfiManager;
use kernel::drivers::multiboot::MultiBootInformation;
use kernel::graphic::GraphicManager;
use kernel::memory_manager::MemoryManager;
use kernel::spin_lock::Mutex;
use kernel::struct_manager::STATIC_BOOT_INFORMATION_MANAGER;

#[no_mangle]
pub extern "C" fn boot_main(
addr: usize, /*マルチブートヘッダのアドレス*/
gdt: u64, /*現在のセグメント:8*/
mbi_addr: usize, /*マルチブートヘッダのアドレス*/
gdt: u64, /*現在のセグメント:8*/
) {
//おそらくこの関数はCLIされた状態で呼ばれる
//この関数はCLIされた状態で呼ばれる
//PIC初期化
unsafe {
device::pic::pic_init();
}
//GraphicManager初期化
//MultiBootInformation読み込み
if !mbi::test(addr) {
panic!("Unaligned Multi Boot Information.");
}
let info = load_mbi(addr);
graphic::GraphicManager::init_default_manager(&info.framebufferinfo);
println!("Methylenix version 0.0.1");
let multiboot_information = MultiBootInformation::new(mbi_addr);
//メモリ管理初期化
let mut memory_manager = init_memman(&info, addr);
let mut memory_manager = MemoryManager::new(&multiboot_information);
//IDT初期化&割り込み初期化
let idt_manager =
unsafe { interrupt::IDTMan::new(memory_manager.alloc_page().unwrap().get_page(), gdt) };
unsafe {
device::keyboard::Keyboard::init(&idt_manager, gdt);
let interrupt_manager = unsafe {
interrupt::InterruptManager::new(memory_manager.alloc_page().unwrap().get_page(), gdt)
};
//シリアルポート初期化
let serial_port_manager = SerialPortManager::new(0x3F8 /*COM1*/);
serial_port_manager.init_serial_port();

if multiboot_information.efi_table_pointer != 0 {
//EFI Bootが有効
unsafe {
STATIC_BOOT_INFORMATION_MANAGER.efi_manager =
Mutex::new(EfiManager::new(multiboot_information.efi_table_pointer));
}
}
//IDT&PICの初期化が終わったのでSTIする
//Boot Information Manager に格納
unsafe {
cpu::sti();
STATIC_BOOT_INFORMATION_MANAGER.graphic_manager =
Mutex::new(GraphicManager::new(&multiboot_information.framebuffer_info));
STATIC_BOOT_INFORMATION_MANAGER.memory_manager = Mutex::new(memory_manager);
STATIC_BOOT_INFORMATION_MANAGER.interrupt_manager = Mutex::new(interrupt_manager);
STATIC_BOOT_INFORMATION_MANAGER.serial_port_manager = Mutex::new(serial_port_manager);
}
hlt();
}
println!("Methylenix version 0.0.1");

fn init_memman(info: &MultiBootInformation, mbiaddr: usize) -> MemoryManager {
//カーネルサイズの計算
let kernel_loader_start = info
.elfinfo
.clone()
.map(|section| section.addr())
.min()
.unwrap();
let kernel_loader_end = info
.elfinfo
.clone()
.map(|section| section.addr())
.max()
.unwrap();
let mbi_start = mbiaddr;
let mbi_end = mbiaddr + mbi::total_size(mbiaddr) as usize;
println!(
"KernelLoader Size:{}KB, MultiBootInformation Size:{}B",
(kernel_loader_end - kernel_loader_start) / 1024 as usize,
mbi::total_size(mbiaddr)
);
memman::MemoryManager::new(
info.memmapinfo.clone(),
kernel_loader_start as usize,
kernel_loader_end as usize,
mbi_start,
mbi_end,
)
}
unsafe {
//IDT&PICの初期化が終わったのでSTIする
cpu::sti();

fn load_mbi(addr: usize) -> mbi::MultiBootInformation {
let mbi_total_size = mbi::total_size(addr);
if mbi_total_size == 0 {
panic!("Invalid Multi Boot Information.");
device::keyboard::Keyboard::init(
&STATIC_BOOT_INFORMATION_MANAGER
.interrupt_manager
.lock()
.unwrap(),
gdt,
);
}
let info = mbi::MultiBootInformation::new(addr); //Result型などがあり利用してみるのもいいかも
info
hlt();
}

fn hlt() {
@@ -2,6 +2,7 @@
フォントの描画などをフレームバッファに行う
*/

// use(Arch非依存)
use core::fmt;
use kernel::drivers::multiboot::FrameBufferInfo;
use kernel::struct_manager::STATIC_BOOT_INFORMATION_MANAGER;
@@ -88,9 +89,26 @@ impl GraphicManager {
}
}

fn write_string_to_serial_port(&self, string: &str) -> bool {
//代替処置
let serial_port_manager_lock = unsafe {
STATIC_BOOT_INFORMATION_MANAGER
.serial_port_manager
.try_lock()
};
if serial_port_manager_lock.is_ok() {
let manager = serial_port_manager_lock.unwrap();
for code in string.bytes() {
manager.send(code);
}
return true;
}
return false;
}

pub fn write_string(&mut self, string: &str) -> bool {
if !self.is_textmode || self.frame_buffer_width == 0 {
return false; //現在未対応
return self.write_string_to_serial_port(string);
}
for code in string.bytes() {
match code as char {
@@ -3,6 +3,7 @@ structをグローバルでやり取りするためのマネージャ(プロセ
*/

//use(Arch実装依存)
use arch::target_arch::device::serial_port::SerialPortManager;
use arch::target_arch::interrupt::InterruptManager;

//use(Arch非依存)
@@ -20,7 +21,7 @@ pub struct BootInformationManager {
pub memory_manager: Mutex<MemoryManager>,
pub interrupt_manager: Mutex<InterruptManager>,
pub efi_manager: Mutex<EfiManager>,
//input_manager:
pub serial_port_manager: Mutex<SerialPortManager>, //input_manager:
}

const fn init_bootinformation_manager() -> BootInformationManager {
@@ -29,5 +30,6 @@ const fn init_bootinformation_manager() -> BootInformationManager {
memory_manager: Mutex::new(MemoryManager::new_static()),
interrupt_manager: Mutex::new(InterruptManager::new_static()),
efi_manager: Mutex::new(EfiManager::new_static()),
serial_port_manager: Mutex::new(SerialPortManager::new_static()),
}
}

0 comments on commit 8a15bd1

Please sign in to comment.
You can’t perform that action at this time.