Skip to content

Commit

Permalink
wip: optimize shell
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Mar 19, 2023
1 parent d664b10 commit a816374
Show file tree
Hide file tree
Showing 18 changed files with 153 additions and 63 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
OVMF := tools/OVMF.fd
ESP := esp
BUILD_ARGS :=
QEMU_ARGS := -serial stdio
QEMU_ARGS := -m 64M
QEMU_OUTPUT := -serial stdio
MODE ?= release
RUN_MODE ?=
CUR_PATH := $(shell pwd)
Expand All @@ -18,7 +19,7 @@ ifeq (${MODE}, release)
endif

ifeq (${RUN_MODE}, nographic)
QEMU_ARGS = -nographic
QEMU_OUTPUT = -nographic
endif

.PHONY: build run debug clean launch intdbg \
Expand All @@ -33,20 +34,24 @@ launch:
-bios ${OVMF} \
-net none \
$(QEMU_ARGS) \
$(QEMU_OUTPUT) \
-drive format=raw,file=fat:rw:${ESP}

intdbg:
@qemu-system-x86_64 \
-bios ${OVMF} \
-net none \
$(QEMU_ARGS) \
-drive format=raw,file=fat:rw:${ESP} -no-reboot -d int,cpu_reset
$(QEMU_OUTPUT) \
-drive format=raw,file=fat:rw:${ESP} \
-no-reboot -d int,cpu_reset

debug: build
@qemu-system-x86_64 \
-bios ${OVMF} \
-net none \
$(QEMU_ARGS) \
$(QEMU_OUTPUT) \
-drive format=raw,file=fat:rw:${ESP} \
-s -S

Expand Down
3 changes: 3 additions & 0 deletions pkg/app/fact/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ fn main() -> usize {
// calculate factorial
let result = factorial(n);

// print system status
sys_stat();

// print result
println!("The factorial of {} under modulo {} is {}.", n, MOD, result);

Expand Down
2 changes: 1 addition & 1 deletion pkg/app/hello/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern crate lib;
fn main() -> usize {
println!("Hello, world!!!");
let time = lib::sys_time();
println!("Now at: {}", time);
println!("Now at: {} UTC", time);

println!("Huge stack testing...");

Expand Down
2 changes: 1 addition & 1 deletion pkg/app/sh/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ggos_sh"
version = "0.4.0"
version = "0.5.0"
edition = "2021"
authors = ["GZTime <[email protected]>"]

Expand Down
68 changes: 48 additions & 20 deletions pkg/app/sh/src/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ pub fn cat(path: &str, root_dir: &str) {
String::from(path)
} else {
format!("{}{}", root_dir, path)
};
}
.to_ascii_uppercase();

let fd = sys_open(path.as_str(), FileMode::ReadOnly);

Expand Down Expand Up @@ -85,30 +86,20 @@ pub fn cat(path: &str, root_dir: &str) {

pub fn cd(path: &str, root_dir: &mut String) {
if path.starts_with('/') {
*root_dir = String::from(path);
return;
}

match path {
".." => {
if root_dir.as_str() == "/" {
return;
}
root_dir.pop();
let pos = root_dir.rfind('/').unwrap();
*root_dir = root_dir[..=pos].to_string();
}
"." => return,
_ => {
root_dir.push_str(path);
*root_dir = String::from(path).to_ascii_uppercase();
if !root_dir.ends_with('/') {
root_dir.push('/');
*root_dir = root_dir.to_ascii_uppercase();
}
} else {
root_dir.push_str(path);
root_dir.push('/');
*root_dir = root_dir.to_ascii_uppercase();
}
canonicalize(root_dir)
}

pub fn exec(path: &str, root_dir: &str) {
let path = format!("{}{}", root_dir, path);
let path = format!("{}{}", root_dir, path).to_ascii_uppercase();
let start = sys_time();

let pid = sys_spawn(path.as_str());
Expand All @@ -129,7 +120,7 @@ pub fn exec(path: &str, root_dir: &str) {
}

pub fn nohup(path: &str, root_dir: &str) {
let path = format!("{}{}", root_dir, path);
let path = format!("{}{}", root_dir, path).to_ascii_uppercase();

let pid = sys_spawn(path.as_str());

Expand All @@ -144,3 +135,40 @@ pub fn nohup(path: &str, root_dir: &str) {
pub fn kill(pid: u16) {
sys_kill(pid);
}

pub fn canonicalize(path: &mut String) {
// If the path is not absolute, return an error
if !path.starts_with('/') {
*path = String::from("/");
return;
}

// Create an empty string to store the canonicalized path
let mut canonical = String::from("/");

// Split the path by the separator and iterate over the segments
for segment in path.split('/') {
match segment {
"" | "." => {}
".." => {
if canonical.len() > 1 {
canonical.pop();
let last_index = canonical.rfind('/').unwrap_or(0);
canonical.truncate(last_index + 1);
}
}
_ => {
if canonical.len() > 1 {
canonical.push('/');
}
canonical.push_str(segment);
}
}
}

if canonical.len() > 1 {
canonical.push('/');
}

*path = canonical;
}
2 changes: 1 addition & 1 deletion pkg/kernel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ggos_kernel"
version = "0.9.7"
version = "0.9.8"
edition = "2021"
authors = ["GZTime <[email protected]>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
10 changes: 6 additions & 4 deletions pkg/kernel/src/drivers/ata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,14 +311,16 @@ impl Drive {
fs::Block::SIZE
}

fn humanized_size(&self) -> (usize, String) {
fn humanized_size(&self) -> (usize, &'static str) {
let size = self.block_size();
let count = self.block_count().unwrap();
let bytes = size * count;
if bytes >> 20 < 1000 {
(bytes >> 20, String::from("MiB"))
if bytes >> 20 < 1024 {
(bytes >> 20, "MiB")
} else if bytes >> 30 < 1024 {
(bytes >> 30, "GiB")
} else {
(bytes >> 30, String::from("GiB"))
(bytes >> 40, "TiB")
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/src/drivers/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn init() {
pub fn push_key(key: DecodedKey) {
if let Some(queue) = get_input_buf() {
if queue.push(key).is_err() {
warn!("Input buffer is full.");
warn!("Input buffer is full. Dropping key '{:?}'", key);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn kernel_main(boot_info: &'static boot::BootInfo) -> ! {

let mut executor = Executor::new();

// TODO: use executor.spawn() to spawn kernel tasks
// use executor.spawn() to spawn kernel tasks

executor.run(spawn_init());
ggos::shutdown(boot_info);
Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/src/memory/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use x86_64::structures::paging::{
use x86_64::VirtAddr;

pub const HEAP_START: usize = 0xFFFF_FF80_0000_0000;
pub const HEAP_SIZE: usize = 512 * 1024; // 512 KiB
pub const HEAP_SIZE: usize = 1024 * 1024; // 1 MiB

#[global_allocator]
pub static ALLOCATOR: LockedHeap = LockedHeap::empty();
Expand Down
8 changes: 7 additions & 1 deletion pkg/kernel/src/memory/frames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type BootInfoFrameIter = impl Iterator<Item = PhysFrame>;

/// A FrameAllocator that returns usable frames from the bootloader's memory map.
pub struct BootInfoFrameAllocator {
size: usize,
frames: BootInfoFrameIter,
used: usize,
recycled: Vec<PhysFrame>,
Expand All @@ -27,8 +28,9 @@ impl BootInfoFrameAllocator {
/// This function is unsafe because the caller must guarantee that the passed
/// memory map is valid. The main requirement is that all frames that are marked
/// as `USABLE` in it are really unused.
pub unsafe fn init(memory_map: &MemoryMap, used: usize) -> Self {
pub unsafe fn init(memory_map: &MemoryMap, used: usize, size: usize) -> Self {
BootInfoFrameAllocator {
size,
frames: create_frame_iter(memory_map),
used,
recycled: Vec::new(),
Expand All @@ -39,6 +41,10 @@ impl BootInfoFrameAllocator {
self.used
}

pub fn frames_total(&self) -> usize {
self.size
}

pub fn recycled_count(&self) -> usize {
self.recycled.len()
}
Expand Down
16 changes: 10 additions & 6 deletions pkg/kernel/src/memory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,23 @@ pub fn init(boot_info: &'static boot::BootInfo) {
let (size, unit) = humanized_size(used as u64 * PAGE_SIZE);
info!("Kernel Used Memory: {:>7.*} {}", 3, size, unit);

let size = used + usable_mem_size as usize;

unsafe {
init_PAGE_TABLE(paging::init(physical_memory_offset));
init_FRAME_ALLOCATOR(BootInfoFrameAllocator::init(memory_map, used));
init_FRAME_ALLOCATOR(BootInfoFrameAllocator::init(memory_map, used, size));
}
}

fn humanized_size(size: u64) -> (f64, &'static str) {
pub fn humanized_size(size: u64) -> (f64, &'static str) {
let bytes = size as f64;
if bytes < 1024f64 {
(bytes, "B")
} else if (bytes / (1 << 10) as f64) < 1024f64 {

// use 1000 to keep the max length of the number is 3 digits
if bytes < 1000f64 {
(bytes, " B")
} else if (bytes / (1 << 10) as f64) < 1000f64 {
(bytes / (1 << 10) as f64, "KiB")
} else if (bytes / (1 << 20) as f64) < 1024f64 {
} else if (bytes / (1 << 20) as f64) < 1000f64 {
(bytes / (1 << 20) as f64, "MiB")
} else {
(bytes / (1 << 30) as f64, "GiB")
Expand Down
2 changes: 1 addition & 1 deletion pkg/kernel/src/memory/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use x86_64::structures::paging::{
use x86_64::VirtAddr;

pub const USER_HEAP_START: usize = 0x4000_0000_0000;
pub const USER_HEAP_SIZE: usize = 128 * 1024; // 128 KiB
pub const USER_HEAP_SIZE: usize = 512 * 1024; // 512 KiB
const USER_HEAP_PAGE: usize = USER_HEAP_SIZE / crate::memory::PAGE_SIZE as usize;

pub static USER_ALLOCATOR: LockedHeap = LockedHeap::empty();
Expand Down
24 changes: 14 additions & 10 deletions pkg/kernel/src/process/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::*;
use crate::memory::{
allocator::{ALLOCATOR, HEAP_SIZE},
get_frame_alloc_for_sure,
user::{USER_ALLOCATOR, USER_HEAP_SIZE},
user::{USER_ALLOCATOR, USER_HEAP_SIZE}, self, PAGE_SIZE,
};
use crate::utils::Registers;
use alloc::collections::BTreeMap;
Expand Down Expand Up @@ -202,7 +202,7 @@ impl ProcessManager {
}

pub fn print_process_list(&self) {
let mut output = String::from(" PID | PPID | Name | Ticks | Status\n");
let mut output = String::from(" PID | PPID | Process Name | Ticks | Memory | Status\n");
for p in self.processes.iter() {
output += format!("{}\n", p).as_str();
}
Expand All @@ -216,9 +216,10 @@ impl ProcessManager {
let alloc = get_frame_alloc_for_sure();
let frames_used = alloc.frames_used();
let frames_recycled = alloc.recycled_count();
let frames_total = alloc.frames_total();

output += format!(
"Heap : {:>7.*}/{:>7.*} KiB ({:>5.2}%)\n",
"System : {:>7.*} KiB/ {:>7.*} KiB ({:>5.2}%)\n",
2,
heap_used as f64 / 1024f64,
2,
Expand All @@ -228,7 +229,7 @@ impl ProcessManager {
.as_str();

output += format!(
"User : {:>7.*}/{:>7.*} KiB ({:>5.2}%)\n",
"User : {:>7.*} KiB/ {:>7.*} KiB ({:>5.2}%)\n",
2,
user_heap_used as f64 / 1024f64,
2,
Expand All @@ -237,15 +238,18 @@ impl ProcessManager {
)
.as_str();

// put used/total frames in MiB
let (used_size, used_unit) = memory::humanized_size(frames_used as u64 * PAGE_SIZE);
let (tot_size, tot_unit) = memory::humanized_size(frames_total as u64 * PAGE_SIZE);

output += format!(
"Frames: {:>7.*}/{:>7.*} MiB ({:>5.2}%) [{}/{} recycled/used]\n",
"Memory : {:>7.*} {}/ {:>7.*} {} ({:>5.2}%) [{} recycled]\n",
2,
(frames_recycled * 4) as f64 / 1024f64,
used_size, used_unit,
2,
(frames_used * 4) as f64 / 1024f64,
frames_recycled as f64 / frames_used as f64 * 100.0,
frames_recycled,
frames_used
tot_size, tot_unit,
frames_used as f64 / frames_total as f64 * 100.0,
frames_recycled
)
.as_str();

Expand Down
Loading

0 comments on commit a816374

Please sign in to comment.