mirror of https://github.com/vinc/moros.git
Move kernel code to api (#204)
* Move code to api * Add palette::from_csv * Refactor palette::from_str with tests * Add tests to api::font::from_bytes * Add TODO comments to fs code * Rename kernel and user dirs to sys and usr * Add missing files from migration * Move console::Style to api * Add more missing changes
This commit is contained in:
parent
04afe534e3
commit
6b8de261ca
|
@ -0,0 +1,83 @@
|
|||
use core::fmt;
|
||||
|
||||
pub struct Style {
|
||||
foreground: Option<usize>,
|
||||
background: Option<usize>,
|
||||
}
|
||||
|
||||
impl Style {
|
||||
pub fn reset() -> Self {
|
||||
Self { foreground: None, background: None }
|
||||
}
|
||||
|
||||
pub fn foreground(name: &str) -> Self {
|
||||
Self { foreground: color_to_fg(name), background: None }
|
||||
}
|
||||
|
||||
pub fn with_foreground(self, name: &str) -> Self {
|
||||
Self { foreground: color_to_fg(name), background: self.background }
|
||||
}
|
||||
|
||||
pub fn background(name: &str) -> Self {
|
||||
Self { foreground: None, background: color_to_bg(name) }
|
||||
}
|
||||
|
||||
pub fn with_background(self, name: &str) -> Self {
|
||||
Self { foreground: self.foreground, background: color_to_bg(name) }
|
||||
}
|
||||
|
||||
pub fn color(name: &str) -> Self {
|
||||
Self::foreground(name)
|
||||
}
|
||||
|
||||
pub fn with_color(self, name: &str) -> Self {
|
||||
self.with_foreground(name)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Style {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(fg) = self.foreground {
|
||||
if let Some(bg) = self.background {
|
||||
write!(f, "\x1b[{};{}m", fg, bg)
|
||||
} else {
|
||||
write!(f, "\x1b[{}m", fg)
|
||||
}
|
||||
} else if let Some(bg) = self.background {
|
||||
write!(f, "\x1b[{}m", bg)
|
||||
} else {
|
||||
write!(f, "\x1b[0m")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn color_to_fg(name: &str) -> Option<usize> {
|
||||
match name {
|
||||
"Black" => Some(30),
|
||||
"Red" => Some(31),
|
||||
"Green" => Some(32),
|
||||
"Brown" => Some(33),
|
||||
"Blue" => Some(34),
|
||||
"Magenta" => Some(35),
|
||||
"Cyan" => Some(36),
|
||||
"LightGray" => Some(37),
|
||||
"DarkGray" => Some(90),
|
||||
"LightRed" => Some(91),
|
||||
"LightGreen" => Some(92),
|
||||
"Yellow" => Some(93),
|
||||
"LightBlue" => Some(94),
|
||||
"Pink" => Some(95),
|
||||
"LightCyan" => Some(96),
|
||||
"White" => Some(97),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn color_to_bg(name: &str) -> Option<usize> {
|
||||
if let Some(fg) = color_to_fg(name) {
|
||||
Some(fg + 10)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ pub struct Font {
|
|||
|
||||
// http://www.fifi.org/doc/console-tools-dev/file-formats/psf
|
||||
pub fn from_bytes(buf: &[u8]) -> Result<Font, ()> {
|
||||
// Header
|
||||
if buf.len() < 4 || buf[0] != 0x36 || buf[1] != 0x04 {
|
||||
return Err(());
|
||||
}
|
||||
|
@ -19,10 +20,25 @@ pub fn from_bytes(buf: &[u8]) -> Result<Font, ()> {
|
|||
1 | 3 => 512,
|
||||
_ => return Err(()),
|
||||
};
|
||||
|
||||
// Data
|
||||
let n = (4 + size * height as u16) as usize;
|
||||
if buf.len() < n {
|
||||
return Err(());
|
||||
}
|
||||
let data = buf[4..n].to_vec();
|
||||
|
||||
// TODO: Unicode Table
|
||||
|
||||
Ok(Font { height, size, data })
|
||||
}
|
||||
|
||||
#[test_case]
|
||||
fn parse_psf_font() {
|
||||
assert!(from_bytes(include_bytes!("../../dsk/ini/boot.sh")).is_err());
|
||||
|
||||
let font = from_bytes(include_bytes!("../../dsk/ini/fonts/zap-light-8x16.psf")).unwrap();
|
||||
assert_eq!(font.height, 16);
|
||||
assert_eq!(font.size, 256);
|
||||
assert_eq!(font.data.len(), 256 * 16);
|
||||
}
|
|
@ -1 +1,4 @@
|
|||
pub mod console;
|
||||
pub mod font;
|
||||
pub mod syscall;
|
||||
pub mod vga;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::syscall;
|
||||
use crate::kernel::syscall::number::*;
|
||||
use crate::sys::syscall::number::*;
|
||||
|
||||
pub fn sleep(seconds: f64) {
|
||||
unsafe { syscall!(SLEEP, seconds.to_bits()) };
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/// The standard color palette in VGA text mode
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum Color {
|
||||
Black = 0,
|
||||
Blue = 1,
|
||||
Green = 2,
|
||||
Cyan = 3,
|
||||
Red = 4,
|
||||
Magenta = 5,
|
||||
Brown = 6,
|
||||
LightGray = 7,
|
||||
DarkGray = 8,
|
||||
LightBlue = 9,
|
||||
LightGreen = 10,
|
||||
LightCyan = 11,
|
||||
LightRed = 12,
|
||||
Pink = 13,
|
||||
Yellow = 14,
|
||||
White = 15,
|
||||
}
|
||||
|
||||
const COLORS: [Color; 16] = [
|
||||
Color::Black,
|
||||
Color::Blue,
|
||||
Color::Green,
|
||||
Color::Cyan,
|
||||
Color::Red,
|
||||
Color::Magenta,
|
||||
Color::Brown,
|
||||
Color::LightGray,
|
||||
Color::DarkGray,
|
||||
Color::LightBlue,
|
||||
Color::LightGreen,
|
||||
Color::LightCyan,
|
||||
Color::LightRed,
|
||||
Color::Pink,
|
||||
Color::Yellow,
|
||||
Color::White,
|
||||
];
|
||||
|
||||
pub fn colors() -> [Color; 16] {
|
||||
COLORS
|
||||
}
|
||||
|
||||
pub fn from_index(index: usize) -> Color {
|
||||
COLORS[index]
|
||||
}
|
||||
|
||||
pub fn from_ansi(code: u8) -> Color {
|
||||
match code {
|
||||
30 => Color::Black,
|
||||
31 => Color::Red,
|
||||
32 => Color::Green,
|
||||
33 => Color::Brown,
|
||||
34 => Color::Blue,
|
||||
35 => Color::Magenta,
|
||||
36 => Color::Cyan,
|
||||
37 => Color::LightGray,
|
||||
90 => Color::DarkGray,
|
||||
91 => Color::LightRed,
|
||||
92 => Color::LightGreen,
|
||||
93 => Color::Yellow,
|
||||
94 => Color::LightBlue,
|
||||
95 => Color::Pink,
|
||||
96 => Color::LightCyan,
|
||||
97 => Color::White,
|
||||
_ => Color::Black, // Error
|
||||
}
|
||||
}
|
||||
|
||||
impl Color {
|
||||
pub fn to_palette_code(&self) -> u8 {
|
||||
match self {
|
||||
Color::Black => 0x00,
|
||||
Color::Blue => 0x01,
|
||||
Color::Green => 0x02,
|
||||
Color::Cyan => 0x03,
|
||||
Color::Red => 0x04,
|
||||
Color::Magenta => 0x05,
|
||||
Color::LightGray => 0x07,
|
||||
Color::Brown => 0x14,
|
||||
Color::DarkGray => 0x38,
|
||||
Color::LightBlue => 0x39,
|
||||
Color::LightGreen => 0x3A,
|
||||
Color::LightCyan => 0x3B,
|
||||
Color::LightRed => 0x3C,
|
||||
Color::Pink => 0x3D,
|
||||
Color::Yellow => 0x3E,
|
||||
Color::White => 0x3F,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
pub mod color;
|
||||
pub mod palette;
|
||||
|
||||
pub use color::Color;
|
||||
pub use palette::Palette;
|
|
@ -0,0 +1,38 @@
|
|||
use alloc::vec::Vec;
|
||||
use core::convert::TryInto;
|
||||
|
||||
pub struct Palette {
|
||||
pub colors: [(u8, u8, u8, u8); 16]
|
||||
}
|
||||
|
||||
pub fn from_csv(s: &str) -> Result<Palette, ()> {
|
||||
let colors: Vec<_> = s.split("\n").filter_map(|line| {
|
||||
let line = line.split("#").next().unwrap(); // Remove comments
|
||||
let color: Vec<u8> = line.split(",").filter_map(|value| {
|
||||
let radix = if value.contains("0x") { 16 } else { 10 };
|
||||
let value = value.trim().trim_start_matches("0x");
|
||||
u8::from_str_radix(value, radix).ok()
|
||||
}).collect();
|
||||
if color.len() == 4 { // Color index + rgb values
|
||||
Some((color[0], color[1], color[2], color[3]))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect();
|
||||
if let Ok(colors) = colors.try_into() { // Array of 16 colors
|
||||
Ok(Palette { colors })
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test_case]
|
||||
fn parse_palette_csv() {
|
||||
assert!(from_csv("").is_err());
|
||||
assert!(from_csv("0,0,0,0").is_err());
|
||||
|
||||
let s = include_str!("../../../dsk/ini/palette.csv");
|
||||
let palette = from_csv(s).unwrap();
|
||||
assert_eq!(palette.colors[0x03].0, 0x03);
|
||||
assert_eq!(palette.colors[0x0D].2, 0x86);
|
||||
}
|
38
src/lib.rs
38
src/lib.rs
|
@ -10,30 +10,30 @@
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
pub mod kernel;
|
||||
pub mod api;
|
||||
pub mod user;
|
||||
pub mod sys;
|
||||
pub mod usr;
|
||||
|
||||
use bootloader::BootInfo;
|
||||
|
||||
pub fn init(boot_info: &'static BootInfo) {
|
||||
kernel::vga::init();
|
||||
kernel::gdt::init();
|
||||
kernel::idt::init();
|
||||
unsafe { kernel::pic::PICS.lock().initialize() };
|
||||
sys::vga::init();
|
||||
sys::gdt::init();
|
||||
sys::idt::init();
|
||||
unsafe { sys::pic::PICS.lock().initialize() };
|
||||
x86_64::instructions::interrupts::enable();
|
||||
|
||||
log!("MOROS v{}\n", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
kernel::time::init();
|
||||
kernel::keyboard::init();
|
||||
kernel::serial::init();
|
||||
kernel::mem::init(boot_info);
|
||||
kernel::cpu::init();
|
||||
kernel::pci::init(); // Require MEM
|
||||
kernel::net::init(); // Require PCI
|
||||
kernel::ata::init();
|
||||
kernel::fs::init(); // Require ATA
|
||||
sys::time::init();
|
||||
sys::keyboard::init();
|
||||
sys::serial::init();
|
||||
sys::mem::init(boot_info);
|
||||
sys::cpu::init();
|
||||
sys::pci::init(); // Require MEM
|
||||
sys::net::init(); // Require PCI
|
||||
sys::ata::init();
|
||||
sys::fs::init(); // Require ATA
|
||||
}
|
||||
|
||||
#[alloc_error_handler]
|
||||
|
@ -49,8 +49,8 @@ impl<T> Testable for T where T: Fn() {
|
|||
fn run(&self) {
|
||||
print!("test {} ... ", core::any::type_name::<T>());
|
||||
self();
|
||||
let csi_color = kernel::console::Style::color("LightGreen");
|
||||
let csi_reset = kernel::console::Style::reset();
|
||||
let csi_color = api::console::Style::color("LightGreen");
|
||||
let csi_reset = api::console::Style::reset();
|
||||
print!("{}ok{}\n", csi_color, csi_reset);
|
||||
}
|
||||
}
|
||||
|
@ -106,8 +106,8 @@ fn test_kernel_main(boot_info: &'static BootInfo) -> ! {
|
|||
#[cfg(test)]
|
||||
#[panic_handler]
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
let csi_color = kernel::console::Style::color("LightRed");
|
||||
let csi_reset = kernel::console::Style::reset();
|
||||
let csi_color = api::console::Style::color("LightRed");
|
||||
let csi_reset = api::console::Style::reset();
|
||||
print!("{}failed{}\n\n", csi_color, csi_reset);
|
||||
print!("{}\n\n", info);
|
||||
exit_qemu(QemuExitCode::Failed);
|
||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -5,7 +5,7 @@ extern crate alloc;
|
|||
|
||||
use bootloader::{entry_point, BootInfo};
|
||||
use core::panic::PanicInfo;
|
||||
use moros::{kernel, print, user};
|
||||
use moros::{sys, usr, print};
|
||||
|
||||
entry_point!(main);
|
||||
|
||||
|
@ -13,17 +13,17 @@ fn main(boot_info: &'static BootInfo) -> ! {
|
|||
moros::init(boot_info);
|
||||
loop {
|
||||
let bootrc = "/ini/boot.sh";
|
||||
if kernel::fs::File::open(bootrc).is_some() {
|
||||
user::shell::main(&["shell", bootrc]);
|
||||
if sys::fs::File::open(bootrc).is_some() {
|
||||
usr::shell::main(&["shell", bootrc]);
|
||||
} else {
|
||||
if kernel::fs::is_mounted() {
|
||||
if sys::fs::is_mounted() {
|
||||
print!("Could not find '{}'\n", bootrc);
|
||||
} else {
|
||||
print!("MFS is not mounted to '/'\n");
|
||||
}
|
||||
print!("Running console in diskless mode\n");
|
||||
|
||||
user::shell::main(&["shell"]);
|
||||
usr::shell::main(&["shell"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,6 @@ fn main(boot_info: &'static BootInfo) -> ! {
|
|||
fn panic(info: &PanicInfo) -> ! {
|
||||
print!("{}\n", info);
|
||||
loop {
|
||||
kernel::time::sleep(10.0)
|
||||
sys::time::sleep(10.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, log};
|
||||
use crate::{sys, log};
|
||||
use acpi::{AcpiHandler, PhysicalMapping, AcpiTables};
|
||||
use alloc::boxed::Box;
|
||||
use aml::{AmlContext, AmlName, DebugVerbosity, Handler};
|
||||
|
@ -22,7 +22,7 @@ enum FADT {
|
|||
}
|
||||
|
||||
fn read_addr<T>(physical_address: usize) -> T where T: Copy {
|
||||
let virtual_address = kernel::mem::phys_to_virt(PhysAddr::new(physical_address as u64));
|
||||
let virtual_address = sys::mem::phys_to_virt(PhysAddr::new(physical_address as u64));
|
||||
unsafe { *virtual_address.as_ptr::<T>() }
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ pub fn shutdown() {
|
|||
let acpi_enable = read_fadt::<u8>(sdt.physical_address, FADT::AcpiEnable);
|
||||
let mut port: Port<u8> = Port::new(smi_cmd_port);
|
||||
unsafe { port.write(acpi_enable); }
|
||||
kernel::time::sleep(3.0);
|
||||
sys::time::sleep(3.0);
|
||||
*/
|
||||
|
||||
pm1a_control_block = read_fadt::<u32>(sdt.physical_address, FADT::Pm1aControlBlock);
|
||||
|
@ -61,7 +61,7 @@ pub fn shutdown() {
|
|||
match &acpi.dsdt {
|
||||
Some(dsdt) => {
|
||||
//log!("ACPI Found DSDT at {}\n", dsdt.address);
|
||||
let address = kernel::mem::phys_to_virt(PhysAddr::new(dsdt.address as u64));
|
||||
let address = sys::mem::phys_to_virt(PhysAddr::new(dsdt.address as u64));
|
||||
let stream = unsafe { core::slice::from_raw_parts(address.as_ptr(), dsdt.length as usize) };
|
||||
if aml.parse_table(stream).is_ok() {
|
||||
let name = AmlName::from_str("\\_S5").unwrap();
|
||||
|
@ -99,7 +99,7 @@ pub struct MorosAcpiHandler;
|
|||
|
||||
impl AcpiHandler for MorosAcpiHandler {
|
||||
unsafe fn map_physical_region<T>(&self, physical_address: usize, size: usize) -> PhysicalMapping<Self, T> {
|
||||
let virtual_address = kernel::mem::phys_to_virt(PhysAddr::new(physical_address as u64));
|
||||
let virtual_address = sys::mem::phys_to_virt(PhysAddr::new(physical_address as u64));
|
||||
PhysicalMapping {
|
||||
physical_start: physical_address,
|
||||
virtual_start: core::ptr::NonNull::new(virtual_address.as_mut_ptr()).unwrap(),
|
|
@ -1,4 +1,4 @@
|
|||
use crate::kernel;
|
||||
use crate::sys;
|
||||
use alloc::slice::SliceIndex;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
|
@ -70,7 +70,7 @@ impl PhysBuf {
|
|||
fn phys_addr(ptr: &u8) -> u64 {
|
||||
let rx_ptr = ptr as *const u8;
|
||||
let virt_addr = VirtAddr::new(rx_ptr as u64);
|
||||
let phys_addr = kernel::mem::virt_to_phys(virt_addr).unwrap();
|
||||
let phys_addr = sys::mem::virt_to_phys(virt_addr).unwrap();
|
||||
phys_addr.as_u64()
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, log, print};
|
||||
use crate::{sys, log, print};
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use bit_field::BitField;
|
||||
|
@ -74,9 +74,9 @@ impl Bus {
|
|||
fn reset(&mut self) {
|
||||
unsafe {
|
||||
self.control_register.write(4); // Set SRST bit
|
||||
kernel::time::nanowait(5); // Wait at least 5 us
|
||||
sys::time::nanowait(5); // Wait at least 5 us
|
||||
self.control_register.write(0); // Then clear it
|
||||
kernel::time::nanowait(2000); // Wait at least 2 ms
|
||||
sys::time::nanowait(2000); // Wait at least 2 ms
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,9 +114,9 @@ impl Bus {
|
|||
|
||||
fn busy_loop(&mut self) {
|
||||
self.wait();
|
||||
let start = kernel::clock::uptime();
|
||||
let start = sys::clock::uptime();
|
||||
while self.is_busy() {
|
||||
if kernel::clock::uptime() - start > 1.0 { // Hanged
|
||||
if sys::clock::uptime() - start > 1.0 { // Hanged
|
||||
return self.reset();
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
use crate::kernel;
|
||||
use crate::kernel::cmos::CMOS;
|
||||
use crate::sys;
|
||||
use crate::sys::cmos::CMOS;
|
||||
|
||||
const DAYS_BEFORE_MONTH: [u64; 13] = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
|
||||
|
||||
// NOTE: This clock is monotonic
|
||||
pub fn uptime() -> f64 {
|
||||
kernel::time::time_between_ticks() * kernel::time::ticks() as f64
|
||||
sys::time::time_between_ticks() * sys::time::ticks() as f64
|
||||
}
|
||||
|
||||
// NOTE: This clock is not monotonic
|
||||
|
@ -19,8 +19,8 @@ pub fn realtime() -> f64 {
|
|||
+ 60 * rtc.minute as u64
|
||||
+ rtc.second as u64;
|
||||
|
||||
let fract = kernel::time::time_between_ticks()
|
||||
* (kernel::time::ticks() - kernel::time::last_rtc_update()) as f64;
|
||||
let fract = sys::time::time_between_ticks()
|
||||
* (sys::time::ticks() - sys::time::last_rtc_update()) as f64;
|
||||
|
||||
(timestamp as f64) + fract
|
||||
}
|
|
@ -1,91 +1,9 @@
|
|||
use crate::{kernel, print};
|
||||
use crate::{sys, print};
|
||||
use alloc::string::String;
|
||||
use core::fmt;
|
||||
use lazy_static::lazy_static;
|
||||
use spin::Mutex;
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
pub struct Style {
|
||||
foreground: Option<usize>,
|
||||
background: Option<usize>,
|
||||
}
|
||||
|
||||
impl Style {
|
||||
pub fn reset() -> Self {
|
||||
Self { foreground: None, background: None }
|
||||
}
|
||||
|
||||
pub fn foreground(name: &str) -> Self {
|
||||
Self { foreground: color_to_fg(name), background: None }
|
||||
}
|
||||
|
||||
pub fn with_foreground(self, name: &str) -> Self {
|
||||
Self { foreground: color_to_fg(name), background: self.background }
|
||||
}
|
||||
|
||||
pub fn background(name: &str) -> Self {
|
||||
Self { foreground: None, background: color_to_bg(name) }
|
||||
}
|
||||
|
||||
pub fn with_background(self, name: &str) -> Self {
|
||||
Self { foreground: self.foreground, background: color_to_bg(name) }
|
||||
}
|
||||
|
||||
pub fn color(name: &str) -> Self {
|
||||
Self::foreground(name)
|
||||
}
|
||||
|
||||
pub fn with_color(self, name: &str) -> Self {
|
||||
self.with_foreground(name)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Style {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(fg) = self.foreground {
|
||||
if let Some(bg) = self.background {
|
||||
write!(f, "\x1b[{};{}m", fg, bg)
|
||||
} else {
|
||||
write!(f, "\x1b[{}m", fg)
|
||||
}
|
||||
} else if let Some(bg) = self.background {
|
||||
write!(f, "\x1b[{}m", bg)
|
||||
} else {
|
||||
write!(f, "\x1b[0m")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn color_to_fg(name: &str) -> Option<usize> {
|
||||
match name {
|
||||
"Black" => Some(30),
|
||||
"Red" => Some(31),
|
||||
"Green" => Some(32),
|
||||
"Brown" => Some(33),
|
||||
"Blue" => Some(34),
|
||||
"Magenta" => Some(35),
|
||||
"Cyan" => Some(36),
|
||||
"LightGray" => Some(37),
|
||||
"DarkGray" => Some(90),
|
||||
"LightRed" => Some(91),
|
||||
"LightGreen" => Some(92),
|
||||
"Yellow" => Some(93),
|
||||
"LightBlue" => Some(94),
|
||||
"Pink" => Some(95),
|
||||
"LightCyan" => Some(96),
|
||||
"White" => Some(97),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn color_to_bg(name: &str) -> Option<usize> {
|
||||
if let Some(fg) = color_to_fg(name) {
|
||||
Some(fg + 10)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref STDIN: Mutex<String> = Mutex::new(String::new());
|
||||
pub static ref ECHO: Mutex<bool> = Mutex::new(true);
|
||||
|
@ -98,7 +16,7 @@ pub fn has_cursor() -> bool {
|
|||
|
||||
pub fn clear_row_after(x: usize) {
|
||||
if cfg!(feature = "video") {
|
||||
kernel::vga::clear_row_after(x);
|
||||
sys::vga::clear_row_after(x);
|
||||
} else {
|
||||
print!("\r"); // Move cursor to begining of line
|
||||
print!("\x1b[{}C", x); // Move cursor forward to position
|
||||
|
@ -108,7 +26,7 @@ pub fn clear_row_after(x: usize) {
|
|||
|
||||
pub fn cursor_position() -> (usize, usize) {
|
||||
if cfg!(feature = "video") {
|
||||
kernel::vga::cursor_position()
|
||||
sys::vga::cursor_position()
|
||||
} else {
|
||||
print!("\x1b[6n"); // Ask cursor position
|
||||
get_char(); // ESC
|
||||
|
@ -137,7 +55,7 @@ pub fn cursor_position() -> (usize, usize) {
|
|||
|
||||
pub fn set_writer_position(x: usize, y: usize) {
|
||||
if cfg!(feature = "video") {
|
||||
kernel::vga::set_writer_position(x, y);
|
||||
sys::vga::set_writer_position(x, y);
|
||||
} else {
|
||||
print!("\x1b[{};{}H", y + 1, x + 1);
|
||||
}
|
||||
|
@ -147,9 +65,9 @@ pub fn set_writer_position(x: usize, y: usize) {
|
|||
macro_rules! print {
|
||||
($($arg:tt)*) => ({
|
||||
if cfg!(feature="video") {
|
||||
$crate::kernel::vga::print_fmt(format_args!($($arg)*));
|
||||
$crate::sys::vga::print_fmt(format_args!($($arg)*));
|
||||
} else {
|
||||
$crate::kernel::serial::print_fmt(format_args!($($arg)*));
|
||||
$crate::sys::serial::print_fmt(format_args!($($arg)*));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -158,15 +76,15 @@ macro_rules! print {
|
|||
macro_rules! log {
|
||||
($($arg:tt)*) => ({
|
||||
if !cfg!(test) {
|
||||
let uptime = $crate::kernel::clock::uptime();
|
||||
let csi_color = $crate::kernel::console::Style::color("LightGreen");
|
||||
let csi_reset = $crate::kernel::console::Style::reset();
|
||||
let uptime = $crate::sys::clock::uptime();
|
||||
let csi_color = $crate::api::console::Style::color("LightGreen");
|
||||
let csi_reset = $crate::api::console::Style::reset();
|
||||
if cfg!(feature="video") {
|
||||
$crate::kernel::vga::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset));
|
||||
$crate::kernel::vga::print_fmt(format_args!($($arg)*));
|
||||
$crate::sys::vga::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset));
|
||||
$crate::sys::vga::print_fmt(format_args!($($arg)*));
|
||||
} else {
|
||||
$crate::kernel::serial::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset));
|
||||
$crate::kernel::serial::print_fmt(format_args!($($arg)*));
|
||||
$crate::sys::serial::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset));
|
||||
$crate::sys::serial::print_fmt(format_args!($($arg)*));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -243,10 +161,10 @@ pub fn drain() {
|
|||
}
|
||||
|
||||
pub fn get_char() -> char {
|
||||
kernel::console::disable_echo();
|
||||
kernel::console::enable_raw();
|
||||
sys::console::disable_echo();
|
||||
sys::console::enable_raw();
|
||||
loop {
|
||||
kernel::time::halt();
|
||||
sys::time::halt();
|
||||
let res = interrupts::without_interrupts(|| {
|
||||
let mut stdin = STDIN.lock();
|
||||
match stdin.chars().next_back() {
|
||||
|
@ -260,8 +178,8 @@ pub fn get_char() -> char {
|
|||
}
|
||||
});
|
||||
if let Some(c) = res {
|
||||
kernel::console::enable_echo();
|
||||
kernel::console::disable_raw();
|
||||
sys::console::enable_echo();
|
||||
sys::console::disable_raw();
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +187,7 @@ pub fn get_char() -> char {
|
|||
|
||||
pub fn get_line() -> String {
|
||||
loop {
|
||||
kernel::time::halt();
|
||||
sys::time::halt();
|
||||
let res = interrupts::without_interrupts(|| {
|
||||
let mut stdin = STDIN.lock();
|
||||
match stdin.chars().next_back() {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, log};
|
||||
use crate::{sys, log};
|
||||
use alloc::format;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
@ -42,7 +42,7 @@ pub fn realpath(pathname: &str) -> String {
|
|||
if pathname.starts_with("/") {
|
||||
pathname.into()
|
||||
} else {
|
||||
let dirname = kernel::process::dir();
|
||||
let dirname = sys::process::dir();
|
||||
let sep = if dirname.ends_with("/") { "" } else { "/" };
|
||||
format!("{}{}{}", dirname, sep, pathname)
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ pub struct File {
|
|||
addr: u32,
|
||||
size: u32,
|
||||
dir: Dir, // TODO: Replace with `parent: Some(Dir)` and also add it to `Dir`
|
||||
// TODO: add `offset: usize`
|
||||
}
|
||||
|
||||
impl File {
|
||||
|
@ -87,6 +88,9 @@ impl File {
|
|||
self.size as usize
|
||||
}
|
||||
|
||||
// TODO: return `Result<usize>`
|
||||
// TODO: start `i` at `self.offset` instead of `0`
|
||||
// TODO: set `self.offset` to `i` at the end
|
||||
pub fn read(&self, buf: &mut [u8]) -> usize {
|
||||
let buf_len = buf.len();
|
||||
let mut addr = self.addr;
|
||||
|
@ -109,6 +113,11 @@ impl File {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: add `seek(&mut self, pos: SeekFrom) -> Result<u32>`
|
||||
|
||||
// TODO: add `read_to_end(&self, buf: &mut Vec<u8>) -> Result<u32>`
|
||||
|
||||
// TODO: `return Result<String>`
|
||||
pub fn read_to_string(&self) -> String {
|
||||
let mut buf: Vec<u8> = Vec::with_capacity(self.size());
|
||||
buf.resize(self.size(), 0);
|
||||
|
@ -117,6 +126,9 @@ impl File {
|
|||
String::from_utf8(buf).unwrap()
|
||||
}
|
||||
|
||||
// TODO: `return Result<usize>`
|
||||
// TODO: start `i` at `self.offset` instead of `0`
|
||||
// TODO: set `self.offset` to `i` at the end
|
||||
pub fn write(&mut self, buf: &[u8]) -> Result<(), ()> {
|
||||
let buf_len = buf.len();
|
||||
let mut addr = self.addr;
|
||||
|
@ -650,11 +662,11 @@ impl BlockDevice {
|
|||
}
|
||||
|
||||
pub fn read(&self, block: u32, mut buf: &mut [u8]) {
|
||||
kernel::ata::read(self.bus, self.dsk, block, &mut buf);
|
||||
sys::ata::read(self.bus, self.dsk, block, &mut buf);
|
||||
}
|
||||
|
||||
pub fn write(&self, block: u32, buf: &[u8]) {
|
||||
kernel::ata::write(self.bus, self.dsk, block, &buf);
|
||||
sys::ata::write(self.bus, self.dsk, block, &buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -685,7 +697,7 @@ pub fn init() {
|
|||
for bus in 0..2 {
|
||||
for dsk in 0..2 {
|
||||
let mut buf = [0u8; 512];
|
||||
kernel::ata::read(bus, dsk, SUPERBLOCK_ADDR, &mut buf);
|
||||
sys::ata::read(bus, dsk, SUPERBLOCK_ADDR, &mut buf);
|
||||
if let Ok(header) = String::from_utf8(buf[0..8].to_vec()) {
|
||||
if header == MAGIC {
|
||||
log!("MFS Superblock found in ATA {}:{}\n", bus, dsk);
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, print};
|
||||
use crate::{sys, print};
|
||||
use lazy_static::lazy_static;
|
||||
use spin::Mutex;
|
||||
use x86_64::instructions::interrupts;
|
||||
|
@ -14,7 +14,7 @@ pub fn init() {
|
|||
|
||||
// Translate IRQ into system interrupt
|
||||
fn interrupt_index(irq: u8) -> u8 {
|
||||
kernel::pic::PIC_1_OFFSET + irq
|
||||
sys::pic::PIC_1_OFFSET + irq
|
||||
}
|
||||
|
||||
fn default_irq_handler() {
|
||||
|
@ -27,7 +27,7 @@ lazy_static! {
|
|||
let mut idt = InterruptDescriptorTable::new();
|
||||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||
unsafe {
|
||||
idt.double_fault.set_handler_fn(double_fault_handler).set_stack_index(kernel::gdt::DOUBLE_FAULT_IST_INDEX);
|
||||
idt.double_fault.set_handler_fn(double_fault_handler).set_stack_index(sys::gdt::DOUBLE_FAULT_IST_INDEX);
|
||||
}
|
||||
idt[interrupt_index(0) as usize].set_handler_fn(irq0_handler);
|
||||
idt[interrupt_index(1) as usize].set_handler_fn(irq1_handler);
|
||||
|
@ -55,7 +55,7 @@ macro_rules! irq_handler {
|
|||
pub extern "x86-interrupt" fn $handler(_stack_frame: InterruptStackFrame) {
|
||||
let handlers = IRQ_HANDLERS.lock();
|
||||
handlers[$irq]();
|
||||
unsafe { kernel::pic::PICS.lock().notify_end_of_interrupt(interrupt_index($irq)); }
|
||||
unsafe { sys::pic::PICS.lock().notify_end_of_interrupt(interrupt_index($irq)); }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -167,8 +167,8 @@ extern "sysv64" fn syscall_handler(_stack_frame: &mut InterruptStackFrame, regs:
|
|||
let arg1 = regs.rdi;
|
||||
let arg2 = regs.rsi;
|
||||
let arg3 = regs.rdx;
|
||||
regs.rax = kernel::syscall::dispatcher(n, arg1, arg2, arg3);
|
||||
unsafe { kernel::pic::PICS.lock().notify_end_of_interrupt(0x80) };
|
||||
regs.rax = sys::syscall::dispatcher(n, arg1, arg2, arg3);
|
||||
unsafe { sys::pic::PICS.lock().notify_end_of_interrupt(0x80) };
|
||||
}
|
||||
|
||||
pub fn set_irq_handler(irq: u8, handler: fn()) {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::kernel;
|
||||
use crate::sys;
|
||||
use lazy_static::lazy_static;
|
||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, KeyCode, Keyboard, ScancodeSet1};
|
||||
use spin::Mutex;
|
||||
|
@ -39,11 +39,11 @@ pub fn init() {
|
|||
let res = unsafe {
|
||||
port.read()
|
||||
};
|
||||
print!("[{:.6}] keyboard: identify {:#X}\n", kernel::clock::uptime(), res);
|
||||
print!("[{:.6}] keyboard: identify {:#X}\n", sys::clock::uptime(), res);
|
||||
let res = unsafe {
|
||||
port.read()
|
||||
};
|
||||
print!("[{:.6}] keyboard: identify {:#X}\n", kernel::clock::uptime(), res);
|
||||
print!("[{:.6}] keyboard: identify {:#X}\n", sys::clock::uptime(), res);
|
||||
|
||||
// Self-test
|
||||
let res = unsafe {
|
||||
|
@ -57,9 +57,9 @@ pub fn init() {
|
|||
port.read()
|
||||
};
|
||||
if res == 0xAA { // 0xAA == Passed, 0xFC or 0xFD == Failed, 0xFE == Resend
|
||||
print!("[{:.6}] keyboard: self test passed\n", kernel::clock::uptime());
|
||||
print!("[{:.6}] keyboard: self test passed\n", sys::clock::uptime());
|
||||
} else {
|
||||
print!("[{:.6}] keyboard: self test failed ({:#X})\n", kernel::clock::uptime(), res);
|
||||
print!("[{:.6}] keyboard: self test failed ({:#X})\n", sys::clock::uptime(), res);
|
||||
}
|
||||
|
||||
// Switch to scancode set 2
|
||||
|
@ -72,9 +72,9 @@ pub fn init() {
|
|||
if res != 0xFA { // 0xFA == ACK, 0xFE == Resend
|
||||
return init();
|
||||
}
|
||||
print!("[{:.6}] keyboard: switch to scancode set 2\n", kernel::clock::uptime());
|
||||
print!("[{:.6}] keyboard: switch to scancode set 2\n", sys::clock::uptime());
|
||||
*/
|
||||
kernel::idt::set_irq_handler(1, interrupt_handler);
|
||||
sys::idt::set_irq_handler(1, interrupt_handler);
|
||||
}
|
||||
|
||||
fn read_scancode() -> u8 {
|
||||
|
@ -95,7 +95,7 @@ fn interrupt_handler() {
|
|||
DecodedKey::RawKey(KeyCode::ArrowDown) => '↓', // U+2193
|
||||
DecodedKey::RawKey(_) => { return; }
|
||||
};
|
||||
kernel::console::key_handle(c);
|
||||
sys::console::key_handle(c);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, log};
|
||||
use crate::{sys, log};
|
||||
use bootloader::bootinfo::{BootInfo, MemoryMap, MemoryRegionType};
|
||||
use x86_64::structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB, Translate};
|
||||
use x86_64::{PhysAddr, VirtAddr};
|
||||
|
@ -20,7 +20,7 @@ pub fn init(boot_info: &'static BootInfo) {
|
|||
|
||||
let mut mapper = unsafe { mapper(VirtAddr::new(PHYS_MEM_OFFSET)) };
|
||||
let mut frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) };
|
||||
kernel::allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");
|
||||
sys::allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");
|
||||
}
|
||||
|
||||
pub fn phys_to_virt(addr: PhysAddr) -> VirtAddr {
|
|
@ -5,7 +5,6 @@ pub mod clock;
|
|||
pub mod cmos;
|
||||
pub mod console;
|
||||
pub mod cpu;
|
||||
pub mod fonts;
|
||||
pub mod fs;
|
||||
pub mod gdt;
|
||||
pub mod idt;
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{kernel, log, print, user};
|
||||
use crate::kernel::allocator::PhysBuf;
|
||||
use crate::kernel::net::Stats;
|
||||
use crate::{sys, usr, log, print};
|
||||
use crate::sys::allocator::PhysBuf;
|
||||
use crate::sys::net::Stats;
|
||||
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
|
@ -258,7 +258,7 @@ impl PCNET {
|
|||
|
||||
// Wait until init is done
|
||||
while !self.ports.read_csr_32(0).get_bit(CSR0_IDON) {
|
||||
kernel::time::halt();
|
||||
sys::time::halt();
|
||||
}
|
||||
assert!(self.ports.read_csr_32(0) == 0b110000001); // IDON + INTR + INIT
|
||||
|
||||
|
@ -347,7 +347,7 @@ impl<'a> Device<'a> for PCNET {
|
|||
self.stats.rx_add(packet.len() as u64);
|
||||
if self.debug_mode {
|
||||
//print!("Size: {} bytes\n", packet.len());
|
||||
user::hex::print_hex(&packet);
|
||||
usr::hex::print_hex(&packet);
|
||||
//print!("CSR0: {:016b}\n", self.ports.read_csr_32(0));
|
||||
//print!("RDTE: {:016b}\n", self.rx_des[rx_id * DE_LEN + 7]);
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ impl phy::TxToken for TxToken {
|
|||
self.device.stats.tx_add(len as u64);
|
||||
if self.device.debug_mode {
|
||||
//print!("Size: {} bytes\n", len);
|
||||
user::hex::print_hex(&buf);
|
||||
usr::hex::print_hex(&buf);
|
||||
//print!("CSR0: {:016b}\n", self.device.ports.read_csr_32(0));
|
||||
}
|
||||
|
||||
|
@ -436,7 +436,7 @@ impl phy::TxToken for TxToken {
|
|||
}
|
||||
|
||||
pub fn init() {
|
||||
if let Some(mut pci_device) = kernel::pci::find_device(0x1022, 0x2000) {
|
||||
if let Some(mut pci_device) = sys::pci::find_device(0x1022, 0x2000) {
|
||||
pci_device.enable_bus_mastering();
|
||||
let io_base = (pci_device.base_addresses[0] as u16) & 0xFFF0;
|
||||
let mut net_device = PCNET::new(io_base);
|
||||
|
@ -456,7 +456,7 @@ pub fn init() {
|
|||
routes(routes).
|
||||
finalize();
|
||||
|
||||
*kernel::net::IFACE.lock() = Some(iface);
|
||||
*sys::net::IFACE.lock() = Some(iface);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{kernel, log, print, user};
|
||||
use crate::kernel::allocator::PhysBuf;
|
||||
use crate::kernel::net::Stats;
|
||||
use crate::{sys, usr, log, print};
|
||||
use crate::sys::allocator::PhysBuf;
|
||||
use crate::sys::net::Stats;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::vec::Vec;
|
||||
use array_macro::array;
|
||||
|
@ -256,7 +256,7 @@ impl<'a> Device<'a> for RTL8139 {
|
|||
//print!("Size: {} bytes\n", len);
|
||||
//print!("CRC: {:#08X}\n", crc);
|
||||
//print!("RX Offset: {}\n", offset);
|
||||
user::hex::print_hex(&self.rx_buffer[(offset + 4)..(offset + n)]);
|
||||
usr::hex::print_hex(&self.rx_buffer[(offset + 4)..(offset + n)]);
|
||||
}
|
||||
self.stats.rx_add(len as u64);
|
||||
|
||||
|
@ -353,7 +353,7 @@ impl phy::TxToken for TxToken {
|
|||
self.device.stats.tx_add(len as u64);
|
||||
if self.device.debug_mode {
|
||||
//print!("Size: {} bytes\n", len);
|
||||
user::hex::print_hex(&buf[0..len]);
|
||||
usr::hex::print_hex(&buf[0..len]);
|
||||
}
|
||||
|
||||
res
|
||||
|
@ -361,7 +361,7 @@ impl phy::TxToken for TxToken {
|
|||
}
|
||||
|
||||
pub fn init() {
|
||||
if let Some(mut pci_device) = kernel::pci::find_device(0x10EC, 0x8139) {
|
||||
if let Some(mut pci_device) = sys::pci::find_device(0x10EC, 0x8139) {
|
||||
pci_device.enable_bus_mastering();
|
||||
|
||||
let io_base = (pci_device.base_addresses[0] as u16) & 0xFFF0;
|
||||
|
@ -382,17 +382,17 @@ pub fn init() {
|
|||
routes(routes).
|
||||
finalize();
|
||||
|
||||
*kernel::net::IFACE.lock() = Some(iface);
|
||||
*sys::net::IFACE.lock() = Some(iface);
|
||||
}
|
||||
|
||||
//let irq = pci_device.interrupt_line;
|
||||
//kernel::idt::set_irq_handler(irq, interrupt_handler);
|
||||
//sys::idt::set_irq_handler(irq, interrupt_handler);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interrupt_handler() {
|
||||
print!("RTL8139 interrupt!\n");
|
||||
if let Some(mut guard) = kernel::net::IFACE.try_lock() {
|
||||
if let Some(mut guard) = sys::net::IFACE.try_lock() {
|
||||
if let Some(ref mut iface) = *guard {
|
||||
unsafe { iface.device_mut().ports.isr.write(0xffff) } // Clear the interrupt
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::kernel;
|
||||
use crate::sys;
|
||||
use core::fmt;
|
||||
use core::fmt::Write;
|
||||
use lazy_static::lazy_static;
|
||||
|
@ -40,7 +40,7 @@ pub fn print_fmt(args: fmt::Arguments) {
|
|||
}
|
||||
|
||||
pub fn init() {
|
||||
kernel::idt::set_irq_handler(4, interrupt_handler);
|
||||
sys::idt::set_irq_handler(4, interrupt_handler);
|
||||
}
|
||||
|
||||
fn interrupt_handler() {
|
||||
|
@ -50,5 +50,5 @@ fn interrupt_handler() {
|
|||
'\x7F' => '\x08', // Delete => Backspace
|
||||
c => c,
|
||||
};
|
||||
kernel::console::key_handle(c);
|
||||
sys::console::key_handle(c);
|
||||
}
|
|
@ -76,15 +76,15 @@ pub unsafe fn syscall3(n: usize, arg1: usize, arg2: usize, arg3: usize) -> usize
|
|||
#[macro_export]
|
||||
macro_rules! syscall {
|
||||
($n:expr) => (
|
||||
$crate::kernel::syscall::syscall0(
|
||||
$crate::sys::syscall::syscall0(
|
||||
$n as usize));
|
||||
($n:expr, $a1:expr) => (
|
||||
$crate::kernel::syscall::syscall1(
|
||||
$crate::sys::syscall::syscall1(
|
||||
$n as usize, $a1 as usize));
|
||||
($n:expr, $a1:expr, $a2:expr) => (
|
||||
$crate::kernel::syscall::syscall2(
|
||||
$crate::sys::syscall::syscall2(
|
||||
$n as usize, $a1 as usize, $a2 as usize));
|
||||
($n:expr, $a1:expr, $a2:expr, $a3:expr) => (
|
||||
$crate::kernel::syscall::syscall3(
|
||||
$crate::sys::syscall::syscall3(
|
||||
$n as usize, $a1 as usize, $a2 as usize, $a3 as usize));
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
use crate::kernel;
|
||||
use crate::sys;
|
||||
|
||||
pub fn sleep(seconds: f64) {
|
||||
unsafe { asm!("sti") }; // Restore interrupts
|
||||
kernel::time::sleep(seconds);
|
||||
sys::time::sleep(seconds);
|
||||
unsafe { asm!("cli") }; // Disable interrupts
|
||||
}
|
||||
|
||||
pub fn uptime() -> f64 {
|
||||
kernel::clock::uptime()
|
||||
sys::clock::uptime()
|
||||
}
|
||||
|
||||
pub fn realtime() -> f64 {
|
||||
kernel::clock::realtime()
|
||||
sys::clock::realtime()
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::kernel;
|
||||
use crate::kernel::cmos::CMOS;
|
||||
use crate::sys;
|
||||
use crate::sys::cmos::CMOS;
|
||||
use core::hint::spin_loop;
|
||||
use core::sync::atomic::{AtomicUsize, AtomicU64, Ordering};
|
||||
use x86_64::instructions::interrupts;
|
||||
|
@ -41,8 +41,8 @@ fn rdtsc() -> u64 {
|
|||
}
|
||||
|
||||
pub fn sleep(seconds: f64) {
|
||||
let start = kernel::clock::uptime();
|
||||
while kernel::clock::uptime() - start < seconds {
|
||||
let start = sys::clock::uptime();
|
||||
while sys::clock::uptime() - start < seconds {
|
||||
halt();
|
||||
}
|
||||
}
|
||||
|
@ -82,10 +82,10 @@ pub fn init() {
|
|||
// PIT timmer
|
||||
let divider = if PIT_DIVIDER < 65536 { PIT_DIVIDER } else { 0 };
|
||||
set_pit_frequency_divider(divider as u16);
|
||||
kernel::idt::set_irq_handler(0, pit_interrupt_handler);
|
||||
sys::idt::set_irq_handler(0, pit_interrupt_handler);
|
||||
|
||||
// RTC timmer
|
||||
kernel::idt::set_irq_handler(8, rtc_interrupt_handler);
|
||||
sys::idt::set_irq_handler(8, rtc_interrupt_handler);
|
||||
CMOS::new().enable_update_interrupt();
|
||||
|
||||
// TSC timmer
|
|
@ -1,4 +1,6 @@
|
|||
use crate::kernel::fonts::Font;
|
||||
use crate::api::font::Font;
|
||||
use crate::api::vga::{Color, Palette};
|
||||
use crate::api::vga::color;
|
||||
use bit_field::BitField;
|
||||
use core::fmt;
|
||||
use core::fmt::Write;
|
||||
|
@ -25,93 +27,6 @@ lazy_static! {
|
|||
});
|
||||
}
|
||||
|
||||
/// The standard color palette in VGA text mode
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum Color {
|
||||
Black = 0,
|
||||
Blue = 1,
|
||||
Green = 2,
|
||||
Cyan = 3,
|
||||
Red = 4,
|
||||
Magenta = 5,
|
||||
Brown = 6,
|
||||
LightGray = 7,
|
||||
DarkGray = 8,
|
||||
LightBlue = 9,
|
||||
LightGreen = 10,
|
||||
LightCyan = 11,
|
||||
LightRed = 12,
|
||||
Pink = 13,
|
||||
Yellow = 14,
|
||||
White = 15,
|
||||
}
|
||||
|
||||
const COLORS: [Color; 16] = [
|
||||
Color::Black,
|
||||
Color::Blue,
|
||||
Color::Green,
|
||||
Color::Cyan,
|
||||
Color::Red,
|
||||
Color::Magenta,
|
||||
Color::Brown,
|
||||
Color::LightGray,
|
||||
Color::DarkGray,
|
||||
Color::LightBlue,
|
||||
Color::LightGreen,
|
||||
Color::LightCyan,
|
||||
Color::LightRed,
|
||||
Color::Pink,
|
||||
Color::Yellow,
|
||||
Color::White,
|
||||
];
|
||||
|
||||
fn color_from_ansi(code: u8) -> Color {
|
||||
match code {
|
||||
30 => Color::Black,
|
||||
31 => Color::Red,
|
||||
32 => Color::Green,
|
||||
33 => Color::Brown,
|
||||
34 => Color::Blue,
|
||||
35 => Color::Magenta,
|
||||
36 => Color::Cyan,
|
||||
37 => Color::LightGray,
|
||||
90 => Color::DarkGray,
|
||||
91 => Color::LightRed,
|
||||
92 => Color::LightGreen,
|
||||
93 => Color::Yellow,
|
||||
94 => Color::LightBlue,
|
||||
95 => Color::Pink,
|
||||
96 => Color::LightCyan,
|
||||
97 => Color::White,
|
||||
_ => FG, // Error
|
||||
}
|
||||
}
|
||||
|
||||
impl Color {
|
||||
fn to_palette_code(&self) -> u8 {
|
||||
match self {
|
||||
Color::Black => 0x00,
|
||||
Color::Blue => 0x01,
|
||||
Color::Green => 0x02,
|
||||
Color::Cyan => 0x03,
|
||||
Color::Red => 0x04,
|
||||
Color::Magenta => 0x05,
|
||||
Color::LightGray => 0x07,
|
||||
Color::Brown => 0x14,
|
||||
Color::DarkGray => 0x38,
|
||||
Color::LightBlue => 0x39,
|
||||
Color::LightGreen => 0x3A,
|
||||
Color::LightCyan => 0x3B,
|
||||
Color::LightRed => 0x3C,
|
||||
Color::Pink => 0x3D,
|
||||
Color::Yellow => 0x3E,
|
||||
Color::White => 0x3F,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
struct ColorCode(u8);
|
||||
|
@ -263,8 +178,8 @@ impl Writer {
|
|||
|
||||
pub fn color(&self) -> (Color, Color) {
|
||||
let cc = self.color_code.0;
|
||||
let fg = COLORS[cc.get_bits(0..4) as usize];
|
||||
let bg = COLORS[cc.get_bits(4..8) as usize];
|
||||
let fg = color::from_index(cc.get_bits(0..4) as usize);
|
||||
let bg = color::from_index(cc.get_bits(4..8) as usize);
|
||||
(fg, bg)
|
||||
}
|
||||
|
||||
|
@ -306,7 +221,7 @@ impl Writer {
|
|||
let mut data: Port<u8> = Port::new(0x03C9); // Data Register
|
||||
for (i, r, g, b) in palette.colors {
|
||||
if i < 16 {
|
||||
let code = COLORS[i as usize].to_palette_code();
|
||||
let code = color::from_index(i as usize).to_palette_code();
|
||||
unsafe {
|
||||
addr.write(code);
|
||||
data.write(r >> 2); // Convert 8-bit color to 6-bit color
|
||||
|
@ -340,10 +255,10 @@ impl Perform for Writer {
|
|||
bg = BG;
|
||||
},
|
||||
30..=37 | 90..=97 => {
|
||||
fg = color_from_ansi(param[0] as u8);
|
||||
fg = color::from_ansi(param[0] as u8);
|
||||
},
|
||||
40..=47 | 100..=107 => {
|
||||
bg = color_from_ansi((param[0] as u8) - 10);
|
||||
bg = color::from_ansi((param[0] as u8) - 10);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
@ -434,10 +349,6 @@ pub fn set_color(foreground: Color, background: Color) {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn colors() -> [Color; 16] {
|
||||
COLORS
|
||||
}
|
||||
|
||||
// Printable ascii chars + backspace + newline + ext chars
|
||||
pub fn is_printable(c: u8) -> bool {
|
||||
match c {
|
||||
|
@ -458,10 +369,6 @@ pub fn set_palette(palette: Palette) {
|
|||
})
|
||||
}
|
||||
|
||||
pub struct Palette {
|
||||
pub colors: [(u8, u8, u8, u8); 16]
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
let mut isr: Port<u8> = Port::new(0x03DA); // Input Status Register
|
||||
let mut aadr: Port<u8> = Port::new(0x03C0); // Attribute Address/Data Register
|
|
@ -1,6 +0,0 @@
|
|||
use crate::{kernel, user};
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
kernel::vga::clear_screen();
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::kernel::console::Style;
|
||||
use alloc::string::ToString;
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
let width = kernel::allocator::size().to_string().len();
|
||||
let color = Style::color("LightCyan");
|
||||
let reset = Style::reset();
|
||||
print!("{}Size:{} {:width$}\n", color, reset, kernel::allocator::size(), width = width);
|
||||
print!("{}Used:{} {:width$}\n", color, reset, kernel::allocator::used(), width = width);
|
||||
print!("{}Free:{} {:width$}\n", color, reset, kernel::allocator::free(), width = width);
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
use crate::user;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
if args.len() != 3 {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
// TODO: Avoid doing copy+delete
|
||||
match user::copy::main(args) {
|
||||
user::shell::ExitCode::CommandSuccessful => user::delete::main(&args[0..2]),
|
||||
_ => user::shell::ExitCode::CommandError,
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
use crate::user;
|
||||
use crate::api::syscall;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
if args.len() == 2 {
|
||||
if let Ok(duration) = args[1].parse::<f64>() {
|
||||
syscall::sleep(duration);
|
||||
return user::shell::ExitCode::CommandSuccessful;
|
||||
}
|
||||
}
|
||||
user::shell::ExitCode::CommandError
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
use crate::{print, user};
|
||||
use crate::api::syscall;
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
print!("{:.6}\n", syscall::uptime());
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::kernel::vga::Palette;
|
||||
use alloc::vec::Vec;
|
||||
use core::convert::TryInto;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
if args.len() == 1 {
|
||||
print!("Usage: vga <command>\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
}
|
||||
match args[1] {
|
||||
"set" => {
|
||||
if args.len() == 4 && args[2] == "font" {
|
||||
if let Some(file) = kernel::fs::File::open(args[3]) {
|
||||
let size = file.size();
|
||||
let mut buf = Vec::with_capacity(size);
|
||||
buf.resize(size, 0);
|
||||
file.read(&mut buf);
|
||||
if let Ok(font) = kernel::fonts::from_bytes(&buf) {
|
||||
kernel::vga::set_font(&font);
|
||||
} else {
|
||||
print!("Could not parse font file\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
} else if args.len() == 4 && args[2] == "palette" {
|
||||
if let Some(file) = kernel::fs::File::open(args[3]) {
|
||||
let mut colors = Vec::with_capacity(16);
|
||||
for line in file.read_to_string().split("\n") {
|
||||
let line = line.split("#").next().unwrap();
|
||||
let color: Vec<u8> = line.split(",").filter_map(|value| {
|
||||
let radix = if value.contains("0x") { 16 } else { 10 };
|
||||
let value = value.trim().trim_start_matches("0x");
|
||||
u8::from_str_radix(value, radix).ok()
|
||||
}).collect();
|
||||
if color.len() == 4 {
|
||||
colors.push((color[0], color[1], color[2], color[3]));
|
||||
}
|
||||
}
|
||||
if let Ok(colors) = colors.try_into() {
|
||||
let palette = Palette { colors };
|
||||
kernel::vga::set_palette(palette);
|
||||
} else {
|
||||
print!("Could not parse palette file\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
print!("Invalid command\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
print!("Invalid command\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
use crate::{print, user};
|
||||
use crate::{usr, print};
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 2 {
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
} else {
|
||||
let buf = encode(args[1].as_bytes());
|
||||
let encoded = String::from_utf8(buf).unwrap();
|
||||
print!("{}\n", encoded);
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
use crate::{sys, usr};
|
||||
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
sys::vga::clear_screen();
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{print, user};
|
||||
use crate::{usr, print};
|
||||
use alloc::format;
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
let csi_reset = "\x1b[0m";
|
||||
|
||||
for i in 30..38 {
|
||||
|
@ -25,5 +25,5 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
print!("\n");
|
||||
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 3 {
|
||||
print!("Usage: copy <source> <dest>\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let source = args[1];
|
||||
|
@ -12,30 +12,30 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
|
||||
if dest.starts_with("/dev") || dest.starts_with("/sys") {
|
||||
print!("Permission denied to write to '{}'\n", dest);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
if let Some(source_file) = kernel::fs::File::open(source) {
|
||||
if let Some(mut dest_file) = kernel::fs::File::create(dest) {
|
||||
if let Some(source_file) = sys::fs::File::open(source) {
|
||||
if let Some(mut dest_file) = sys::fs::File::create(dest) {
|
||||
let filesize = source_file.size();
|
||||
let mut buf = Vec::with_capacity(filesize);
|
||||
buf.resize(filesize, 0);
|
||||
source_file.read(&mut buf);
|
||||
match dest_file.write(&buf) {
|
||||
Ok(()) => {
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
},
|
||||
Err(()) => {
|
||||
print!("Could not write to '{}'\n", dest);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print!("Permission denied to write to '{}'\n", dest);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
} else {
|
||||
print!("File not found '{}'\n", source);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use time::{OffsetDateTime, Duration, UtcOffset};
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
let seconds = syscall::realtime(); // Since Unix Epoch
|
||||
let nanoseconds = libm::floor(1e9 * (seconds - libm::floor(seconds))) as i64;
|
||||
let date = OffsetDateTime::from_unix_timestamp(seconds as i64).to_offset(offset())
|
||||
|
@ -12,17 +12,17 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
match time::util::validate_format_string(format) {
|
||||
Ok(()) => {
|
||||
print!("{}\n", date.format(format));
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
Err(e) => {
|
||||
print!("Error: {}\n", e);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn offset() -> UtcOffset {
|
||||
if let Some(tz) = kernel::process::env("TZ") {
|
||||
if let Some(tz) = sys::process::env("TZ") {
|
||||
if let Ok(offset) = tz.parse::<i32>() {
|
||||
return UtcOffset::seconds(offset);
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 2 {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let mut pathname = args[1];
|
||||
|
||||
if pathname.starts_with("/dev") || pathname.starts_with("/sys") {
|
||||
print!("Permission denied to delete '{}'\n", pathname);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
// The commands `delete /usr/alice/` and `delete /usr/alice` are equivalent,
|
||||
|
@ -18,27 +18,27 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
pathname = pathname.trim_end_matches('/');
|
||||
}
|
||||
|
||||
if let Some(dir) = kernel::fs::Dir::open(pathname) {
|
||||
if let Some(dir) = sys::fs::Dir::open(pathname) {
|
||||
if dir.read().count() == 0 {
|
||||
if kernel::fs::Dir::delete(pathname).is_ok() {
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
if sys::fs::Dir::delete(pathname).is_ok() {
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("Could not delete directory '{}'\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
} else {
|
||||
print!("Directory '{}' not empty\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
} else if kernel::fs::File::open(pathname).is_some() {
|
||||
if kernel::fs::File::delete(pathname).is_ok() {
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
} else if sys::fs::File::open(pathname).is_some() {
|
||||
if sys::fs::File::delete(pathname).is_ok() {
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("Could not delete file '{}'\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
} else {
|
||||
print!("File not found '{}'\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use alloc::string::ToString;
|
||||
use alloc::vec;
|
||||
|
@ -9,8 +9,8 @@ use smoltcp::socket::{RawPacketMetadata, RawSocketBuffer, SocketSet};
|
|||
use smoltcp::time::Instant;
|
||||
use smoltcp::wire::{IpCidr, Ipv4Address, Ipv4Cidr};
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
let mut iface = iface;
|
||||
let mut sockets = SocketSet::new(vec![]);
|
||||
let dhcp_rx_buffer = RawSocketBuffer::new([RawPacketMetadata::EMPTY; 1], vec![0; 900]);
|
||||
|
@ -30,11 +30,11 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
loop {
|
||||
if syscall::realtime() - started > timeout {
|
||||
print!("Timeout reached\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
if kernel::console::abort() {
|
||||
if sys::console::abort() {
|
||||
print!("\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
let timestamp = Instant::from_millis((syscall::realtime() * 1000.0) as i64);
|
||||
match iface.poll(&mut sockets, timestamp) {
|
||||
|
@ -77,7 +77,7 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
print!("DNS: {}\n", dns_servers.join(", "));
|
||||
}
|
||||
|
||||
return user::shell::ExitCode::CommandSuccessful;
|
||||
return usr::shell::ExitCode::CommandSuccessful;
|
||||
}
|
||||
|
||||
if let Some(wait_duration) = iface.poll_delay(&sockets, timestamp) {
|
||||
|
@ -87,5 +87,5 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
const COMMANDS: [&'static str; 2] = ["list", "format"];
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() == 1 || !COMMANDS.contains(&args[1]) {
|
||||
return usage();
|
||||
}
|
||||
|
@ -24,36 +24,36 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
fn usage() -> user::shell::ExitCode {
|
||||
fn usage() -> usr::shell::ExitCode {
|
||||
print!("Usage: <command>\n");
|
||||
print!("\n");
|
||||
print!("Commands:\n");
|
||||
print!(" list\n");
|
||||
print!(" format <path>\n");
|
||||
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
|
||||
fn list() -> user::shell::ExitCode {
|
||||
fn list() -> usr::shell::ExitCode {
|
||||
print!("Path Name (Size)\n");
|
||||
for (bus, drive, model, serial, size, unit) in kernel::ata::list() {
|
||||
for (bus, drive, model, serial, size, unit) in sys::ata::list() {
|
||||
print!("/dev/ata/{}/{} {} {} ({} {})\n", bus, drive, model, serial, size, unit);
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
fn format(pathname: &str) -> user::shell::ExitCode {
|
||||
fn format(pathname: &str) -> usr::shell::ExitCode {
|
||||
let path: Vec<_> = pathname.split('/').collect();
|
||||
if !pathname.starts_with("/dev/ata/") || path.len() != 5 {
|
||||
print!("Could not find disk at '{}'\n", pathname);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let bus = path[3].parse().expect("Could not parse <bus>");
|
||||
let dsk = path[4].parse().expect("Could not parse <dsk>");
|
||||
kernel::fs::format(bus, dsk);
|
||||
sys::fs::format(bus, dsk);
|
||||
print!("Disk successfully formatted\n");
|
||||
print!("MFS is now mounted to '/'\n");
|
||||
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::kernel::console::Style;
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::console::Style;
|
||||
use alloc::format;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::vec::Vec;
|
||||
use core::cmp;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 2 {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let pathname = args[1];
|
||||
|
@ -20,7 +20,7 @@ struct EditorConfig {
|
|||
}
|
||||
|
||||
pub struct Editor {
|
||||
file: Option<kernel::fs::File>,
|
||||
file: Option<sys::fs::File>,
|
||||
pathname: String,
|
||||
lines: Vec<String>,
|
||||
dx: usize, // Horizontal offset
|
||||
|
@ -35,7 +35,7 @@ impl Editor {
|
|||
let mut lines = Vec::new();
|
||||
let config = EditorConfig { tab_size: 4 };
|
||||
|
||||
let file = match kernel::fs::File::open(pathname) {
|
||||
let file = match sys::fs::File::open(pathname) {
|
||||
Some(file) => {
|
||||
let contents = file.read_to_string();
|
||||
for line in contents.split('\n') {
|
||||
|
@ -45,7 +45,7 @@ impl Editor {
|
|||
},
|
||||
None => {
|
||||
lines.push(String::new());
|
||||
kernel::fs::File::create(pathname)
|
||||
sys::fs::File::create(pathname)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -54,7 +54,7 @@ impl Editor {
|
|||
Self { file, pathname, lines, dx, dy, config }
|
||||
}
|
||||
|
||||
pub fn save(&mut self) -> user::shell::ExitCode {
|
||||
pub fn save(&mut self) -> usr::shell::ExitCode {
|
||||
let mut contents = String::new();
|
||||
let n = self.lines.len();
|
||||
for i in 0..n {
|
||||
|
@ -68,22 +68,22 @@ impl Editor {
|
|||
file.write(&contents.as_bytes()).unwrap();
|
||||
let status = format!("Wrote {}L to '{}'", n, self.pathname);
|
||||
self.print_status(&status, "Yellow");
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
let status = format!("Could not write to '{}'", self.pathname);
|
||||
self.print_status(&status, "LightRed");
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
|
||||
fn print_status(&mut self, status: &str, background: &str) {
|
||||
let color = Style::color("Black").with_background(background);
|
||||
let reset = Style::reset();
|
||||
let (x, y) = kernel::vga::cursor_position();
|
||||
kernel::vga::set_writer_position(0, self.height());
|
||||
let (x, y) = sys::vga::cursor_position();
|
||||
sys::vga::set_writer_position(0, self.height());
|
||||
print!("{}{:width$}{}", color, status, reset, width = self.width());
|
||||
kernel::vga::set_writer_position(x, y);
|
||||
kernel::vga::set_cursor_position(x, y);
|
||||
sys::vga::set_writer_position(x, y);
|
||||
sys::vga::set_cursor_position(x, y);
|
||||
}
|
||||
|
||||
fn print_screen(&mut self) {
|
||||
|
@ -93,7 +93,7 @@ impl Editor {
|
|||
for y in a..b {
|
||||
rows.push(self.render_line(y));
|
||||
}
|
||||
kernel::vga::set_writer_position(0, 0);
|
||||
sys::vga::set_writer_position(0, 0);
|
||||
print!("{}", rows.join("\n"));
|
||||
|
||||
let status = format!("Editing '{}'", self.pathname);
|
||||
|
@ -124,22 +124,22 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> user::shell::ExitCode {
|
||||
kernel::vga::clear_screen();
|
||||
pub fn run(&mut self) -> usr::shell::ExitCode {
|
||||
sys::vga::clear_screen();
|
||||
self.print_screen();
|
||||
kernel::vga::set_cursor_position(0, 0);
|
||||
kernel::vga::set_writer_position(0, 0);
|
||||
sys::vga::set_cursor_position(0, 0);
|
||||
sys::vga::set_writer_position(0, 0);
|
||||
|
||||
loop {
|
||||
let (mut x, mut y) = kernel::vga::cursor_position();
|
||||
let c = kernel::console::get_char();
|
||||
let (mut x, mut y) = sys::vga::cursor_position();
|
||||
let c = sys::console::get_char();
|
||||
match c {
|
||||
'\0' => {
|
||||
continue;
|
||||
}
|
||||
'\x11' => { // Ctrl Q
|
||||
// TODO: Warn if modifications have not been saved
|
||||
kernel::vga::clear_screen();
|
||||
sys::vga::clear_screen();
|
||||
break;
|
||||
},
|
||||
'\x17' => { // Ctrl W
|
||||
|
@ -147,7 +147,7 @@ impl Editor {
|
|||
},
|
||||
'\x18' => { // Ctrl X
|
||||
let res = self.save();
|
||||
kernel::vga::clear_screen();
|
||||
sys::vga::clear_screen();
|
||||
return res;
|
||||
},
|
||||
'\n' => { // Newline
|
||||
|
@ -257,7 +257,7 @@ impl Editor {
|
|||
} else {
|
||||
x -= 1;
|
||||
let line = self.render_line(self.dy + y);
|
||||
kernel::vga::clear_row();
|
||||
sys::vga::clear_row();
|
||||
print!("{}", line);
|
||||
}
|
||||
} else { // Remove newline from previous line
|
||||
|
@ -294,7 +294,7 @@ impl Editor {
|
|||
} else { // Remove char from line
|
||||
self.lines[self.dy + y].remove(self.dx + x);
|
||||
let line = self.render_line(self.dy + y);
|
||||
kernel::vga::clear_row();
|
||||
sys::vga::clear_row();
|
||||
print!("{}", line);
|
||||
}
|
||||
},
|
||||
|
@ -314,16 +314,16 @@ impl Editor {
|
|||
self.print_screen();
|
||||
} else {
|
||||
let line = self.render_line(self.dy + y);
|
||||
kernel::vga::clear_row();
|
||||
sys::vga::clear_row();
|
||||
print!("{}", line);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
kernel::vga::set_cursor_position(x, y);
|
||||
kernel::vga::set_writer_position(x, y);
|
||||
sys::vga::set_cursor_position(x, y);
|
||||
sys::vga::set_writer_position(x, y);
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
// Move cursor past end of line to end of line or left of the screen
|
||||
|
@ -341,11 +341,11 @@ impl Editor {
|
|||
}
|
||||
|
||||
fn height(&self) -> usize {
|
||||
kernel::vga::screen_height() - 1 // Leave out one line for status line
|
||||
sys::vga::screen_height() - 1 // Leave out one line for status line
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
kernel::vga::screen_width()
|
||||
sys::vga::screen_width()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() == 1 {
|
||||
for (key, val) in kernel::process::envs() {
|
||||
for (key, val) in sys::process::envs() {
|
||||
print!("{}={}\n", key, val);
|
||||
}
|
||||
} else {
|
||||
|
@ -10,13 +10,13 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
if let Some(i) = arg.find('=') {
|
||||
let (key, mut val) = arg.split_at(i);
|
||||
val = &val[1..];
|
||||
kernel::process::set_env(key, val);
|
||||
sys::process::set_env(key, val);
|
||||
print!("{}={}\n", key, val);
|
||||
} else {
|
||||
print!("Error: could not parse '{}'\n", arg);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
use crate::{print, user};
|
||||
use crate::{usr, print};
|
||||
use crate::api::syscall;
|
||||
use alloc::format;
|
||||
use core::f64::consts::PI;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() < 2 {
|
||||
print!("Usage: <longitude> [<timestamp>]\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let longitude = args[1].parse().expect("Could not parse longitude");
|
||||
|
@ -21,7 +21,7 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
let t = libm::floor(100.0 * t) / 100.0; // Avoid rounding up 99.996 to 100.00
|
||||
print!("{}\n", format!("{:05.2}", t).replace(".", ":"));
|
||||
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
pub fn geotime(longitude: f64, timestamp: f64) -> f64 {
|
|
@ -1,11 +1,11 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use crate::kernel::console::Style;
|
||||
use crate::api::console::Style;
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
let csi_color = Style::color("Yellow");
|
||||
let csi_reset = Style::reset();
|
||||
print!("{}MOROS has reached its fate, the system is now halting.{}\n", csi_color, csi_reset);
|
||||
kernel::acpi::shutdown();
|
||||
sys::acpi::shutdown();
|
||||
loop { syscall::sleep(1.0) }
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{print, user};
|
||||
use crate::kernel::console::Style;
|
||||
use crate::{usr, print};
|
||||
use crate::api::console::Style;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() > 1 {
|
||||
help_command(args[1])
|
||||
} else {
|
||||
|
@ -9,7 +9,7 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
fn help_command(cmd: &str) -> user::shell::ExitCode {
|
||||
fn help_command(cmd: &str) -> usr::shell::ExitCode {
|
||||
match cmd {
|
||||
"date" => help_date(),
|
||||
"edit" => help_edit(),
|
||||
|
@ -17,12 +17,12 @@ fn help_command(cmd: &str) -> user::shell::ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
fn help_unknown(cmd: &str) -> user::shell::ExitCode {
|
||||
fn help_unknown(cmd: &str) -> usr::shell::ExitCode {
|
||||
print!("Help not found for command '{}'\n", cmd);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
|
||||
fn help_summary() -> user::shell::ExitCode {
|
||||
fn help_summary() -> usr::shell::ExitCode {
|
||||
let csi_color = Style::color("Yellow");
|
||||
let csi_reset = Style::reset();
|
||||
print!("{}Commands:{}\n", csi_color, csi_reset);
|
||||
|
@ -52,10 +52,10 @@ fn help_summary() -> user::shell::ExitCode {
|
|||
print!("\n");
|
||||
|
||||
print!("Made with <3 in 2019-2021 by Vincent Ollivier <v@vinc.cc>\n");
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
fn help_edit() -> user::shell::ExitCode {
|
||||
fn help_edit() -> usr::shell::ExitCode {
|
||||
let csi_color = Style::color("Yellow");
|
||||
let csi_reset = Style::reset();
|
||||
print!("MOROS text editor is somewhat inspired by Pico, but with an even smaller range\n");
|
||||
|
@ -78,10 +78,10 @@ fn help_edit() -> user::shell::ExitCode {
|
|||
let csi_reset = Style::reset();
|
||||
print!(" {}{}{} {}\n", csi_color, shortcut, csi_reset, usage);
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
fn help_date() -> user::shell::ExitCode {
|
||||
fn help_date() -> usr::shell::ExitCode {
|
||||
let csi_color = Style::color("Yellow");
|
||||
let csi_reset = Style::reset();
|
||||
print!("The date command's formatting behavior is based on strftime in C\n");
|
||||
|
@ -128,5 +128,5 @@ fn help_date() -> user::shell::ExitCode {
|
|||
let csi_reset = Style::reset();
|
||||
print!(" {}{}{} {}\n", csi_color, specifier, csi_reset, usage);
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::kernel::console::Style;
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::console::Style;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 2 {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let pathname = args[1];
|
||||
|
||||
if let Some(file) = kernel::fs::File::open(pathname) {
|
||||
if let Some(file) = sys::fs::File::open(pathname) {
|
||||
let contents = file.read_to_string();
|
||||
print_hex(contents.as_bytes());
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("File not found '{}'\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
|
@ -59,7 +59,7 @@ impl Message {
|
|||
pub fn query(qname: &str, qtype: QueryType, qclass: QueryClass) -> Self {
|
||||
let mut datagram = Vec::new();
|
||||
|
||||
let id = kernel::random::get_u16();
|
||||
let id = sys::random::get_u16();
|
||||
for b in id.to_be_bytes().iter() {
|
||||
datagram.push(*b); // Transaction ID
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> {
|
|||
let dns_port = 53;
|
||||
let server = IpEndpoint::new(dns_address, dns_port);
|
||||
|
||||
let local_port = 49152 + kernel::random::get_u16() % 16384;
|
||||
let local_port = 49152 + sys::random::get_u16() % 16384;
|
||||
let client = IpEndpoint::new(IpAddress::Unspecified, local_port);
|
||||
|
||||
let qname = name;
|
||||
|
@ -142,7 +142,7 @@ pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> {
|
|||
|
||||
enum State { Bind, Query, Response }
|
||||
let mut state = State::Bind;
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
match iface.ipv4_addr() {
|
||||
None => {
|
||||
return Err(ResponseCode::NetworkError);
|
||||
|
@ -215,20 +215,20 @@ pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 2 {
|
||||
print!("Usage: host <name>\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
let name = args[1];
|
||||
match resolve(name) {
|
||||
Ok(ip_addr) => {
|
||||
print!("{} has address {}\n", name, ip_addr);
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
Err(e) => {
|
||||
print!("Could not resolve host: {:?}\n", e);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::string::{String, ToString};
|
||||
|
@ -40,7 +40,7 @@ impl URL {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
// Parse command line options
|
||||
let mut is_verbose = false;
|
||||
let mut args: Vec<String> = args.iter().map(ToOwned::to_owned).map(ToOwned::to_owned).filter(|arg| {
|
||||
|
@ -64,7 +64,7 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
|
||||
if args.len() != 3 {
|
||||
print!("Usage: http <host> <path>\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let url = "http://".to_owned() + &args[1] + &args[2];
|
||||
|
@ -73,13 +73,13 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
let address = if url.host.ends_with(char::is_numeric) {
|
||||
IpAddress::from_str(&url.host).expect("invalid address format")
|
||||
} else {
|
||||
match user::host::resolve(&url.host) {
|
||||
match usr::host::resolve(&url.host) {
|
||||
Ok(ip_addr) => {
|
||||
ip_addr
|
||||
}
|
||||
Err(e) => {
|
||||
print!("Could not resolve host: {:?}\n", e);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -94,15 +94,15 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
enum State { Connect, Request, Response }
|
||||
let mut state = State::Connect;
|
||||
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
match iface.ipv4_addr() {
|
||||
None => {
|
||||
print!("Error: Interface not ready\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
Some(ip_addr) if ip_addr.is_unspecified() => {
|
||||
print!("Error: Interface not ready\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -113,11 +113,11 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
loop {
|
||||
if syscall::realtime() - started > timeout {
|
||||
print!("Timeout reached\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
if kernel::console::abort() {
|
||||
if sys::console::abort() {
|
||||
print!("\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
let timestamp = Instant::from_millis((syscall::realtime() * 1000.0) as i64);
|
||||
match iface.poll(&mut sockets, timestamp) {
|
||||
|
@ -133,13 +133,13 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
|
||||
state = match state {
|
||||
State::Connect if !socket.is_active() => {
|
||||
let local_port = 49152 + kernel::random::get_u16() % 16384;
|
||||
let local_port = 49152 + sys::random::get_u16() % 16384;
|
||||
if is_verbose {
|
||||
print!("* Connecting to {}:{}\n", address, url.port);
|
||||
}
|
||||
if socket.connect((address, url.port), local_port).is_err() {
|
||||
print!("Could not connect to {}:{}\n", address, url.port);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
State::Request
|
||||
}
|
||||
|
@ -193,8 +193,8 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
syscall::sleep(wait_duration.as_secs_f64());
|
||||
}
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use crate::kernel::console::Style;
|
||||
use crate::api::console::Style;
|
||||
use alloc::collections::vec_deque::VecDeque;
|
||||
use alloc::format;
|
||||
use alloc::string::String;
|
||||
|
@ -14,18 +14,18 @@ use smoltcp::socket::SocketSet;
|
|||
use smoltcp::phy::Device;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
let port = 80;
|
||||
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
match iface.ipv4_addr() {
|
||||
None => {
|
||||
print!("Error: Interface not ready\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
Some(ip_addr) if ip_addr.is_unspecified() => {
|
||||
print!("Error: Interface not ready\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -44,9 +44,9 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
let mut send_queue: VecDeque<Vec<u8>> = VecDeque::new();
|
||||
let mut tcp_active = false;
|
||||
loop {
|
||||
if kernel::console::abort() {
|
||||
if sys::console::abort() {
|
||||
print!("\n");
|
||||
return user::shell::ExitCode::CommandSuccessful;
|
||||
return usr::shell::ExitCode::CommandSuccessful;
|
||||
}
|
||||
|
||||
let timestamp = Instant::from_millis((syscall::realtime() * 1000.0) as i64);
|
||||
|
@ -111,12 +111,12 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
res.push_str(&format!("Location: {}\r\n", path.trim_end_matches('/')));
|
||||
body = format!("<h1>Moved Permanently</h1>\r\n");
|
||||
mime = "text/html";
|
||||
} else if let Some(file) = kernel::fs::File::open(path) {
|
||||
} else if let Some(file) = sys::fs::File::open(path) {
|
||||
code = 200;
|
||||
res.push_str("HTTP/1.0 200 OK\r\n");
|
||||
body = file.read_to_string().replace("\n", "\r\n");
|
||||
mime = "text/plain";
|
||||
} else if let Some(dir) = kernel::fs::Dir::open(path) {
|
||||
} else if let Some(dir) = sys::fs::Dir::open(path) {
|
||||
code = 200;
|
||||
res.push_str("HTTP/1.0 200 OK\r\n");
|
||||
body = format!("<h1>Index of {}</h1>\r\n", path);
|
||||
|
@ -138,10 +138,10 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
"PUT" => {
|
||||
if path.ends_with("/") { // Write directory
|
||||
let path = path.trim_end_matches('/');
|
||||
if kernel::fs::Dir::open(path).is_some() {
|
||||
if sys::fs::Dir::open(path).is_some() {
|
||||
code = 403;
|
||||
res.push_str("HTTP/1.0 403 Forbidden\r\n");
|
||||
} else if kernel::fs::Dir::create(path).is_none() {
|
||||
} else if sys::fs::Dir::create(path).is_none() {
|
||||
code = 500;
|
||||
res.push_str("HTTP/1.0 500 Internal Server Error\r\n");
|
||||
} else {
|
||||
|
@ -149,9 +149,9 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
res.push_str("HTTP/1.0 200 OK\r\n");
|
||||
}
|
||||
} else { // Write file
|
||||
let maybe_file = match kernel::fs::File::open(path) {
|
||||
let maybe_file = match sys::fs::File::open(path) {
|
||||
Some(file) => Some(file),
|
||||
None => kernel::fs::File::create(path),
|
||||
None => sys::fs::File::create(path),
|
||||
};
|
||||
match maybe_file {
|
||||
Some(mut file) => {
|
||||
|
@ -173,8 +173,8 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
mime = "text/plain";
|
||||
},
|
||||
"DELETE" => {
|
||||
if kernel::fs::File::open(path).is_some() {
|
||||
if kernel::fs::File::delete(path).is_ok() {
|
||||
if sys::fs::File::open(path).is_some() {
|
||||
if sys::fs::File::delete(path).is_ok() {
|
||||
code = 200;
|
||||
res.push_str("HTTP/1.0 200 OK\r\n");
|
||||
} else {
|
||||
|
@ -235,7 +235,7 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
} else {
|
||||
print!("Error: Could not find network interface\n");
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,27 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::kernel::console::Style;
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::console::Style;
|
||||
use alloc::string::String;
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
let csi_color = Style::color("Yellow");
|
||||
let csi_reset = Style::reset();
|
||||
print!("{}Welcome to MOROS v{} installation program!{}\n", csi_color, env!("CARGO_PKG_VERSION"), csi_reset);
|
||||
print!("\n");
|
||||
|
||||
print!("Proceed? [y/N] ");
|
||||
if kernel::console::get_line().trim() == "y" {
|
||||
if sys::console::get_line().trim() == "y" {
|
||||
print!("\n");
|
||||
|
||||
if !kernel::fs::is_mounted() {
|
||||
if !sys::fs::is_mounted() {
|
||||
print!("{}Listing disks ...{}\n", csi_color, csi_reset);
|
||||
user::disk::main(&["disk", "list"]);
|
||||
usr::disk::main(&["disk", "list"]);
|
||||
print!("\n");
|
||||
|
||||
print!("{}Formatting disk ...{}\n", csi_color, csi_reset);
|
||||
print!("Enter path of disk to format: ");
|
||||
let pathname = kernel::console::get_line();
|
||||
let res = user::disk::main(&["disk", "format", pathname.trim_end()]);
|
||||
if res == user::shell::ExitCode::CommandError {
|
||||
let pathname = sys::console::get_line();
|
||||
let res = usr::disk::main(&["disk", "format", pathname.trim_end()]);
|
||||
if res == usr::shell::ExitCode::CommandError {
|
||||
return res;
|
||||
}
|
||||
print!("\n");
|
||||
|
@ -49,11 +49,11 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
copy_file("/ini/fonts/zap-light-8x16.psf", include_bytes!("../../dsk/ini/fonts/zap-light-8x16.psf"));
|
||||
copy_file("/ini/fonts/zap-vga-8x16.psf", include_bytes!("../../dsk/ini/fonts/zap-vga-8x16.psf"));
|
||||
|
||||
if kernel::process::user().is_none() {
|
||||
if sys::process::user().is_none() {
|
||||
print!("\n");
|
||||
print!("{}Creating user...{}\n", csi_color, csi_reset);
|
||||
let res = user::user::main(&["user", "create"]);
|
||||
if res == user::shell::ExitCode::CommandError {
|
||||
let res = usr::user::main(&["user", "create"]);
|
||||
if res == usr::shell::ExitCode::CommandError {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -64,20 +64,20 @@ pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
|||
print!("Exit console or reboot to apply changes\n");
|
||||
}
|
||||
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
fn create_dir(pathname: &str) {
|
||||
if kernel::fs::Dir::create(pathname).is_some() {
|
||||
if sys::fs::Dir::create(pathname).is_some() {
|
||||
print!("Created '{}'\n", pathname);
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_file(pathname: &str, buf: &[u8]) {
|
||||
if kernel::fs::File::open(pathname).is_some() {
|
||||
if sys::fs::File::open(pathname).is_some() {
|
||||
return;
|
||||
}
|
||||
if let Some(mut file) = kernel::fs::File::create(pathname) {
|
||||
if let Some(mut file) = sys::fs::File::create(pathname) {
|
||||
if pathname.ends_with(".txt") {
|
||||
if let Ok(text) = String::from_utf8(buf.to_vec()) {
|
||||
let text = text.replace("{x.x.x}", env!("CARGO_PKG_VERSION"));
|
|
@ -1,9 +1,9 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use core::str::FromStr;
|
||||
use smoltcp::wire::IpCidr;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
if args.len() == 1 {
|
||||
print!("Link: {}\n", iface.ethernet_addr());
|
||||
for ip_cidr in iface.ip_addrs() {
|
||||
|
@ -37,13 +37,13 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
}
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
error("could not find network interface")
|
||||
}
|
||||
}
|
||||
|
||||
fn error(message: &str) -> user::shell::ExitCode {
|
||||
fn error(message: &str) -> usr::shell::ExitCode {
|
||||
print!("Error: {}\n", message);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
let current_dir = kernel::process::dir();
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
let current_dir = sys::process::dir();
|
||||
let mut pathname = if args.len() == 2 && args[1].len() > 0 {
|
||||
args[1]
|
||||
} else {
|
||||
|
@ -15,7 +15,7 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
pathname = pathname.trim_end_matches('/');
|
||||
}
|
||||
|
||||
if let Some(dir) = kernel::fs::Dir::open(pathname) {
|
||||
if let Some(dir) = sys::fs::Dir::open(pathname) {
|
||||
let mut files: Vec<_> = dir.read().collect();
|
||||
|
||||
files.sort_by_key(|f| f.name());
|
||||
|
@ -23,9 +23,9 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
for file in files {
|
||||
print!("{}\n", file.name());
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("Dir not found '{}'\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
use crate::{sys, usr, print};
|
||||
use crate::api::console::Style;
|
||||
use alloc::string::ToString;
|
||||
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
let width = sys::allocator::size().to_string().len();
|
||||
let color = Style::color("LightCyan");
|
||||
let reset = Style::reset();
|
||||
print!("{}Size:{} {:width$}\n", color, reset, sys::allocator::size(), width = width);
|
||||
print!("{}Used:{} {:width$}\n", color, reset, sys::allocator::used(), width = width);
|
||||
print!("{}Free:{} {:width$}\n", color, reset, sys::allocator::free(), width = width);
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
use crate::usr;
|
||||
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 3 {
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
// TODO: Avoid doing copy+delete
|
||||
match usr::copy::main(args) {
|
||||
usr::shell::ExitCode::CommandSuccessful => usr::delete::main(&args[0..2]),
|
||||
_ => usr::shell::ExitCode::CommandError,
|
||||
}
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
//use smoltcp::wire::Ipv4Address;
|
||||
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
|
||||
use smoltcp::time::Instant;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() == 1 {
|
||||
print!("Usage: net <command>\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
match args[1] {
|
||||
"config" => {
|
||||
if args.len() < 4 {
|
||||
print!("Usage: net config <key> <value>\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
match args[2] {
|
||||
"debug" => {
|
||||
|
@ -24,13 +24,13 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
"0" | "off" | "disable" => false,
|
||||
_ => {
|
||||
print!("Invalid config value\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
print!("Invalid config key\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,9 +49,9 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
let _server_handle = sockets.add(server_socket);
|
||||
|
||||
loop {
|
||||
if kernel::console::abort() {
|
||||
if sys::console::abort() {
|
||||
print!("\n");
|
||||
return user::shell::ExitCode::CommandSuccessful;
|
||||
return usr::shell::ExitCode::CommandSuccessful;
|
||||
}
|
||||
|
||||
let now = syscall::uptime();
|
||||
|
@ -74,9 +74,9 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
_ => {
|
||||
print!("Invalid command\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{print, user};
|
||||
use crate::{usr, print};
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
let n = args.len();
|
||||
for i in 1..n {
|
||||
print!("{}", args[i]);
|
||||
|
@ -9,5 +9,5 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
}
|
||||
print!("\n");
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use crate::kernel::cmos::CMOS;
|
||||
use crate::sys::cmos::CMOS;
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 2 {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let pathname = args[1];
|
||||
|
@ -19,26 +19,26 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
rtc.year, rtc.month, rtc.day,
|
||||
rtc.hour, rtc.minute, rtc.second
|
||||
);
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
},
|
||||
"/dev/clk/realtime" => {
|
||||
print!("{:.6}\n", syscall::realtime());
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
},
|
||||
"/dev/clk/uptime" => {
|
||||
print!("{:.6}\n", syscall::uptime());
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
},
|
||||
"/dev/random" => {
|
||||
loop {
|
||||
// Generate ASCII graphic chars
|
||||
let i = (kernel::random::get_u32() % (0x72 - 0x20)) + 0x20;
|
||||
let i = (sys::random::get_u32() % (0x72 - 0x20)) + 0x20;
|
||||
if let Some(c) = core::char::from_u32(i) {
|
||||
print!("{}", c);
|
||||
}
|
||||
if kernel::console::abort() {
|
||||
if sys::console::abort() {
|
||||
print!("\n");
|
||||
return user::shell::ExitCode::CommandSuccessful;
|
||||
return usr::shell::ExitCode::CommandSuccessful;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -52,37 +52,37 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
let parts: Vec<_> = pathname.split('/').collect();
|
||||
if parts.len() < 4 {
|
||||
print!("Usage: read /net/http/<host>/<path>\n");
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
} else {
|
||||
match parts[2] {
|
||||
"tcp" => {
|
||||
let host = parts[3];
|
||||
user::tcp::main(&["tcp", host])
|
||||
usr::tcp::main(&["tcp", host])
|
||||
}
|
||||
"daytime" => {
|
||||
let host = parts[3];
|
||||
let port = "13";
|
||||
user::tcp::main(&["tcp", host, port])
|
||||
usr::tcp::main(&["tcp", host, port])
|
||||
}
|
||||
"http" => {
|
||||
let host = parts[3];
|
||||
let path = "/".to_owned() + &parts[4..].join("/");
|
||||
user::http::main(&["http", host, &path])
|
||||
usr::http::main(&["http", host, &path])
|
||||
}
|
||||
_ => {
|
||||
print!("Error: unknown protocol '{}'\n", parts[2]);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if pathname.ends_with('/') {
|
||||
user::list::main(args)
|
||||
} else if let Some(file) = kernel::fs::File::open(pathname) {
|
||||
usr::list::main(args)
|
||||
} else if let Some(file) = sys::fs::File::open(pathname) {
|
||||
print!("{}", file.read_to_string());
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("File not found '{}'\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use alloc::string::ToString;
|
||||
|
||||
pub fn main(_args: &[&str]) -> user::shell::ExitCode {
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
print!("{:<19} {}\n", "Destination", "Gateway");
|
||||
iface.routes_mut().update(|storage| {
|
||||
for (cidr, route) in storage.iter() {
|
||||
print!("{:<19} {}\n", cidr.to_string(), route.via_router);
|
||||
}
|
||||
});
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("Could not find network interface\n");
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{print, user, kernel};
|
||||
use crate::kernel::console::Style;
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::console::Style;
|
||||
use alloc::format;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
|
@ -55,20 +55,20 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> user::shell::ExitCode {
|
||||
pub fn run(&mut self) -> usr::shell::ExitCode {
|
||||
self.load_history();
|
||||
print!("\n");
|
||||
self.print_prompt();
|
||||
loop {
|
||||
let (x, y) = kernel::vga::cursor_position();
|
||||
let c = kernel::console::get_char();
|
||||
let (x, y) = sys::vga::cursor_position();
|
||||
let c = sys::console::get_char();
|
||||
match c {
|
||||
'\0' => {
|
||||
continue;
|
||||
}
|
||||
'\x04' => { // Ctrl D
|
||||
if self.cmd.is_empty() {
|
||||
kernel::vga::clear_screen();
|
||||
sys::vga::clear_screen();
|
||||
return ExitCode::CommandSuccessful;
|
||||
}
|
||||
},
|
||||
|
@ -98,14 +98,14 @@ impl Shell {
|
|||
self.save_history();
|
||||
},
|
||||
ExitCode::ShellExit => {
|
||||
kernel::vga::clear_screen();
|
||||
sys::vga::clear_screen();
|
||||
return ExitCode::CommandSuccessful
|
||||
},
|
||||
_ => {
|
||||
self.errored = true;
|
||||
},
|
||||
}
|
||||
kernel::console::drain();
|
||||
sys::console::drain();
|
||||
self.cmd.clear();
|
||||
} else {
|
||||
self.errored = false;
|
||||
|
@ -125,8 +125,8 @@ impl Shell {
|
|||
}
|
||||
let cmd = &self.history[self.history_index];
|
||||
let n = self.prompt.len();
|
||||
kernel::console::clear_row_after(n + cmd.len());
|
||||
kernel::vga::set_writer_position(n, y);
|
||||
sys::console::clear_row_after(n + cmd.len());
|
||||
sys::vga::set_writer_position(n, y);
|
||||
print!("{}", cmd);
|
||||
}
|
||||
},
|
||||
|
@ -140,8 +140,8 @@ impl Shell {
|
|||
&self.cmd
|
||||
};
|
||||
let n = self.prompt.len();
|
||||
kernel::console::clear_row_after(n + cmd.len());
|
||||
kernel::vga::set_writer_position(n, y);
|
||||
sys::console::clear_row_after(n + cmd.len());
|
||||
sys::vga::set_writer_position(n, y);
|
||||
print!("{}", cmd);
|
||||
}
|
||||
},
|
||||
|
@ -149,23 +149,23 @@ impl Shell {
|
|||
self.update_history();
|
||||
self.update_autocomplete();
|
||||
if x > self.prompt.len() {
|
||||
kernel::vga::set_cursor_position(x - 1, y);
|
||||
kernel::vga::set_writer_position(x - 1, y);
|
||||
sys::vga::set_cursor_position(x - 1, y);
|
||||
sys::vga::set_writer_position(x - 1, y);
|
||||
}
|
||||
},
|
||||
'→' => { // Arrow right
|
||||
self.update_history();
|
||||
self.update_autocomplete();
|
||||
if x < self.prompt.len() + self.cmd.len() {
|
||||
kernel::vga::set_cursor_position(x + 1, y);
|
||||
kernel::vga::set_writer_position(x + 1, y);
|
||||
sys::vga::set_cursor_position(x + 1, y);
|
||||
sys::vga::set_writer_position(x + 1, y);
|
||||
}
|
||||
},
|
||||
'\x08' => { // Backspace
|
||||
self.update_history();
|
||||
self.update_autocomplete();
|
||||
if self.cmd.len() > 0 {
|
||||
if kernel::console::has_cursor() {
|
||||
if sys::console::has_cursor() {
|
||||
if x > self.prompt.len() {
|
||||
let cmd = self.cmd.clone();
|
||||
let (before_cursor, mut after_cursor) = cmd.split_at(x - 1 - self.prompt.len());
|
||||
|
@ -176,8 +176,8 @@ impl Shell {
|
|||
self.cmd.push_str(before_cursor);
|
||||
self.cmd.push_str(after_cursor);
|
||||
print!("{}{} ", c, after_cursor);
|
||||
kernel::vga::set_cursor_position(x - 1, y);
|
||||
kernel::vga::set_writer_position(x - 1, y);
|
||||
sys::vga::set_cursor_position(x - 1, y);
|
||||
sys::vga::set_writer_position(x - 1, y);
|
||||
}
|
||||
} else {
|
||||
self.cmd.pop();
|
||||
|
@ -189,7 +189,7 @@ impl Shell {
|
|||
self.update_history();
|
||||
self.update_autocomplete();
|
||||
if self.cmd.len() > 0 {
|
||||
if kernel::console::has_cursor() {
|
||||
if sys::console::has_cursor() {
|
||||
let cmd = self.cmd.clone();
|
||||
let (before_cursor, mut after_cursor) = cmd.split_at(x - self.prompt.len());
|
||||
if after_cursor.len() > 0 {
|
||||
|
@ -199,16 +199,16 @@ impl Shell {
|
|||
self.cmd.push_str(before_cursor);
|
||||
self.cmd.push_str(after_cursor);
|
||||
print!("{} ", after_cursor);
|
||||
kernel::vga::set_cursor_position(x, y);
|
||||
kernel::vga::set_writer_position(x, y);
|
||||
sys::vga::set_cursor_position(x, y);
|
||||
sys::vga::set_writer_position(x, y);
|
||||
}
|
||||
}
|
||||
},
|
||||
c => {
|
||||
self.update_history();
|
||||
self.update_autocomplete();
|
||||
if c.is_ascii() && kernel::vga::is_printable(c as u8) {
|
||||
if kernel::console::has_cursor() {
|
||||
if c.is_ascii() && sys::vga::is_printable(c as u8) {
|
||||
if sys::console::has_cursor() {
|
||||
let cmd = self.cmd.clone();
|
||||
let (before_cursor, after_cursor) = cmd.split_at(x - self.prompt.len());
|
||||
self.cmd.clear();
|
||||
|
@ -216,8 +216,8 @@ impl Shell {
|
|||
self.cmd.push(c);
|
||||
self.cmd.push_str(after_cursor);
|
||||
print!("{}{}", c, after_cursor);
|
||||
kernel::vga::set_cursor_position(x + 1, y);
|
||||
kernel::vga::set_writer_position(x + 1, y);
|
||||
sys::vga::set_cursor_position(x + 1, y);
|
||||
sys::vga::set_writer_position(x + 1, y);
|
||||
} else {
|
||||
self.cmd.push(c);
|
||||
print!("{}", c);
|
||||
|
@ -240,10 +240,10 @@ impl Shell {
|
|||
}
|
||||
|
||||
pub fn load_history(&mut self) {
|
||||
if let Some(home) = kernel::process::env("HOME") {
|
||||
if let Some(home) = sys::process::env("HOME") {
|
||||
let pathname = format!("{}/.shell_history", home);
|
||||
|
||||
if let Some(file) = kernel::fs::File::open(&pathname) {
|
||||
if let Some(file) = sys::fs::File::open(&pathname) {
|
||||
let contents = file.read_to_string();
|
||||
for line in contents.split('\n') {
|
||||
let cmd = line.trim();
|
||||
|
@ -257,7 +257,7 @@ impl Shell {
|
|||
}
|
||||
|
||||
pub fn save_history(&mut self) {
|
||||
if let Some(home) = kernel::process::env("HOME") {
|
||||
if let Some(home) = sys::process::env("HOME") {
|
||||
let pathname = format!("{}/.shell_history", home);
|
||||
|
||||
let mut contents = String::new();
|
||||
|
@ -265,9 +265,9 @@ impl Shell {
|
|||
contents.push_str(&format!("{}\n", cmd));
|
||||
}
|
||||
|
||||
let mut file = match kernel::fs::File::open(&pathname) {
|
||||
let mut file = match sys::fs::File::open(&pathname) {
|
||||
Some(file) => file,
|
||||
None => kernel::fs::File::create(&pathname).unwrap(),
|
||||
None => sys::fs::File::create(&pathname).unwrap(),
|
||||
};
|
||||
|
||||
file.write(&contents.as_bytes()).unwrap();
|
||||
|
@ -286,20 +286,20 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
} else { // Autocomplete path
|
||||
let pathname = kernel::fs::realpath(args[i]);
|
||||
let dirname = kernel::fs::dirname(&pathname);
|
||||
let filename = kernel::fs::filename(&pathname);
|
||||
let pathname = sys::fs::realpath(args[i]);
|
||||
let dirname = sys::fs::dirname(&pathname);
|
||||
let filename = sys::fs::filename(&pathname);
|
||||
self.autocomplete = vec![args[i].into()];
|
||||
let sep = if dirname.ends_with("/") { "" } else { "/" };
|
||||
if pathname.starts_with("/dev") {
|
||||
for dev in &AUTOCOMPLETE_DEVICES {
|
||||
let d = kernel::fs::dirname(dev);
|
||||
let f = kernel::fs::filename(dev);
|
||||
let d = sys::fs::dirname(dev);
|
||||
let f = sys::fs::filename(dev);
|
||||
if d == dirname && f.starts_with(filename) {
|
||||
self.autocomplete.push(format!("{}{}{}", d, sep, f));
|
||||
}
|
||||
}
|
||||
} else if let Some(dir) = kernel::fs::Dir::open(dirname) {
|
||||
} else if let Some(dir) = sys::fs::Dir::open(dirname) {
|
||||
for entry in dir.read() {
|
||||
let name = entry.name();
|
||||
if name.starts_with(filename) {
|
||||
|
@ -316,9 +316,9 @@ impl Shell {
|
|||
|
||||
let cmd = args.join(" ");
|
||||
let n = self.prompt.len();
|
||||
let (_, y) = kernel::console::cursor_position();
|
||||
kernel::console::clear_row_after(n + cmd.len());
|
||||
kernel::console::set_writer_position(n, y);
|
||||
let (_, y) = sys::console::cursor_position();
|
||||
sys::console::clear_row_after(n + cmd.len());
|
||||
sys::console::set_writer_position(n, y);
|
||||
print!("{}", cmd);
|
||||
}
|
||||
|
||||
|
@ -383,53 +383,53 @@ impl Shell {
|
|||
"" => ExitCode::CommandSuccessful,
|
||||
"a" | "alias" => ExitCode::CommandUnknown,
|
||||
"b" => ExitCode::CommandUnknown,
|
||||
"c" | "copy" => user::copy::main(&args),
|
||||
"d" | "del" | "delete" => user::delete::main(&args),
|
||||
"e" | "edit" => user::editor::main(&args),
|
||||
"c" | "copy" => usr::copy::main(&args),
|
||||
"d" | "del" | "delete" => usr::delete::main(&args),
|
||||
"e" | "edit" => usr::editor::main(&args),
|
||||
"f" | "find" => ExitCode::CommandUnknown,
|
||||
"g" | "go" | "goto" => self.change_dir(&args),
|
||||
"h" | "help" => user::help::main(&args),
|
||||
"h" | "help" => usr::help::main(&args),
|
||||
"i" => ExitCode::CommandUnknown,
|
||||
"j" | "jump" => ExitCode::CommandUnknown,
|
||||
"k" | "kill" => ExitCode::CommandUnknown,
|
||||
"l" | "list" => user::list::main(&args),
|
||||
"m" | "move" => user::r#move::main(&args),
|
||||
"l" | "list" => usr::list::main(&args),
|
||||
"m" | "move" => usr::r#move::main(&args),
|
||||
"n" => ExitCode::CommandUnknown,
|
||||
"o" => ExitCode::CommandUnknown,
|
||||
"p" | "print" => user::print::main(&args),
|
||||
"p" | "print" => usr::print::main(&args),
|
||||
"q" | "quit" | "exit" => ExitCode::ShellExit,
|
||||
"r" | "read" => user::read::main(&args),
|
||||
"r" | "read" => usr::read::main(&args),
|
||||
"s" => ExitCode::CommandUnknown,
|
||||
"t" => ExitCode::CommandUnknown,
|
||||
"u" => ExitCode::CommandUnknown,
|
||||
"v" => ExitCode::CommandUnknown,
|
||||
"w" | "write" => user::write::main(&args),
|
||||
"w" | "write" => usr::write::main(&args),
|
||||
"x" => ExitCode::CommandUnknown,
|
||||
"y" => ExitCode::CommandUnknown,
|
||||
"z" => ExitCode::CommandUnknown,
|
||||
"vga" => user::vga::main(&args),
|
||||
"shell" => user::shell::main(&args),
|
||||
"sleep" => user::sleep::main(&args),
|
||||
"clear" => user::clear::main(&args),
|
||||
"base64" => user::base64::main(&args),
|
||||
"date" => user::date::main(&args),
|
||||
"env" => user::env::main(&args),
|
||||
"halt" => user::halt::main(&args),
|
||||
"hex" => user::hex::main(&args),
|
||||
"net" => user::net::main(&args),
|
||||
"route" => user::route::main(&args),
|
||||
"dhcp" => user::dhcp::main(&args),
|
||||
"http" => user::http::main(&args),
|
||||
"httpd" => user::httpd::main(&args),
|
||||
"tcp" => user::tcp::main(&args),
|
||||
"host" => user::host::main(&args),
|
||||
"install" => user::install::main(&args),
|
||||
"ip" => user::ip::main(&args),
|
||||
"geotime" => user::geotime::main(&args),
|
||||
"colors" => user::colors::main(&args),
|
||||
"disk" => user::disk::main(&args),
|
||||
"user" => user::user::main(&args),
|
||||
"mem" | "memory" => user::mem::main(&args),
|
||||
"vga" => usr::vga::main(&args),
|
||||
"shell" => usr::shell::main(&args),
|
||||
"sleep" => usr::sleep::main(&args),
|
||||
"clear" => usr::clear::main(&args),
|
||||
"base64" => usr::base64::main(&args),
|
||||
"date" => usr::date::main(&args),
|
||||
"env" => usr::env::main(&args),
|
||||
"halt" => usr::halt::main(&args),
|
||||
"hex" => usr::hex::main(&args),
|
||||
"net" => usr::net::main(&args),
|
||||
"route" => usr::route::main(&args),
|
||||
"dhcp" => usr::dhcp::main(&args),
|
||||
"http" => usr::http::main(&args),
|
||||
"httpd" => usr::httpd::main(&args),
|
||||
"tcp" => usr::tcp::main(&args),
|
||||
"host" => usr::host::main(&args),
|
||||
"install" => usr::install::main(&args),
|
||||
"ip" => usr::ip::main(&args),
|
||||
"geotime" => usr::geotime::main(&args),
|
||||
"colors" => usr::colors::main(&args),
|
||||
"disk" => usr::disk::main(&args),
|
||||
"user" => usr::user::main(&args),
|
||||
"mem" | "memory" => usr::mem::main(&args),
|
||||
_ => ExitCode::CommandUnknown,
|
||||
}
|
||||
}
|
||||
|
@ -444,13 +444,13 @@ impl Shell {
|
|||
fn change_dir(&self, args: &[&str]) -> ExitCode {
|
||||
match args.len() {
|
||||
1 => {
|
||||
print!("{}\n", kernel::process::dir());
|
||||
print!("{}\n", sys::process::dir());
|
||||
ExitCode::CommandSuccessful
|
||||
},
|
||||
2 => {
|
||||
let pathname = kernel::fs::realpath(args[1]);
|
||||
if kernel::fs::Dir::open(&pathname).is_some() {
|
||||
kernel::process::set_dir(&pathname);
|
||||
let pathname = sys::fs::realpath(args[1]);
|
||||
if sys::fs::Dir::open(&pathname).is_some() {
|
||||
sys::process::set_dir(&pathname);
|
||||
ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("File not found '{}'\n", pathname);
|
||||
|
@ -472,7 +472,7 @@ pub fn main(args: &[&str]) -> ExitCode {
|
|||
},
|
||||
2 => {
|
||||
let pathname = args[1];
|
||||
if let Some(file) = kernel::fs::File::open(pathname) {
|
||||
if let Some(file) = sys::fs::File::open(pathname) {
|
||||
for line in file.read_to_string().split("\n") {
|
||||
if line.len() > 0 {
|
||||
shell.exec(line);
|
|
@ -0,0 +1,12 @@
|
|||
use crate::usr;
|
||||
use crate::api::syscall;
|
||||
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() == 2 {
|
||||
if let Ok(duration) = args[1].parse::<f64>() {
|
||||
syscall::sleep(duration);
|
||||
return usr::shell::ExitCode::CommandSuccessful;
|
||||
}
|
||||
}
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::string::{String, ToString};
|
||||
|
@ -10,7 +10,7 @@ use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
|
|||
use smoltcp::time::Instant;
|
||||
use smoltcp::wire::IpAddress;
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
let mut args: Vec<String> = args.iter().map(ToOwned::to_owned).map(ToOwned::to_owned).collect();
|
||||
|
||||
// Split <host> and <port>
|
||||
|
@ -25,7 +25,7 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
|
||||
if args.len() != 3 {
|
||||
print!("Usage: tcp <host> <port>\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let host = &args[1];
|
||||
|
@ -35,13 +35,13 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
let address = if host.ends_with(char::is_numeric) {
|
||||
IpAddress::from_str(&host).expect("invalid address format")
|
||||
} else {
|
||||
match user::host::resolve(&host) {
|
||||
match usr::host::resolve(&host) {
|
||||
Ok(ip_addr) => {
|
||||
ip_addr
|
||||
}
|
||||
Err(e) => {
|
||||
print!("Could not resolve host: {:?}\n", e);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -56,15 +56,15 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
enum State { Connect, Request, Response }
|
||||
let mut state = State::Connect;
|
||||
|
||||
if let Some(ref mut iface) = *kernel::net::IFACE.lock() {
|
||||
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
|
||||
match iface.ipv4_addr() {
|
||||
None => {
|
||||
print!("Interface not ready\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
Some(ip_addr) if ip_addr.is_unspecified() => {
|
||||
print!("Interface not ready\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -74,11 +74,11 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
loop {
|
||||
if syscall::realtime() - started > timeout {
|
||||
print!("Timeout reached\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
if kernel::console::abort() {
|
||||
if sys::console::abort() {
|
||||
print!("\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
let timestamp = Instant::from_millis((syscall::realtime() * 1000.0) as i64);
|
||||
match iface.poll(&mut sockets, timestamp) {
|
||||
|
@ -94,11 +94,11 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
|
||||
state = match state {
|
||||
State::Connect if !socket.is_active() => {
|
||||
let local_port = 49152 + kernel::random::get_u16() % 16384;
|
||||
let local_port = 49152 + sys::random::get_u16() % 16384;
|
||||
print!("Connecting to {}:{}\n", address, port);
|
||||
if socket.connect((address, port), local_port).is_err() {
|
||||
print!("Could not connect to {}:{}\n", address, port);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
State::Request
|
||||
}
|
||||
|
@ -130,8 +130,8 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
syscall::sleep(wait_duration.as_secs_f64());
|
||||
}
|
||||
}
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
use crate::{usr, print};
|
||||
use crate::api::syscall;
|
||||
|
||||
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
|
||||
print!("{:.6}\n", syscall::uptime());
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
use crate::api::syscall;
|
||||
use alloc::collections::btree_map::BTreeMap;
|
||||
use alloc::format;
|
||||
|
@ -12,14 +12,14 @@ use sha2::Sha256;
|
|||
const PASSWORDS: &'static str = "/ini/passwords.csv";
|
||||
const COMMANDS: [&'static str; 2] = ["create", "login"];
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() == 1 || !COMMANDS.contains(&args[1]) {
|
||||
return usage();
|
||||
}
|
||||
|
||||
let username: String = if args.len() == 2 {
|
||||
print!("Username: ");
|
||||
kernel::console::get_line().trim_end().into()
|
||||
sys::console::get_line().trim_end().into()
|
||||
} else {
|
||||
args[2].into()
|
||||
};
|
||||
|
@ -31,13 +31,13 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
fn usage() -> user::shell::ExitCode {
|
||||
fn usage() -> usr::shell::ExitCode {
|
||||
print!("Usage: user [{}] <username>\n", COMMANDS.join("|"));
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
// TODO: Add max number of attempts
|
||||
pub fn login(username: &str) -> user::shell::ExitCode {
|
||||
pub fn login(username: &str) -> usr::shell::ExitCode {
|
||||
if username.is_empty() {
|
||||
print!("\n");
|
||||
syscall::sleep(1.0);
|
||||
|
@ -47,9 +47,9 @@ pub fn login(username: &str) -> user::shell::ExitCode {
|
|||
match hashed_password(&username) {
|
||||
Some(hash) => {
|
||||
print!("Password: ");
|
||||
kernel::console::disable_echo();
|
||||
let mut password = kernel::console::get_line();
|
||||
kernel::console::enable_echo();
|
||||
sys::console::disable_echo();
|
||||
let mut password = sys::console::get_line();
|
||||
sys::console::enable_echo();
|
||||
print!("\n");
|
||||
password.pop();
|
||||
if !check(&password, &hash) {
|
||||
|
@ -66,56 +66,56 @@ pub fn login(username: &str) -> user::shell::ExitCode {
|
|||
}
|
||||
|
||||
let home = format!("/usr/{}", username);
|
||||
kernel::process::set_user(&username);
|
||||
kernel::process::set_env("HOME", &home);
|
||||
kernel::process::set_dir(&home);
|
||||
sys::process::set_user(&username);
|
||||
sys::process::set_env("HOME", &home);
|
||||
sys::process::set_dir(&home);
|
||||
|
||||
// TODO: load shell
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
pub fn create(username: &str) -> user::shell::ExitCode {
|
||||
pub fn create(username: &str) -> usr::shell::ExitCode {
|
||||
if username.is_empty() {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
if hashed_password(&username).is_some() {
|
||||
print!("Username exists\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
print!("Password: ");
|
||||
kernel::console::disable_echo();
|
||||
let mut password = kernel::console::get_line();
|
||||
kernel::console::enable_echo();
|
||||
sys::console::disable_echo();
|
||||
let mut password = sys::console::get_line();
|
||||
sys::console::enable_echo();
|
||||
print!("\n");
|
||||
password.pop();
|
||||
|
||||
if password.is_empty() {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
print!("Confirm: ");
|
||||
kernel::console::disable_echo();
|
||||
let mut confirm = kernel::console::get_line();
|
||||
kernel::console::enable_echo();
|
||||
sys::console::disable_echo();
|
||||
let mut confirm = sys::console::get_line();
|
||||
sys::console::enable_echo();
|
||||
print!("\n");
|
||||
confirm.pop();
|
||||
|
||||
if password != confirm {
|
||||
print!("Password confirmation failed\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
if save_hashed_password(&username, &hash(&password)).is_err() {
|
||||
print!("Could not save user\n");
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
// Create home dir
|
||||
kernel::fs::Dir::create(&format!("/usr/{}", username)).unwrap();
|
||||
sys::fs::Dir::create(&format!("/usr/{}", username)).unwrap();
|
||||
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
||||
|
||||
pub fn check(password: &str, hashed_password: &str) -> bool {
|
||||
|
@ -124,15 +124,15 @@ pub fn check(password: &str, hashed_password: &str) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
let decoded_field = user::base64::decode(&fields[1].as_bytes());
|
||||
let decoded_field = usr::base64::decode(&fields[1].as_bytes());
|
||||
let c = u32::from_be_bytes(decoded_field[0..4].try_into().unwrap());
|
||||
|
||||
let decoded_field = user::base64::decode(&fields[2].as_bytes());
|
||||
let decoded_field = usr::base64::decode(&fields[2].as_bytes());
|
||||
let salt: [u8; 16] = decoded_field[0..16].try_into().unwrap();
|
||||
|
||||
let mut hash = [0u8; 32];
|
||||
pbkdf2::pbkdf2::<Hmac<Sha256>>(password.as_bytes(), &salt, c as usize, &mut hash);
|
||||
let encoded_hash = String::from_utf8(user::base64::encode(&hash)).unwrap();
|
||||
let encoded_hash = String::from_utf8(usr::base64::encode(&hash)).unwrap();
|
||||
|
||||
encoded_hash == fields[3]
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ pub fn hash(password: &str) -> String {
|
|||
|
||||
// Generating salt
|
||||
for i in 0..2 {
|
||||
let num = kernel::random::get_u64();
|
||||
let num = sys::random::get_u64();
|
||||
let buf = num.to_be_bytes();
|
||||
let n = buf.len();
|
||||
for j in 0..n {
|
||||
|
@ -163,17 +163,17 @@ pub fn hash(password: &str) -> String {
|
|||
let c = c.to_be_bytes();
|
||||
let mut res: String = String::from(v);
|
||||
res.push('$');
|
||||
res.push_str(&String::from_utf8(user::base64::encode(&c)).unwrap());
|
||||
res.push_str(&String::from_utf8(usr::base64::encode(&c)).unwrap());
|
||||
res.push('$');
|
||||
res.push_str(&String::from_utf8(user::base64::encode(&salt)).unwrap());
|
||||
res.push_str(&String::from_utf8(usr::base64::encode(&salt)).unwrap());
|
||||
res.push('$');
|
||||
res.push_str(&String::from_utf8(user::base64::encode(&hash)).unwrap());
|
||||
res.push_str(&String::from_utf8(usr::base64::encode(&hash)).unwrap());
|
||||
res
|
||||
}
|
||||
|
||||
fn read_hashed_passwords() -> BTreeMap<String, String> {
|
||||
let mut hashed_passwords = BTreeMap::new();
|
||||
if let Some(file) = kernel::fs::File::open(PASSWORDS) {
|
||||
if let Some(file) = sys::fs::File::open(PASSWORDS) {
|
||||
for line in file.read_to_string().split("\n") {
|
||||
let mut rows = line.split(",");
|
||||
if let Some(username) = rows.next() {
|
||||
|
@ -200,8 +200,8 @@ fn save_hashed_password(username: &str, hash: &str) -> Result<(), ()> {
|
|||
hashed_passwords.remove(username.into());
|
||||
hashed_passwords.insert(username.into(), hash.into());
|
||||
|
||||
let mut file = match kernel::fs::File::open(PASSWORDS) {
|
||||
None => match kernel::fs::File::create(PASSWORDS) {
|
||||
let mut file = match sys::fs::File::open(PASSWORDS) {
|
||||
None => match sys::fs::File::create(PASSWORDS) {
|
||||
None => return Err(()),
|
||||
Some(file) => file,
|
||||
},
|
|
@ -0,0 +1,45 @@
|
|||
use crate::{api, sys, usr, print};
|
||||
use crate::api::vga::palette;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() == 1 {
|
||||
print!("Usage: vga <command>\n");
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
match args[1] {
|
||||
"set" => {
|
||||
if args.len() == 4 && args[2] == "font" {
|
||||
if let Some(file) = sys::fs::File::open(args[3]) {
|
||||
let size = file.size();
|
||||
let mut buf = Vec::with_capacity(size);
|
||||
buf.resize(size, 0);
|
||||
file.read(&mut buf);
|
||||
if let Ok(font) = api::font::from_bytes(&buf) {
|
||||
sys::vga::set_font(&font);
|
||||
} else {
|
||||
print!("Could not parse font file\n");
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
} else if args.len() == 4 && args[2] == "palette" {
|
||||
if let Some(file) = sys::fs::File::open(args[3]) {
|
||||
if let Ok(palette) = palette::from_csv(&file.read_to_string()) {
|
||||
sys::vga::set_palette(palette);
|
||||
} else {
|
||||
print!("Could not parse palette file\n");
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print!("Invalid command\n");
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
print!("Invalid command\n");
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
}
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
use crate::{kernel, print, user};
|
||||
use crate::{sys, usr, print};
|
||||
|
||||
pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
||||
pub fn main(args: &[&str]) -> usr::shell::ExitCode {
|
||||
if args.len() != 2 {
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
let pathname = args[1];
|
||||
|
||||
if pathname.starts_with("/dev") || pathname.starts_with("/sys") {
|
||||
print!("Permission denied to write to '{}'\n", pathname);
|
||||
return user::shell::ExitCode::CommandError;
|
||||
return usr::shell::ExitCode::CommandError;
|
||||
}
|
||||
|
||||
// The command `write /usr/alice/` with a trailing slash will create
|
||||
|
@ -17,15 +17,15 @@ pub fn main(args: &[&str]) -> user::shell::ExitCode {
|
|||
// create a file.
|
||||
let success = if pathname.ends_with('/') {
|
||||
let pathname = pathname.trim_end_matches('/');
|
||||
kernel::fs::Dir::create(pathname).is_some()
|
||||
sys::fs::Dir::create(pathname).is_some()
|
||||
} else {
|
||||
kernel::fs::File::create(pathname).is_some()
|
||||
sys::fs::File::create(pathname).is_some()
|
||||
};
|
||||
|
||||
if success {
|
||||
user::shell::ExitCode::CommandSuccessful
|
||||
usr::shell::ExitCode::CommandSuccessful
|
||||
} else {
|
||||
print!("Could not write to '{}'\n", pathname);
|
||||
user::shell::ExitCode::CommandError
|
||||
usr::shell::ExitCode::CommandError
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue