libk now replaces the plethora of lib crates #5
+13
-2
@@ -9,5 +9,16 @@ build-std-features = ["compiler-builtins-mem"]
|
|||||||
[env]
|
[env]
|
||||||
RUST_TARGET_PATH = { value = "kernel", relative = true }
|
RUST_TARGET_PATH = { value = "kernel", relative = true }
|
||||||
|
|
||||||
[target.x86_64-kernel]
|
# Run in debug mode.
|
||||||
runner = "scripts/run.sh"
|
[target.'cfg(all(target_arch = "x86_64", target_os = "none", debug_assertions))']
|
||||||
|
runner = "scripts/run_debug.sh"
|
||||||
|
|
||||||
|
# Otherwise we run in release mode.
|
||||||
|
[target.'cfg(all(target_arch = "x86_64", target_os = "none", not(debug_assertions)))']
|
||||||
|
runner = "scripts/run_release.sh"
|
||||||
|
|
||||||
|
# [registry]
|
||||||
|
# default = "gitea"
|
||||||
|
|
||||||
|
[registries.gitea]
|
||||||
|
index = "sparse+https://git.zxq5.dev/api/packages/OsDev/cargo/" # Sparse index
|
||||||
|
|||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
[submodule "lib/lib_application"]
|
|
||||||
path = lib/lib_application
|
|
||||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_application.git
|
|
||||||
[submodule "lib/lib_ascii"]
|
|
||||||
path = lib/lib_ascii
|
|
||||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_ascii.git
|
|
||||||
[submodule "lib/lib_framebuffer"]
|
|
||||||
path = lib/lib_framebuffer
|
|
||||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_framebuffer.git
|
|
||||||
[submodule "lib/lib_serial"]
|
|
||||||
path = lib/lib_serial
|
|
||||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_serial.git
|
|
||||||
[submodule "lib/lib_alloc"]
|
|
||||||
path = lib/lib_alloc
|
|
||||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_alloc.git
|
|
||||||
[submodule "lib/lib_async"]
|
|
||||||
path = lib/lib_async
|
|
||||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_async.git
|
|
||||||
[submodule "lib/lib_keyboard"]
|
|
||||||
path = lib/lib_keyboard
|
|
||||||
url = https://git.zxq5.dev/OsDev/FoundryOS-lib_keyboard.git
|
|
||||||
Vendored
+2
-2
@@ -4,6 +4,6 @@
|
|||||||
"[rust]": {
|
"[rust]": {
|
||||||
"editor.defaultFormatter": "rust-lang.rust-analyzer",
|
"editor.defaultFormatter": "rust-lang.rust-analyzer",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
}
|
},
|
||||||
|
"rust-analyzer.check.command": "clippy",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+6
-70
@@ -22,9 +22,9 @@ checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.14"
|
version = "1.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9"
|
checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
@@ -69,13 +69,7 @@ name = "foundry_os"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"lib_alloc",
|
"libk",
|
||||||
"lib_application",
|
|
||||||
"lib_ascii",
|
|
||||||
"lib_async",
|
|
||||||
"lib_framebuffer",
|
|
||||||
"lib_keyboard",
|
|
||||||
"lib_serial",
|
|
||||||
"limine",
|
"limine",
|
||||||
"pc-keyboard",
|
"pc-keyboard",
|
||||||
"pic8259",
|
"pic8259",
|
||||||
@@ -108,73 +102,15 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "libk"
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|
||||||
dependencies = [
|
|
||||||
"spin",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lib_alloc"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"linked_list_allocator",
|
|
||||||
"x86_64",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lib_application"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"lib_ascii",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lib_ascii"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
"lib_framebuffer",
|
|
||||||
"spin",
|
|
||||||
"x86_64",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lib_async"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam",
|
|
||||||
"spin",
|
|
||||||
"x86_64",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lib_framebuffer"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"limine",
|
|
||||||
"spin",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lib_keyboard"
|
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"lib_ascii",
|
"limine",
|
||||||
|
"linked_list_allocator",
|
||||||
"pc-keyboard",
|
"pc-keyboard",
|
||||||
"spin",
|
"spin",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lib_serial"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
"spin",
|
|
||||||
"x86_64",
|
"x86_64",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
+6
-11
@@ -1,23 +1,18 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = ["kernel", "libk"]
|
||||||
"kernel",
|
|
||||||
"lib/lib_framebuffer",
|
|
||||||
"lib/lib_serial",
|
|
||||||
"lib/lib_ascii",
|
|
||||||
"lib/lib_application",
|
|
||||||
"lib/lib_alloc",
|
|
||||||
"lib/lib_async",
|
|
||||||
"lib/lib_keyboard",
|
|
||||||
]
|
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
authors = ["The FoundryOS Contributors"]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
debug = true
|
debug = true
|
||||||
|
# Leave this on to force Cargo to use the debug runner,
|
||||||
|
# which adds the necessary flags for GDB debugging if you
|
||||||
|
# set $USE_GDB (to any value) e.g. USE_GDB=1 cargo run
|
||||||
debug-assertions = true
|
debug-assertions = true
|
||||||
overflow-checks = true
|
overflow-checks = true
|
||||||
lto = false
|
lto = false
|
||||||
|
|||||||
@@ -5,18 +5,20 @@
|
|||||||
Here are some simple steps to get started:
|
Here are some simple steps to get started:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# If you have not yet cloned the repo:
|
git clone https://git.zxq5.dev/OsDev/FoundryOS.git
|
||||||
git clone --recurse-submodules https://git.zxq5.dev/OsDev/FoundryOS.git
|
|
||||||
# If you already cloned the repo:
|
|
||||||
git submodule update --init --recursive
|
|
||||||
|
|
||||||
cargo build
|
|
||||||
# This will build the binaries if required - no need to call cargo build.
|
|
||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Running in GDB:
|
||||||
|
```sh
|
||||||
|
USE_GDB=1 cargo run
|
||||||
|
```
|
||||||
|
|
||||||
### Build dependencies
|
### Build dependencies
|
||||||
|
|
||||||
* jq: checks whether the app is to be run in debugging mode.
|
|
||||||
* libisoburn: creates ISO images to be booted from.
|
* libisoburn: creates ISO images to be booted from.
|
||||||
* qemu: to run the kernel.
|
* qemu: to run the kernel.
|
||||||
|
|
||||||
|
Optionally,
|
||||||
|
|
||||||
|
* GDB: for debugging the kernel.
|
||||||
+5
-10
@@ -1,18 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "foundry_os"
|
name = "foundry_os"
|
||||||
version = "0.1.0"
|
edition.workspace = true
|
||||||
edition = "2021"
|
version.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
limine = "0.3.1"
|
limine = "0.3.1"
|
||||||
lib_framebuffer = { path = "../lib/lib_framebuffer" }
|
libk = { path = "../libk" }
|
||||||
lib_serial = { path = "../lib/lib_serial" }
|
|
||||||
lib_ascii = { path = "../lib/lib_ascii" }
|
|
||||||
lib_alloc = { path = "../lib/lib_alloc" }
|
|
||||||
lib_application = { path = "../lib/lib_application" }
|
|
||||||
lib_async = { path = "../lib/lib_async" }
|
|
||||||
lib_keyboard = { path = "../lib/lib_keyboard" }
|
|
||||||
|
|
||||||
x86_64 = "0.15.2"
|
x86_64 = "0.15.2"
|
||||||
spin = "0.9.8"
|
spin = "0.9.8"
|
||||||
pic8259 = "0.11.0"
|
pic8259 = "0.11.0"
|
||||||
@@ -27,3 +21,4 @@ default = []
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "kernel"
|
name = "kernel"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
test = false
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use lib_ascii::println_log;
|
use libk::prelude::*;
|
||||||
use lib_serial::serial_println;
|
|
||||||
// use x86_64::instructions::port::Port;
|
|
||||||
use x86_64::registers::control::Cr2;
|
use x86_64::registers::control::Cr2;
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
|
||||||
|
|
||||||
@@ -98,7 +96,7 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
|
|||||||
let mut port = Port::new(0x60);
|
let mut port = Port::new(0x60);
|
||||||
|
|
||||||
let scancode: u8 = unsafe { port.read() };
|
let scancode: u8 = unsafe { port.read() };
|
||||||
lib_keyboard::add_scancode(scancode);
|
libk::io::keyboard::add_scancode(scancode);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
PICS.lock()
|
PICS.lock()
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ use limine::{
|
|||||||
use spin::Lazy;
|
use spin::Lazy;
|
||||||
|
|
||||||
#[used]
|
#[used]
|
||||||
#[link_section = ".requests"]
|
#[unsafe(link_section = ".requests")]
|
||||||
static MEMORY_MAP_REQUEST: MemoryMapRequest = MemoryMapRequest::new();
|
static MEMORY_MAP_REQUEST: MemoryMapRequest = MemoryMapRequest::new();
|
||||||
|
|
||||||
#[used]
|
#[used]
|
||||||
#[link_section = ".requests"]
|
#[unsafe(link_section = ".requests")]
|
||||||
static HIGHER_HALF_DIRECT_MAP_REQUEST: HhdmRequest = HhdmRequest::new();
|
static HIGHER_HALF_DIRECT_MAP_REQUEST: HhdmRequest = HhdmRequest::new();
|
||||||
|
|
||||||
/// ```rs
|
/// ```rs
|
||||||
@@ -26,7 +26,7 @@ pub static PHYSICAL_MEMORY_OFFSET: Lazy<u64> = Lazy::new(|| {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#[used]
|
#[used]
|
||||||
#[link_section = ".requests"]
|
#[unsafe(link_section = ".requests")]
|
||||||
static KERNEL_ADDRESS_REQUEST: KernelAddressRequest = KernelAddressRequest::new();
|
static KERNEL_ADDRESS_REQUEST: KernelAddressRequest = KernelAddressRequest::new();
|
||||||
|
|
||||||
/// Converts virtual addresses in the kernel to a physical address like this:
|
/// Converts virtual addresses in the kernel to a physical address like this:
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// use lib_alloc::allocator::FoundryAllocator;
|
// use lib_alloc::allocator::FoundryAllocator;
|
||||||
use limine::{memory_map::EntryType, response::MemoryMapResponse};
|
use limine::{memory_map::EntryType, response::MemoryMapResponse};
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
|
PhysAddr,
|
||||||
|
VirtAddr,
|
||||||
// addr,
|
// addr,
|
||||||
registers::control::Cr3,
|
registers::control::Cr3,
|
||||||
structures::paging::{
|
structures::paging::{
|
||||||
@@ -11,8 +13,6 @@ use x86_64::{
|
|||||||
PhysFrame,
|
PhysFrame,
|
||||||
Size4KiB,
|
Size4KiB,
|
||||||
},
|
},
|
||||||
PhysAddr,
|
|
||||||
VirtAddr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns a mutable reference to the current level 4 page table.
|
/// Returns a mutable reference to the current level 4 page table.
|
||||||
@@ -27,7 +27,7 @@ unsafe fn active_l4_table(physical_memory_offset: VirtAddr) -> &'static mut Page
|
|||||||
|
|
||||||
let phys_addr = level_4_frame.start_address();
|
let phys_addr = level_4_frame.start_address();
|
||||||
let virt = phys_addr.as_u64() + physical_memory_offset.as_u64();
|
let virt = phys_addr.as_u64() + physical_memory_offset.as_u64();
|
||||||
&mut *(virt as *mut PageTable)
|
unsafe { &mut *(virt as *mut PageTable) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the `OffsetPageTable` for the current CPU architecture.
|
/// Initializes the `OffsetPageTable` for the current CPU architecture.
|
||||||
@@ -49,8 +49,10 @@ unsafe fn active_l4_table(physical_memory_offset: VirtAddr) -> &'static mut Page
|
|||||||
/// Returns an `OffsetPageTable` that allows for manipulation of the page
|
/// Returns an `OffsetPageTable` that allows for manipulation of the page
|
||||||
/// tables for the current CPU architecture.
|
/// tables for the current CPU architecture.
|
||||||
pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
|
pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
|
||||||
|
unsafe {
|
||||||
let l4_table = active_l4_table(physical_memory_offset);
|
let l4_table = active_l4_table(physical_memory_offset);
|
||||||
OffsetPageTable::new(l4_table, physical_memory_offset)
|
OffsetPageTable::new(l4_table, physical_memory_offset)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct FoundryOSFrameAllocator {
|
pub(crate) struct FoundryOSFrameAllocator {
|
||||||
@@ -76,7 +78,7 @@ impl FoundryOSFrameAllocator {
|
|||||||
/// Yields one `PhysFrame` for each available 4KiB frame in the memory map.
|
/// Yields one `PhysFrame` for each available 4KiB frame in the memory map.
|
||||||
///
|
///
|
||||||
/// This function is used to allocate frames for the pagemap.
|
/// This function is used to allocate frames for the pagemap.
|
||||||
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
|
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> + use<> {
|
||||||
let regions = self.memory_map.entries().iter();
|
let regions = self.memory_map.entries().iter();
|
||||||
let usable_regions = regions.filter(|region| region.entry_type == EntryType::USABLE);
|
let usable_regions = regions.filter(|region| region.entry_type == EntryType::USABLE);
|
||||||
|
|
||||||
|
|||||||
+5
-7
@@ -4,13 +4,11 @@
|
|||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use lib_alloc::allocator::init_heap;
|
|
||||||
use limine::BaseRevision;
|
use limine::BaseRevision;
|
||||||
|
|
||||||
pub use lib_ascii::{print, print_log, println, println_log, WRITER};
|
use libk::alloc::init_heap;
|
||||||
pub use lib_serial::{serial_print, serial_println, serial_read};
|
use libk::prelude::*;
|
||||||
// use x86_64::structures::paging::Translate;
|
|
||||||
// use x86_64::PhysAddr;
|
|
||||||
use x86_64::VirtAddr;
|
use x86_64::VirtAddr;
|
||||||
|
|
||||||
mod arch;
|
mod arch;
|
||||||
@@ -20,7 +18,7 @@ mod arch;
|
|||||||
/// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
|
/// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
|
||||||
#[used]
|
#[used]
|
||||||
// The .requests section allows limine to find the requests faster and more safely.
|
// The .requests section allows limine to find the requests faster and more safely.
|
||||||
#[link_section = ".requests"]
|
#[unsafe(link_section = ".requests")]
|
||||||
static BASE_REVISION: BaseRevision = BaseRevision::new();
|
static BASE_REVISION: BaseRevision = BaseRevision::new();
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
@@ -53,7 +51,7 @@ pub fn boot() -> Result<(), &'static str> {
|
|||||||
let memory_map = memmap::get_memory_map();
|
let memory_map = memmap::get_memory_map();
|
||||||
|
|
||||||
print_log!(" Initialising Serial... ");
|
print_log!(" Initialising Serial... ");
|
||||||
lib_serial::init()?;
|
libk::io::serial::init()?;
|
||||||
println_log!("[Success]");
|
println_log!("[Success]");
|
||||||
|
|
||||||
print_log!(" Setting Up Global Descriptor Table... ");
|
print_log!(" Setting Up Global Descriptor Table... ");
|
||||||
|
|||||||
+9
-7
@@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use foundry_os::{println, println_log};
|
use libk::{
|
||||||
use lib_async::task::{Executor, Task};
|
io,
|
||||||
use lib_keyboard::print_keypresses;
|
prelude::*,
|
||||||
|
scheduling::task::{Executor, Task},
|
||||||
|
};
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn kmain() -> ! {
|
extern "C" fn kmain() -> ! {
|
||||||
println_log!(" [ Initialising Kernel Systems ] ");
|
println_log!(" [ Initialising Kernel Systems ] ");
|
||||||
if let Err(err) = foundry_os::boot() {
|
if let Err(err) = foundry_os::boot() {
|
||||||
@@ -16,8 +18,8 @@ extern "C" fn kmain() -> ! {
|
|||||||
|
|
||||||
println_log!("[ Kernel Initialised Successfully ] ");
|
println_log!("[ Kernel Initialised Successfully ] ");
|
||||||
|
|
||||||
let dimensions = lib_ascii::screensize_chars();
|
let dimensions = io::ascii::screensize_chars();
|
||||||
let dimensions2 = lib_framebuffer::screensize_px();
|
let dimensions2 = io::ascii::screensize_px();
|
||||||
|
|
||||||
println!("Dimensions: {}x{} (px)", dimensions2.0, dimensions2.1);
|
println!("Dimensions: {}x{} (px)", dimensions2.0, dimensions2.1);
|
||||||
println!("Dimensions: {}x{} (chars)", dimensions.0, dimensions.1);
|
println!("Dimensions: {}x{} (chars)", dimensions.0, dimensions.1);
|
||||||
@@ -44,7 +46,7 @@ extern "C" fn kmain() -> ! {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut executor = Executor::new();
|
let mut executor = Executor::new();
|
||||||
executor.spawn(Task::new(print_keypresses()));
|
executor.spawn(Task::new(io::keyboard::print_keypresses()));
|
||||||
executor.try_run();
|
executor.try_run();
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
|
|||||||
Submodule lib/lib_alloc deleted from cce44f5273
Submodule lib/lib_application deleted from 4b1c60676a
Submodule lib/lib_ascii deleted from 70d528b2e8
Submodule lib/lib_async deleted from 5e74d22e25
Submodule lib/lib_framebuffer deleted from 53553278d1
Submodule lib/lib_keyboard deleted from b475480d8f
Submodule lib/lib_serial deleted from ed2fa6b501
@@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
name = "libk"
|
||||||
|
publish = ["gitea"]
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
description = "A library crate used to write the kernel for Foundry OS."
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
limine = "0.3.1"
|
||||||
|
x86_64 = "0.15.2"
|
||||||
|
crossbeam = { version = "0.8.4", default-features = false, features = [
|
||||||
|
"alloc",
|
||||||
|
"crossbeam-queue",
|
||||||
|
] }
|
||||||
|
pc-keyboard = "0.8.0"
|
||||||
|
spin = "0.9.8"
|
||||||
|
futures-util = { version = "0.3.31", default-features = false, features = [
|
||||||
|
"alloc",
|
||||||
|
] }
|
||||||
|
linked_list_allocator = "0.10.5"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# libk is for the code that did not make the kernel*
|
||||||
|
|
||||||
|
\*crate, lol.
|
||||||
|
|
||||||
|
libk is an attempt to move away from the godforsaken git submodules that plagued our forefathers. Now we have a crate containing a bunch of code that didn't quite make the core kernel crate, which should be:
|
||||||
|
|
||||||
|
* simpler to maintain
|
||||||
|
* has a catchier name
|
||||||
|
* less fighting with Cargo.toml manifests
|
||||||
|
|
||||||
|
## TODO:
|
||||||
|
|
||||||
|
A lot of things must be improved and worked on, feel free to add extra TODOs below.
|
||||||
|
|
||||||
|
[] Create a kernel logging abstraction similar to Linux. (this should probably just use the serial drivers)
|
||||||
|
|
||||||
|
The rationale behind this is that we want some sort of debug log/tracing support so we aren't just printf debugging forever.
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
Again, write your name below if you like:
|
||||||
|
|
||||||
|
* @zxq5 (wrote most of the libraries as of 23/02/25)
|
||||||
|
* @nullndvoid (made this lushious library crate)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod allocator;
|
||||||
|
|
||||||
|
pub use self::allocator::init_heap;
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
use linked_list_allocator::LockedHeap;
|
||||||
|
use x86_64::{
|
||||||
|
structures::paging::{
|
||||||
|
mapper::MapToError, FrameAllocator, Mapper, Page, PageTableFlags, Size4KiB,
|
||||||
|
},
|
||||||
|
VirtAddr,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// We are currently using a linked list heap allocator which uses our underlying page allocator.
|
||||||
|
pub type FoundryAllocator = LockedHeap;
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
/// This is now Rust's global allocator, so we can use stuff requiring heap allocations.
|
||||||
|
static ALLOCATOR: FoundryAllocator = FoundryAllocator::empty();
|
||||||
|
|
||||||
|
pub const HEAP_START: usize = 0x4444_4444_0000;
|
||||||
|
pub const HEAP_SIZE: usize = 1000 * 1024;
|
||||||
|
|
||||||
|
/// Sets up the heap using the backing page frame allocator.
|
||||||
|
pub fn init_heap(
|
||||||
|
mapper: &mut impl Mapper<Size4KiB>,
|
||||||
|
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
|
||||||
|
) -> Result<(), MapToError<Size4KiB>> {
|
||||||
|
let range = {
|
||||||
|
let heap_start = VirtAddr::new(HEAP_START as u64);
|
||||||
|
let heap_end = heap_start + HEAP_SIZE as u64 - 1u64;
|
||||||
|
let heap_start_page = Page::<Size4KiB>::containing_address(heap_start);
|
||||||
|
let heap_end_page = Page::<Size4KiB>::containing_address(heap_end);
|
||||||
|
Page::range_inclusive(heap_start_page, heap_end_page)
|
||||||
|
};
|
||||||
|
|
||||||
|
for page in range {
|
||||||
|
let frame = frame_allocator
|
||||||
|
.allocate_frame()
|
||||||
|
.ok_or(MapToError::FrameAllocationFailed)?;
|
||||||
|
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
|
||||||
|
unsafe { mapper.map_to(page, frame, flags, frame_allocator)?.flush() };
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
ALLOCATOR.lock().init(HEAP_START as *mut u8, HEAP_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
pub mod ascii;
|
||||||
|
pub mod framebuffer;
|
||||||
|
pub mod keyboard;
|
||||||
|
pub mod port;
|
||||||
|
pub mod serial;
|
||||||
|
|
||||||
|
// Re-exported macro definitions.
|
||||||
|
|
||||||
|
pub use crate::print;
|
||||||
|
pub use crate::print_log;
|
||||||
|
pub use crate::printerr;
|
||||||
|
pub use crate::println;
|
||||||
|
pub use crate::println_log;
|
||||||
|
pub use crate::printlnerr;
|
||||||
|
|
||||||
|
pub use crate::serial_print;
|
||||||
|
pub use crate::serial_println;
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
use core::fmt;
|
||||||
|
use spin::{Lazy, Mutex};
|
||||||
|
use x86_64::instructions::interrupts;
|
||||||
|
|
||||||
|
pub use super::framebuffer::screensize_px;
|
||||||
|
use super::framebuffer::{Colour, FRAMEBUFFER_WRITER};
|
||||||
|
|
||||||
|
mod font;
|
||||||
|
use font::FONT;
|
||||||
|
|
||||||
|
static FONT_WIDTH: u32 = 8;
|
||||||
|
static FONT_HEIGHT: u32 = 16;
|
||||||
|
|
||||||
|
pub static WRITER: Lazy<Mutex<Writer>> = Lazy::new(|| Mutex::new(Writer::new()));
|
||||||
|
|
||||||
|
pub fn screensize_chars() -> (u32, u32) {
|
||||||
|
let writer = WRITER.lock();
|
||||||
|
(writer.screen_width, writer.screen_height)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Writer {
|
||||||
|
/// Measured in chars not pixels.
|
||||||
|
screen_width: u32,
|
||||||
|
/// Measured in chars not pixels.
|
||||||
|
screen_height: u32,
|
||||||
|
/// 16 pixels tall.
|
||||||
|
text_line: u32,
|
||||||
|
/// 8 pixels wide.
|
||||||
|
text_col: u32,
|
||||||
|
|
||||||
|
fg_color: Colour,
|
||||||
|
bg_color: Colour,
|
||||||
|
|
||||||
|
offset1: usize,
|
||||||
|
offset2: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Writer {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Writer {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
FRAMEBUFFER_WRITER.lock().as_mut().map_or_else(
|
||||||
|
|| {
|
||||||
|
panic!("Framebuffer writer not initialized.");
|
||||||
|
},
|
||||||
|
|writer| Self {
|
||||||
|
screen_width: writer.width() / 8,
|
||||||
|
screen_height: writer.height() / 16,
|
||||||
|
text_line: 0,
|
||||||
|
text_col: 0,
|
||||||
|
fg_color: Colour::White,
|
||||||
|
bg_color: Colour::Black,
|
||||||
|
offset1: 16,
|
||||||
|
offset2: 0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_glyph(&mut self, c: u16) {
|
||||||
|
if c as u8 == b'\n' {
|
||||||
|
self.newline();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the character data from the font array. -- each byte is a row of pixels
|
||||||
|
let data: &[u8] = &FONT[c as usize * 16..(c as usize + 1) * 16];
|
||||||
|
|
||||||
|
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||||
|
for (row, line) in data.iter().enumerate().take(16) {
|
||||||
|
for col in 0..8 {
|
||||||
|
let pixel_x: u32 = self.text_col * FONT_WIDTH + col;
|
||||||
|
let pixel_y: u32 = self.text_line * FONT_HEIGHT + row as u32;
|
||||||
|
|
||||||
|
if line & (0x80 >> col) != 0 {
|
||||||
|
// write the foreground color
|
||||||
|
writer.write_pixel(pixel_x as usize, pixel_y as usize, self.fg_color);
|
||||||
|
} else {
|
||||||
|
// write the background color
|
||||||
|
writer.write_pixel(pixel_x as usize, pixel_y as usize, self.bg_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// go to next position
|
||||||
|
if self.text_col + 1 >= self.screen_width {
|
||||||
|
self.newline();
|
||||||
|
} else {
|
||||||
|
self.text_col += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn set_offset(&mut self, offset1: usize, offset2: usize) {
|
||||||
|
self.offset1 = offset1;
|
||||||
|
self.offset2 = offset2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn dimensions(&self) -> (u32, u32) {
|
||||||
|
(self.screen_width, self.screen_height)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn next_char(&mut self) {
|
||||||
|
self.text_col += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn newline(&mut self) {
|
||||||
|
self.text_col = 0;
|
||||||
|
|
||||||
|
if self.text_line + 1 >= self.screen_height {
|
||||||
|
self.text_line = 0;
|
||||||
|
} else {
|
||||||
|
self.text_line += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_string(&mut self, s: &str) {
|
||||||
|
for c in s.chars() {
|
||||||
|
self.write_glyph(c as u16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn set_colour(&mut self, fg: Colour, bg: Colour) {
|
||||||
|
self.fg_color = fg;
|
||||||
|
self.bg_color = bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn reset_colour(&mut self) {
|
||||||
|
self.fg_color = Colour::White;
|
||||||
|
self.bg_color = Colour::Black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::fmt::Write for Writer {
|
||||||
|
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||||
|
self.write_string(s);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(args: fmt::Arguments, fg: Colour, bg: Colour) {
|
||||||
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
interrupts::without_interrupts(|| {
|
||||||
|
let mut writer = WRITER.lock();
|
||||||
|
writer.set_colour(fg, bg);
|
||||||
|
writer.write_fmt(args).unwrap();
|
||||||
|
writer.reset_colour();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _print(args: fmt::Arguments) {
|
||||||
|
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||||
|
write(args, Colour::White, Colour::Black);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _print_err(args: fmt::Arguments) {
|
||||||
|
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||||
|
write(args, Colour::Red, Colour::Black);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _print_log(args: fmt::Arguments) {
|
||||||
|
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||||
|
write(args, Colour::Yellow, Colour::Black);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_screen() {
|
||||||
|
interrupts::without_interrupts(|| {
|
||||||
|
let mut writer = WRITER.lock();
|
||||||
|
writer.text_line = 0;
|
||||||
|
writer.text_col = 0;
|
||||||
|
|
||||||
|
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||||
|
writer.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! println_log {
|
||||||
|
() => ($crate::print_log!("\n"));
|
||||||
|
($($arg:tt)*) => ($crate::print_log!("{}\n", format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! print_log {
|
||||||
|
($($arg:tt)*) => ($crate::io::ascii::_print_log(format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! println {
|
||||||
|
() => ($crate::print!("\n"));
|
||||||
|
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! print {
|
||||||
|
($($arg:tt)*) => ($crate::io::ascii::_print(format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! printlnerr {
|
||||||
|
() => ($crate::printerr!("\n"));
|
||||||
|
($($arg:tt)*) => ($crate::printerr!("{}\n", format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! printerr {
|
||||||
|
($($arg:tt)*) => ($crate::_print_err(format_args!($($arg)*)));
|
||||||
|
}
|
||||||
@@ -0,0 +1,578 @@
|
|||||||
|
pub static FONT: [u8; 288 * 16] = [
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 0
|
||||||
|
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 1
|
||||||
|
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 2
|
||||||
|
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 3
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 4
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 5
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 6
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 7
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 8
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, // 9
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 10
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, // 11
|
||||||
|
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 12
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 13
|
||||||
|
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00,
|
||||||
|
0x00, // 14
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 15
|
||||||
|
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 16
|
||||||
|
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 17
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 18
|
||||||
|
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 19
|
||||||
|
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 20
|
||||||
|
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00,
|
||||||
|
0x00, // 21
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 22
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 23
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 24
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 25
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 26
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 27
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 28
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 29
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 30
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 31
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 32
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 33
|
||||||
|
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 34
|
||||||
|
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 35
|
||||||
|
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00,
|
||||||
|
0x00, // 36
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 37
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 38
|
||||||
|
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 39
|
||||||
|
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 40
|
||||||
|
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 41
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 42
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 43
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00,
|
||||||
|
0x00, // 44
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 45
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 46
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 47
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 48
|
||||||
|
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 49
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 50
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 51
|
||||||
|
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 52
|
||||||
|
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 53
|
||||||
|
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 54
|
||||||
|
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 55
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 56
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 57
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 58
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 59
|
||||||
|
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 60
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 61
|
||||||
|
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 62
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 63
|
||||||
|
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 64
|
||||||
|
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 65
|
||||||
|
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 66
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 67
|
||||||
|
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 68
|
||||||
|
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 69
|
||||||
|
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 70
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 71
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 72
|
||||||
|
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 73
|
||||||
|
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 74
|
||||||
|
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 75
|
||||||
|
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 76
|
||||||
|
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 77
|
||||||
|
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 78
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 79
|
||||||
|
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 80
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00,
|
||||||
|
0x00, // 81
|
||||||
|
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 82
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 83
|
||||||
|
0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 84
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 85
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 86
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 87
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 88
|
||||||
|
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 89
|
||||||
|
0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 90
|
||||||
|
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 91
|
||||||
|
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 92
|
||||||
|
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 93
|
||||||
|
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 94
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||||
|
0x00, // 95
|
||||||
|
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 96
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 97
|
||||||
|
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 98
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 99
|
||||||
|
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 100
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 101
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 102
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78,
|
||||||
|
0x00, // 103
|
||||||
|
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 104
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 105
|
||||||
|
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c,
|
||||||
|
0x00, // 106
|
||||||
|
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 107
|
||||||
|
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 108
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 109
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 110
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 111
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0,
|
||||||
|
0x00, // 112
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e,
|
||||||
|
0x00, // 113
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 114
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 115
|
||||||
|
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 116
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 117
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 118
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 119
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 120
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8,
|
||||||
|
0x00, // 121
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 122
|
||||||
|
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 123
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 124
|
||||||
|
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 125
|
||||||
|
0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 126
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 127
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 128
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 129
|
||||||
|
0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 130
|
||||||
|
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 131
|
||||||
|
0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 132
|
||||||
|
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00,
|
||||||
|
0x00, // 133
|
||||||
|
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 134
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 135
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 136
|
||||||
|
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 137
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 138
|
||||||
|
0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 139
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00,
|
||||||
|
0x00, // 140
|
||||||
|
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 141
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 142
|
||||||
|
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 143
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 144
|
||||||
|
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00,
|
||||||
|
0x00, // 145
|
||||||
|
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00,
|
||||||
|
0x00, // 146
|
||||||
|
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 147
|
||||||
|
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 148
|
||||||
|
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 149
|
||||||
|
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 150
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00,
|
||||||
|
0x00, // 151
|
||||||
|
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 152
|
||||||
|
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 153
|
||||||
|
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 154
|
||||||
|
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 155
|
||||||
|
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 156
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 157
|
||||||
|
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 158
|
||||||
|
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 159
|
||||||
|
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 160
|
||||||
|
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 161
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 162
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, // 163
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 164
|
||||||
|
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 165
|
||||||
|
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 166
|
||||||
|
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 167
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 168
|
||||||
|
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 169
|
||||||
|
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 170
|
||||||
|
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 171
|
||||||
|
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 172
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 173
|
||||||
|
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 174
|
||||||
|
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 175
|
||||||
|
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 176
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 177
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 178
|
||||||
|
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 179
|
||||||
|
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 180
|
||||||
|
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 181
|
||||||
|
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78,
|
||||||
|
0x00, // 182
|
||||||
|
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00,
|
||||||
|
0x00, // 183
|
||||||
|
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 184
|
||||||
|
0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 185
|
||||||
|
0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 186
|
||||||
|
0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 187
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 188
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 189
|
||||||
|
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 190
|
||||||
|
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 191
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 192
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 193
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 194
|
||||||
|
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 195
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 196
|
||||||
|
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 197
|
||||||
|
0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 198
|
||||||
|
0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 199
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 200
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 201
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 202
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 203
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 204
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 205
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 206
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 207
|
||||||
|
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 208
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 209
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 210
|
||||||
|
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 211
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 212
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 213
|
||||||
|
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 214
|
||||||
|
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 215
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 216
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 217
|
||||||
|
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 218
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 219
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 220
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 221
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 222
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 223
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 224
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 225
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 226
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 227
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 228
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 229
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 230
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 231
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 232
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 233
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 234
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 235
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 236
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 237
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 238
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 239
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 240
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 241
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 242
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 243
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 244
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 245
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 246
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 247
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 248
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 249
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 250
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 251
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 252
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 253
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 254
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 255
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 256
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, // 257
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 258
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, // 259
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 260
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, // 261
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, // 262
|
||||||
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xf0, // 263
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x0f, // 264
|
||||||
|
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11,
|
||||||
|
0x44, // 265
|
||||||
|
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
|
||||||
|
0xaa, // 266
|
||||||
|
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd,
|
||||||
|
0x77, // 267
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 268
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 269
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 270
|
||||||
|
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 271
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 272
|
||||||
|
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 273
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 274
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, // 275
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, // 276
|
||||||
|
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 277
|
||||||
|
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 278
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 279
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 280
|
||||||
|
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 281
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 282
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 283
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 284
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 285
|
||||||
|
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, // 286
|
||||||
|
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00,
|
||||||
|
0x00, // 287
|
||||||
|
];
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
use limine::request::FramebufferRequest;
|
||||||
|
|
||||||
|
#[used]
|
||||||
|
#[unsafe(link_section = ".requests")]
|
||||||
|
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
||||||
|
|
||||||
|
mod colour;
|
||||||
|
|
||||||
|
pub use colour::Colour;
|
||||||
|
use core::panic;
|
||||||
|
|
||||||
|
use limine::framebuffer::Framebuffer;
|
||||||
|
use spin::{Lazy, Mutex};
|
||||||
|
|
||||||
|
pub static FRAMEBUFFER_WRITER: Lazy<Mutex<Option<FramebufferWriter>>> = Lazy::new(|| {
|
||||||
|
Mutex::new(FRAMEBUFFER_REQUEST.get_response().map_or_else(
|
||||||
|
|| {
|
||||||
|
panic!("Framebuffer request failed");
|
||||||
|
},
|
||||||
|
|framebuffer_response| {
|
||||||
|
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
|
||||||
|
Some(FramebufferWriter::new(framebuffer))
|
||||||
|
},
|
||||||
|
))
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The updated writer stores necessary fields from the [Framebuffer].
|
||||||
|
/// This ensures that the contained types are Send, as Framebuffer was
|
||||||
|
/// not marked as Send.
|
||||||
|
///
|
||||||
|
/// It also avoids the requirement for lifetimes.
|
||||||
|
///
|
||||||
|
/// Note this does not implement Writer as these functions only handle drawing pixels.
|
||||||
|
pub struct FramebufferWriter {
|
||||||
|
pitch: u64,
|
||||||
|
bpp: u16,
|
||||||
|
addr: *mut u8,
|
||||||
|
width: u64,
|
||||||
|
height: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for FramebufferWriter {}
|
||||||
|
unsafe impl Sync for FramebufferWriter {}
|
||||||
|
|
||||||
|
impl FramebufferWriter {
|
||||||
|
pub fn new(framebuffer: Framebuffer) -> Self {
|
||||||
|
Self {
|
||||||
|
pitch: framebuffer.pitch(),
|
||||||
|
bpp: framebuffer.bpp(),
|
||||||
|
addr: framebuffer.addr(),
|
||||||
|
width: framebuffer.width(),
|
||||||
|
height: framebuffer.height(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_pixel(&self, x: usize, y: usize, color: Colour) {
|
||||||
|
let pitch = self.pitch as usize;
|
||||||
|
let bpp = (self.bpp / 8) as usize;
|
||||||
|
let pixel_offset = y * pitch + x * bpp;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
*(self.addr.add(pixel_offset) as *mut u32) = color.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_frame(&self, buffer: &[Colour; 1280 * 800]) {
|
||||||
|
for (y, row) in buffer.chunks(1280).enumerate() {
|
||||||
|
for (x, pixel) in row.iter().enumerate() {
|
||||||
|
self.write_pixel(x, y, *pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn width(&self) -> u32 {
|
||||||
|
self.width as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn height(&self) -> u32 {
|
||||||
|
self.height as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&self) {
|
||||||
|
let width = self.width as usize;
|
||||||
|
let height = self.height as usize;
|
||||||
|
|
||||||
|
for y in 0..height {
|
||||||
|
for x in 0..width {
|
||||||
|
self.write_pixel(x, y, Colour::Black);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn screensize_px() -> (u32, u32) {
|
||||||
|
FRAMEBUFFER_WRITER
|
||||||
|
.lock()
|
||||||
|
.as_mut()
|
||||||
|
.map_or_else(|| (0, 0), |writer| (writer.width(), writer.height()))
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#[repr(u32)]
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub enum Colour {
|
||||||
|
ARGB(u8, u8, u8, u8),
|
||||||
|
RGB(u8, u8, u8),
|
||||||
|
HexARGB(u32),
|
||||||
|
Black = 0x000000FF,
|
||||||
|
Blue = 0x0000FFFF,
|
||||||
|
Green = 0x00FF00FF,
|
||||||
|
Cyan = 0x00FFFFFF,
|
||||||
|
Red = 0xFF0000FF,
|
||||||
|
Magenta = 0xFF00FFFF,
|
||||||
|
Yellow = 0xFFFF00FF,
|
||||||
|
White = 0xFFFFFFFF,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::use_self)]
|
||||||
|
impl From<Colour> for u32 {
|
||||||
|
fn from(val: Colour) -> Self {
|
||||||
|
match val {
|
||||||
|
Colour::ARGB(a, r, g, b) => {
|
||||||
|
(a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32)
|
||||||
|
}
|
||||||
|
Colour::RGB(r, g, b) => ((r as u32) << 16) | (g as u32) << 8 | (b as u32),
|
||||||
|
Colour::HexARGB(hex) => hex,
|
||||||
|
Colour::Black => 0xFF000000,
|
||||||
|
Colour::Blue => 0xFF0000FF,
|
||||||
|
Colour::Green => 0xFF00FF00,
|
||||||
|
Colour::Cyan => 0xFF00FFFF,
|
||||||
|
Colour::Red => 0xFFFF0000,
|
||||||
|
Colour::Magenta => 0xFFFF00FF,
|
||||||
|
Colour::Yellow => 0xFFFFFF00,
|
||||||
|
Colour::White => 0xFFFFFFFF,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::fmt::Display for Colour {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a),
|
||||||
|
Self::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b),
|
||||||
|
Self::HexARGB(hex) => write!(f, "Hex(#{:x})", hex),
|
||||||
|
Self::Black => write!(f, "Black"),
|
||||||
|
Self::Blue => write!(f, "Blue"),
|
||||||
|
Self::Green => write!(f, "Green"),
|
||||||
|
Self::Cyan => write!(f, "Cyan"),
|
||||||
|
Self::Red => write!(f, "Red"),
|
||||||
|
Self::Magenta => write!(f, "Magenta"),
|
||||||
|
Self::Yellow => write!(f, "Yellow"),
|
||||||
|
Self::White => write!(f, "White"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use core::{
|
||||||
|
pin::Pin,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
use crossbeam::queue::ArrayQueue;
|
||||||
|
use futures_util::{Stream, task::AtomicWaker};
|
||||||
|
use spin::Once;
|
||||||
|
|
||||||
|
static KBD_QUEUE: Once<ArrayQueue<u8>> = Once::new();
|
||||||
|
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
|
|
||||||
|
pub fn add_scancode(scancode: u8) {
|
||||||
|
if let Some(queue) = KBD_QUEUE.get() {
|
||||||
|
if queue.push(scancode).is_err() {
|
||||||
|
println!("WARNING: scancode queue full; dropping keyboard input");
|
||||||
|
} else {
|
||||||
|
println!("waking waker");
|
||||||
|
WAKER.wake();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("WARNING: scancode queue not initialised");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ScanCodeStream {
|
||||||
|
_private: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScanCodeStream {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
KBD_QUEUE.call_once(|| ArrayQueue::new(5));
|
||||||
|
|
||||||
|
Self { _private: () }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ScanCodeStream {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stream for ScanCodeStream {
|
||||||
|
type Item = u8;
|
||||||
|
|
||||||
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||||
|
let queue = KBD_QUEUE.get().expect("scancode queue not initialized");
|
||||||
|
serial_println!("This is called once.");
|
||||||
|
WAKER.register(cx.waker());
|
||||||
|
|
||||||
|
// fast path
|
||||||
|
if let Some(scancode) = queue.pop() {
|
||||||
|
return Poll::Ready(Some(scancode));
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.pop().map_or_else(
|
||||||
|
|| {
|
||||||
|
print!("Returning");
|
||||||
|
Poll::Pending
|
||||||
|
},
|
||||||
|
|scancode| {
|
||||||
|
print!("Scancode found");
|
||||||
|
WAKER.take();
|
||||||
|
Poll::Ready(Some(scancode))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use futures_util::stream::StreamExt;
|
||||||
|
use pc_keyboard::{DecodedKey, HandleControl, Keyboard, ScancodeSet1, layouts};
|
||||||
|
|
||||||
|
pub async fn print_keypresses() {
|
||||||
|
let mut scancodes = ScanCodeStream::new();
|
||||||
|
let mut keyboard = Keyboard::new(
|
||||||
|
ScancodeSet1::new(),
|
||||||
|
layouts::Us104Key,
|
||||||
|
HandleControl::Ignore,
|
||||||
|
);
|
||||||
|
|
||||||
|
serial_println!("Printing keypresses.");
|
||||||
|
|
||||||
|
while let Some(scancode) = scancodes.next().await {
|
||||||
|
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||||
|
if let Some(key) = keyboard.process_keyevent(key_event) {
|
||||||
|
match key {
|
||||||
|
DecodedKey::Unicode(character) => print!("{}", character),
|
||||||
|
DecodedKey::RawKey(key) => print!("{:?}", key),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//! Functions for IO using ports.
|
||||||
|
|
||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inb(port: u16) -> u8 {
|
||||||
|
let value: u8;
|
||||||
|
unsafe {
|
||||||
|
asm!(
|
||||||
|
"in al, dx",
|
||||||
|
out("al") value,
|
||||||
|
in("dx") port,
|
||||||
|
options(nomem, nostack, preserves_flags)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn outb(port: u16, value: u8) {
|
||||||
|
unsafe {
|
||||||
|
asm!(
|
||||||
|
"out dx, al",
|
||||||
|
in("dx") port,
|
||||||
|
in("al") value,
|
||||||
|
options(nomem, nostack, preserves_flags)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
use core::{
|
||||||
|
fmt,
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
|
};
|
||||||
|
use spin::{Lazy, Mutex};
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serial_println {
|
||||||
|
() => ($crate::serial_print!("\n"));
|
||||||
|
($($arg:tt)*) => ($crate::io::serial_print!("{}\n", format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! serial_print {
|
||||||
|
($($arg:tt)*) => ($crate::io::serial::_serial_write(format_args!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
use super::port::{inb, outb};
|
||||||
|
|
||||||
|
use x86_64::instructions::interrupts;
|
||||||
|
|
||||||
|
pub fn _serial_write(args: fmt::Arguments) {
|
||||||
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
interrupts::without_interrupts(|| {
|
||||||
|
if let Some(writer) = WRITER.lock().as_mut() {
|
||||||
|
writer.write_fmt(args).unwrap();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serial_read() -> &'static str {
|
||||||
|
serial_println!("getting value!");
|
||||||
|
|
||||||
|
interrupts::without_interrupts(|| {
|
||||||
|
if let Some(reader) = READER.lock().as_mut() {
|
||||||
|
serial_println!("stuff happnin.");
|
||||||
|
reader.read_str_to_buffer();
|
||||||
|
} else {
|
||||||
|
serial_println!("failed to get writer");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
serial_println!("eee");
|
||||||
|
|
||||||
|
let i = BUFFER_LEN.load(Ordering::SeqCst);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
if i != 0 {
|
||||||
|
core::str::from_utf8(&BUFFER[..i - 1]).unwrap()
|
||||||
|
} else {
|
||||||
|
serial_println!("empty string");
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PORT: u16 = 0x3f8;
|
||||||
|
static mut BUFFER: [u8; 256] = [0; 256];
|
||||||
|
static BUFFER_LEN: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
static READER: Lazy<Mutex<Option<Reader>>> = Lazy::new(|| Mutex::new(None));
|
||||||
|
static WRITER: Lazy<Mutex<Option<Writer>>> = Lazy::new(|| Mutex::new(None));
|
||||||
|
|
||||||
|
struct Reader;
|
||||||
|
|
||||||
|
struct Writer;
|
||||||
|
|
||||||
|
impl fmt::Write for Writer {
|
||||||
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
|
for c in s.chars() {
|
||||||
|
self.write_byte(c as u8);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Writer {
|
||||||
|
unsafe fn write_success(&self) -> bool {
|
||||||
|
inb(PORT + 5) & 0x20 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_byte(&self, data: u8) {
|
||||||
|
unsafe {
|
||||||
|
while !self.write_success() {}
|
||||||
|
outb(PORT, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init() -> Result<(), &'static str> {
|
||||||
|
test()?;
|
||||||
|
|
||||||
|
if READER.lock().is_none() {
|
||||||
|
*READER.lock() = Some(Reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if WRITER.lock().is_none() {
|
||||||
|
*WRITER.lock() = Some(Writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test() -> Result<(), &'static str> {
|
||||||
|
outb(PORT + 1, 0x00); // Disable all interrupts
|
||||||
|
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
||||||
|
outb(PORT, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
||||||
|
outb(PORT + 1, 0x00); // (hi byte)
|
||||||
|
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||||
|
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-bytethreshold
|
||||||
|
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||||
|
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
|
||||||
|
outb(PORT, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
||||||
|
|
||||||
|
if inb(PORT) != 0xAE {
|
||||||
|
return Err("serial test failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
outb(PORT + 4, 0x0F);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Reader {
|
||||||
|
pub fn read_str_to_buffer(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
while !self.read_ready() {}
|
||||||
|
|
||||||
|
BUFFER_LEN.store(0, Ordering::SeqCst);
|
||||||
|
|
||||||
|
while BUFFER_LEN.load(Ordering::SeqCst) < 256 {
|
||||||
|
let c = self.read();
|
||||||
|
BUFFER[BUFFER_LEN.load(Ordering::SeqCst)] = c;
|
||||||
|
if c as char == '\r' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
BUFFER_LEN.fetch_add(1, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_println!("returning")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn read_ready(&self) -> bool {
|
||||||
|
inb(PORT + 5) & 1 != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&self) -> u8 {
|
||||||
|
unsafe {
|
||||||
|
while !self.read_ready() {}
|
||||||
|
inb(PORT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![warn(tail_expr_drop_order)]
|
||||||
|
#![warn(clippy::correctness, clippy::perf, clippy::nursery)]
|
||||||
|
// alloc
|
||||||
|
// io : serial, framebuffer, ascii(?), keyboard
|
||||||
|
// ?????
|
||||||
|
// scheduling / tasks : async
|
||||||
|
|
||||||
|
pub mod alloc;
|
||||||
|
pub mod io;
|
||||||
|
pub mod scheduling;
|
||||||
|
|
||||||
|
/// Re-exports most of the IO macros.
|
||||||
|
pub mod prelude {
|
||||||
|
pub use crate::{print, print_log, println, println_log, serial_print, serial_println};
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pub mod task;
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
extern crate alloc;
|
||||||
|
use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, task::Wake};
|
||||||
|
use core::{
|
||||||
|
future::Future,
|
||||||
|
pin::Pin,
|
||||||
|
sync::atomic::{AtomicU64, Ordering},
|
||||||
|
task::{Context, Poll, Waker},
|
||||||
|
};
|
||||||
|
use crossbeam::queue::ArrayQueue;
|
||||||
|
|
||||||
|
pub struct Task {
|
||||||
|
id: TaskId,
|
||||||
|
future: Pin<Box<dyn Future<Output = ()>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Task {
|
||||||
|
pub fn new(future: impl Future<Output = ()> + 'static) -> Self {
|
||||||
|
Self {
|
||||||
|
id: TaskId::new(),
|
||||||
|
future: Box::pin(future),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll(&mut self, context: &mut Context) -> Poll<()> {
|
||||||
|
self.future.as_mut().poll(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Executor {
|
||||||
|
tasks: BTreeMap<TaskId, Task>,
|
||||||
|
task_queue: Arc<ArrayQueue<TaskId>>,
|
||||||
|
waker_cache: BTreeMap<TaskId, Waker>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Executor {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Executor {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tasks: BTreeMap::new(),
|
||||||
|
task_queue: Arc::new(ArrayQueue::new(100)),
|
||||||
|
waker_cache: BTreeMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn(&mut self, task: Task) {
|
||||||
|
let task_id = task.id;
|
||||||
|
if self.tasks.insert(task.id, task).is_some() {
|
||||||
|
panic!("a task with this id has already been allocated");
|
||||||
|
}
|
||||||
|
self.task_queue.push(task_id).expect("task queue is full");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_ready_tasks(&mut self) {
|
||||||
|
let Self {
|
||||||
|
tasks,
|
||||||
|
task_queue,
|
||||||
|
waker_cache,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
while let Some(task_id) = task_queue.pop() {
|
||||||
|
let task = match tasks.get_mut(&task_id) {
|
||||||
|
Some(task) => task,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
let waker = waker_cache
|
||||||
|
.entry(task_id)
|
||||||
|
.or_insert_with(|| TaskWaker::waker(task_id, task_queue.clone()));
|
||||||
|
let mut context = Context::from_waker(waker);
|
||||||
|
match task.poll(&mut context) {
|
||||||
|
Poll::Ready(()) => {
|
||||||
|
tasks.remove(&task_id);
|
||||||
|
waker_cache.remove(&task_id);
|
||||||
|
}
|
||||||
|
Poll::Pending => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_run(&mut self) {
|
||||||
|
self.run_ready_tasks();
|
||||||
|
self.sleep_if_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sleep_if_idle(&self) {
|
||||||
|
use x86_64::instructions::interrupts::{self, enable_and_hlt};
|
||||||
|
|
||||||
|
interrupts::disable();
|
||||||
|
if self.task_queue.is_empty() {
|
||||||
|
enable_and_hlt();
|
||||||
|
} else {
|
||||||
|
interrupts::enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TaskWaker {
|
||||||
|
task_id: TaskId,
|
||||||
|
task_queue: Arc<ArrayQueue<TaskId>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaskWaker {
|
||||||
|
fn waker(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
|
||||||
|
Waker::from(Arc::new(Self {
|
||||||
|
task_id,
|
||||||
|
task_queue,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake_task(&self) {
|
||||||
|
self.task_queue
|
||||||
|
.push(self.task_id)
|
||||||
|
.expect("task queue is full!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Wake for TaskWaker {
|
||||||
|
fn wake(self: Arc<Self>) {
|
||||||
|
self.wake_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake_by_ref(self: &Arc<Self>) {
|
||||||
|
self.wake_task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
struct TaskId(u64);
|
||||||
|
|
||||||
|
impl TaskId {
|
||||||
|
fn new() -> Self {
|
||||||
|
static NEXT: AtomicU64 = AtomicU64::new(0);
|
||||||
|
Self(NEXT.fetch_add(1, Ordering::Relaxed))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script originally written by zxq5, I added separate scripts to remove `jq` dependency.
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
BLUE='\033[0;34m'
|
BLUE='\033[0;34m'
|
||||||
@@ -16,6 +18,8 @@ trap 'echo -e "${RED}${BOLD}error${NC}: build failed" >&2' ERR
|
|||||||
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||||
project_root=$(cd "$script_dir/.." &>/dev/null && pwd)
|
project_root=$(cd "$script_dir/.." &>/dev/null && pwd)
|
||||||
|
|
||||||
|
echo -e "${GREEN}${BOLD} Running kernel in debug mode."
|
||||||
|
|
||||||
# Logging functions
|
# Logging functions
|
||||||
info() {
|
info() {
|
||||||
echo -e "${BLUE}${BOLD}info${NC}: $1"
|
echo -e "${BLUE}${BOLD}info${NC}: $1"
|
||||||
@@ -124,8 +128,8 @@ else
|
|||||||
kvm_flag=""
|
kvm_flag=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if we're running in debug mode
|
# Enable using GDB with $USE_GDB.
|
||||||
if [[ "$(cargo metadata --format-version=1 | jq -r '.workspace_members[0]' | cut -d' ' -f2)" == "(debug)" ]]; then
|
if [ $USE_GDB ]; then
|
||||||
debug_flags="-s -S"
|
debug_flags="-s -S"
|
||||||
else
|
else
|
||||||
debug_flags=""
|
debug_flags=""
|
||||||
Executable
+186
@@ -0,0 +1,186 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script originally written by zxq5, I added separate scripts to remove `jq` dependency.
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
YELLOW='\033[0;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
BOLD='\033[1m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Error handling
|
||||||
|
set -e
|
||||||
|
trap 'echo -e "${RED}${BOLD}error${NC}: build failed" >&2' ERR
|
||||||
|
|
||||||
|
# Get absolute path to project root
|
||||||
|
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||||
|
project_root=$(cd "$script_dir/.." &>/dev/null && pwd)
|
||||||
|
|
||||||
|
echo -e "${GREEN}${BOLD} Running kernel in release mode."
|
||||||
|
|
||||||
|
# Logging functions
|
||||||
|
info() {
|
||||||
|
echo -e "${BLUE}${BOLD}info${NC}: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
compiling() {
|
||||||
|
echo -e "${GREEN}${BOLD}Compiling${NC}: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
warning() {
|
||||||
|
echo -e "${YELLOW}${BOLD}warning${NC}: $1" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
building() {
|
||||||
|
echo -e "${GREEN}${BOLD}Building${NC}: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
copying() {
|
||||||
|
echo -e "${GREEN}${BOLD} Copying${NC}: $1 to $2"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}${BOLD}error${NC}: $1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_file() {
|
||||||
|
copying $1 $2
|
||||||
|
cp "$1" "$2" || error $3
|
||||||
|
}
|
||||||
|
|
||||||
|
build_dir="$project_root/build"
|
||||||
|
iso_root="$build_dir/iso_root"
|
||||||
|
|
||||||
|
# Check if we're running tests
|
||||||
|
is_test=0
|
||||||
|
if [[ $1 == *"deps"* ]]; then
|
||||||
|
is_test=1
|
||||||
|
kernel_path="$1"
|
||||||
|
else
|
||||||
|
# Build the kernel normally
|
||||||
|
cd "$project_root"
|
||||||
|
# cargo build
|
||||||
|
kernel_path="$build_dir/target/x86_64-kernel/release/kernel"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for required tools
|
||||||
|
check_tools() {
|
||||||
|
local missing=0
|
||||||
|
for tool in xorriso git qemu-system-x86_64; do
|
||||||
|
if ! command -v $tool >/dev/null 2>&1; then
|
||||||
|
error "required tool '$tool' is not installed"
|
||||||
|
missing=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $missing -eq 1 ]; then
|
||||||
|
error "missing required tools"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create build directory structure
|
||||||
|
info "Creating build directory structure"
|
||||||
|
mkdir -p "$iso_root/boot/limine"
|
||||||
|
mkdir -p "$iso_root/EFI/BOOT"
|
||||||
|
|
||||||
|
# Clone Limine if needed
|
||||||
|
if [ ! -d "$build_dir/limine" ]; then
|
||||||
|
compiling "limine bootloader"
|
||||||
|
cd "$build_dir"
|
||||||
|
git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 "$build_dir/limine" || error "failed to clone limine"
|
||||||
|
make -C "$build_dir/limine" || error "failed to build limine"
|
||||||
|
cd "$project_root"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy files
|
||||||
|
info "Copying files to ISO root"
|
||||||
|
copy_file "$kernel_path" "$iso_root/boot/kernel" "failed to copy kernel"
|
||||||
|
copy_file "$project_root/config/limine.conf" "$iso_root/boot/limine/limine.conf" "failed to copy limine config"
|
||||||
|
copy_file "$build_dir/limine/limine-bios-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-bios-cd.bin"
|
||||||
|
copy_file "$build_dir/limine/limine-uefi-cd.bin" "$iso_root/boot/limine/" "failed to copy limine-uefi-cd.bin"
|
||||||
|
copy_file "$build_dir/limine/limine-bios.sys" "$iso_root/boot/limine/" "failed to copy limine-bios.sys"
|
||||||
|
copy_file "$build_dir/limine/BOOTX64.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTX64.EFI"
|
||||||
|
copy_file "$build_dir/limine/BOOTIA32.EFI" "$iso_root/EFI/BOOT/" "failed to copy BOOTIA32.EFI"
|
||||||
|
|
||||||
|
# Create ISO
|
||||||
|
building "bootable ISO image"
|
||||||
|
xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \
|
||||||
|
-no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
|
||||||
|
-apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \
|
||||||
|
-efi-boot-part --efi-boot-image --protective-msdos-label \
|
||||||
|
"$iso_root" -o "$build_dir/image.iso" || error "failed to create ISO"
|
||||||
|
|
||||||
|
# Install Limine
|
||||||
|
info "Installing Limine bootloader"
|
||||||
|
"$build_dir/limine/limine" bios-install "$build_dir/image.iso" || error "failed to install limine"
|
||||||
|
|
||||||
|
# Check if KVM is available
|
||||||
|
if [ "${KVM_FLAG:-enable}" = "disable" ]; then
|
||||||
|
warning "KVM acceleration disabled by user"
|
||||||
|
kvm_flag=""
|
||||||
|
elif [ -c "/dev/kvm" ] && [ -w "/dev/kvm" ]; then
|
||||||
|
info "KVM acceleration enabled"
|
||||||
|
kvm_flag="-enable-kvm"
|
||||||
|
else
|
||||||
|
warning "KVM acceleration not available (is kvm module loaded?)"
|
||||||
|
kvm_flag=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# I'm lazy but I just remove GDB flags when running this script.
|
||||||
|
debug_flags=""
|
||||||
|
|
||||||
|
# Set up test-specific flags
|
||||||
|
if [ $is_test -eq 1 ]; then
|
||||||
|
test_flags="-device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none"
|
||||||
|
serial_flags="-serial stdio"
|
||||||
|
else
|
||||||
|
test_flags=""
|
||||||
|
# serial_flags="-serial tcp:127.0.0.1:1234,server -monitor telnet:127.0.0.1:1235,server"
|
||||||
|
serial_flags="-serial stdio"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run in QEMU
|
||||||
|
if [[ ${QEMU_FLAGS} == *-S* ]]; then
|
||||||
|
info "Running OS in QEMU with GDB debugging enabled"
|
||||||
|
info "To connect GDB, run: gdb"
|
||||||
|
info "At the GDB prompt, type: target remote localhost:1234"
|
||||||
|
else
|
||||||
|
info "Running OS in QEMU..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
check_test_res() {
|
||||||
|
qemu_exit_code=$?
|
||||||
|
if [ $qemu_exit_code -eq 33 ]; then
|
||||||
|
# Success case (0x10 << 1) | 1 = 33
|
||||||
|
info "All tests passed"
|
||||||
|
exit 0
|
||||||
|
elif [ $qemu_exit_code -eq 35 ]; then
|
||||||
|
# Failure case (0x11 << 1) | 1 = 35
|
||||||
|
warning "Some tests failed"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
# Any other exit code is treated as a failure
|
||||||
|
warning "Some tests failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
kvm_flag=""
|
||||||
|
|
||||||
|
trap 'check_test_res "tests completed"' ERR
|
||||||
|
|
||||||
|
cd "$project_root"
|
||||||
|
qemu-system-x86_64 -M q35 \
|
||||||
|
${kvm_flag} \
|
||||||
|
-cdrom "$build_dir/image.iso" \
|
||||||
|
-boot d \
|
||||||
|
-m 2G \
|
||||||
|
${serial_flags} \
|
||||||
|
-no-reboot \
|
||||||
|
${test_flags} \
|
||||||
|
${debug_flags} \
|
||||||
|
${QEMU_FLAGS:-}
|
||||||
|
|
||||||
Reference in New Issue
Block a user