1
0
Fork 0
forked from AbleOS/ableos

sunset work, stn changes, and fiddling with kernel logging clutter

This commit is contained in:
koniifer 2024-11-11 21:48:43 +00:00
parent e40a22fccd
commit 8ad7542b9c
17 changed files with 202 additions and 241 deletions

18
Cargo.lock generated
View file

@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "allocator-api2"
version = "0.2.19"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f"
checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9"
[[package]]
name = "anyhow"
@ -228,12 +228,12 @@ dependencies = [
[[package]]
name = "hbbytecode"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b6274f3455d0545a64f2cc866b39d409e0a73427"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d99672b75179b79249c4b6b91dfccef0b757fa3a"
[[package]]
name = "hblang"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b6274f3455d0545a64f2cc866b39d409e0a73427"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d99672b75179b79249c4b6b91dfccef0b757fa3a"
dependencies = [
"hashbrown 0.15.1",
"hbbytecode",
@ -245,7 +245,7 @@ dependencies = [
[[package]]
name = "hbvm"
version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b6274f3455d0545a64f2cc866b39d409e0a73427"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d99672b75179b79249c4b6b91dfccef0b757fa3a"
dependencies = [
"hbbytecode",
]
@ -675,18 +675,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
version = "1.0.214"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.214"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [
"proc-macro2",
"quote",

View file

@ -111,7 +111,7 @@ unsafe extern "C" fn oops() -> ! {
unsafe extern "C" fn start() -> ! {
logging::init();
crate::logger::init().expect("failed to set logger");
log::info!("Initialising AKern {}", crate::VERSION);
log::debug!("Initialising AKern {}", crate::VERSION);
static HDHM_REQ: HhdmRequest = HhdmRequest::new(0);
memory::init_pt(VirtAddr::new(
@ -190,7 +190,7 @@ unsafe extern "C" fn start() -> ! {
// TODO: Add in rdseed and rdrand as sources for randomness
let _rand = xml::XMLElement::new("Random");
log::trace!("Getting boot modules");
log::debug!("Getting boot modules");
let bm = MOD_REQ.get_response().get();
let mut bootmodules = alloc::vec::Vec::new();
@ -228,7 +228,7 @@ unsafe extern "C" fn start() -> ! {
break;
}
}
log::info!("Boot module count: {:?}", bootmodules.len());
log::debug!("Boot module count: {:?}", bootmodules.len());
assert_eq!(bm.module_count, bootmodules.len() as u64);
}

View file

@ -69,7 +69,7 @@ pub fn check_device(bus: u8, device: u8) -> Option<PciDeviceInfo> {
}
let (reg2, addr) = unsafe { pci_config_read_2(bus, device, 0, 0x8) };
log::info!("pci device-({}) addr {} is {}", device, addr, reg2);
log::debug!("pci device-({}) addr {} is {}", device, addr, reg2);
let class = ((reg2 >> 16) & 0x0000_FFFF) as u16;
let pci_class = PciFullClass::from_u16(class);
let header_type = get_header_type(bus, device, 0);

View file

@ -58,10 +58,10 @@ pub fn handler(vm: &mut Vm) {
true => IpcBuffer::new(true, length),
},
);
info!("Buffer ID: {}", buff_id);
vm.registers[1] = hbvm::value::Value(buff_id);
}
2 => {
log::error!("Oops, deleting buffers is not implemented.")
// Delete buffer
}
3 => {

View file

@ -9,7 +9,20 @@ use log::Record;
pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
let msg_vec = block_read(mem_addr, length);
let log_level = msg_vec[0];
use log::Level::*;
let log_level = match msg_vec[0] {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
if log_level > log::max_level() {
return Ok(());
}
let strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap());
let strlen = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as usize;
@ -20,18 +33,6 @@ pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(),
match core::str::from_utf8(&str) {
Ok(strr) => {
use log::Level::*;
let log_level = match log_level {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
log::logger().log(
&Record::builder()
.args(format_args!("{}", strr))

View file

@ -71,7 +71,18 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
let cmd = module.cmd.trim_matches('"');
let cmd_len = cmd.len() as u64;
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
log::info!(
"Starting {}",
module
.path
.split('/')
.last()
.unwrap()
.split('.')
.next()
.unwrap()
);
log::debug!("Spawning {} with arguments \"{}\"", module.path, cmd);
// decode AbleOS Executable format
let header = &module.bytes[0..46];
@ -92,7 +103,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap());
let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
let end = (code_length + data_length) as usize;
log::info!("{code_length} + {data_length} = {end}");
log::debug!("{code_length} + {data_length} = {end}");
let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0));
if cmd_len > 0 {

View file

@ -4,15 +4,15 @@ recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void {
return @eca(4, buffer_id, memory_map_location, @sizeof(Expr))
}
write := fn($Expr: type, msg: ^Expr, buffer_id: uint): void {
write := fn($Expr: type, buffer_id: uint, msg: ^Expr): void {
return @eca(3, buffer_id, msg, @sizeof(Expr))
}
recv_length := fn(buffer_id: uint, memory_map_location: ^u8, length: uint): void {
recv_length := fn(length: uint, memory_map_location: ^u8, buffer_id: uint): void {
return @eca(4, buffer_id, memory_map_location, length)
}
write_length := fn(msg: ^u8, buffer_id: uint, length: uint): void {
write_length := fn(length: uint, msg: ^u8, buffer_id: uint): void {
return @eca(3, buffer_id, msg, length)
}
@ -22,6 +22,14 @@ create := fn(msg: ^u8): uint {
return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
}
create_without_name := fn(): uint {
return @eca(1, 0)
}
delete_buffer := fn(buffer_id: uint): void {
return @eca(2, buffer_id)
}
search := fn(msg: ^u8): uint {
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
}

View file

@ -4,118 +4,60 @@ length := fn(ptr: ^u8): uint {
}
display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
is_negative := num < 0
if is_negative num = -num
ptr := p
negative := num < 0
if negative {
num = -num
}
if radix == 2 {
*ptr = 48
ptr += 1;
*ptr = 98
ptr += 1
} else if radix == 16 {
*ptr = 48
ptr += 1;
*ptr = 120
ptr += 1
} else if radix == 8 {
*ptr = 48
ptr += 1;
*ptr = 111
ptr += 1
}
digits_start := ptr
if num == 0 {
*ptr = 48
ptr += 1
} else {
*ptr = 0x30;
*(ptr + 1) = 0
return p
}
loop if num == 0 break else {
digit := num % @bitcast(radix)
if digit < 10 {
*ptr = @intcast(digit) + 48
} else {
*ptr = @intcast(digit) + 55
remainder := num % @bitcast(radix)
num /= @bitcast(radix);
*ptr = @intcast(remainder + 0x30)
if remainder > 9 {
*ptr = @intcast(remainder - 10 + 0x41)
}
ptr += 1
num /= @bitcast(radix)
}
}
if negative {
*ptr = 45
if is_negative {
*ptr = 0x2D
ptr += 1
};
*ptr = 0
@inline(reverse, digits_start)
}
// ! it gets broked when you do this ??
// *ptr = 0
@inline(reverse, p)
return p
}
reverse := fn(s: ^u8): void {
i := 0
j := @inline(length, s) - 1
j := s + @inline(length, s) - 1
temp := @as(u8, 0)
loop if i >= j break else {
temp = *(s + i);
*(s + i) = *(s + j);
*(s + j) = temp
i += 1
loop if s < j {
temp = *s;
*s = *j;
*j = temp
s += 1
j -= 1
}
return
} else return
}
equals := fn(lhs: ^u8, rhs: ^u8): bool {
if lhs == rhs {
return true
}
i := 0
loop if *(lhs + i) != *(rhs + i) {
loop if *lhs != *rhs {
return false
} else if *lhs == 0 {
return true
} else {
i += 1
lhs += 1
rhs += 1
}
}
contains := fn(haystack: ^u8, needle: ^u8): bool {
haystack_len := @inline(length, haystack)
needle_len := @inline(length, needle)
if needle_len == 0 {
return true
}
if haystack_len < needle_len {
return false
}
max_start := haystack_len - needle_len
pos := 0
loop if pos > max_start break else {
is_match := true
offset := 0
loop if offset >= needle_len break else {
if *(haystack + pos + offset) != *(needle + offset) {
is_match = false
}
if is_match == false {
break
}
offset += 1
}
if is_match {
return true
}
pos += 1
}
return false
}

View file

@ -1,79 +1,59 @@
.{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb");
.{Surface, new_surface} := @use("../../render/src/lib.hb");
.{Window, WindowData, WindowProps, MessageHeader, message, BUFFER} := @use("./lib.hb")
.{Window, WindowData, WindowProps, MessageHeader, send_message, message, await_buffer, await_message, BUFFER} := @use("./lib.hb")
render := @use("../../render/src/lib.hb")
server_id := @as(?uint, null)
server_id := @as(uint, idk)
screen := @as(render.Surface, idk)
init := fn(): void {
log.info("client: waiting for server\0")
id := 0
loop if id != 0 {
server_id = id
log.info("client: done waiting\0")
return
} else {
id = buffer.search(BUFFER)
}
find_server := fn(): void {
// ! to be removed in the future
screen = render.init(false)
render.clear(screen, render.black)
log.debug("client: waiting for server\0")
server_id = await_buffer(BUFFER)
log.debug("client: found server\0")
}
// wait_for_message := fn($Expr: type, ptr: ^?Expr, buffer_id: uint): bool {
// timer := 0
// loop if timer < 1000 {
// buffer.recv(?Expr, buffer_id, ptr)
// if *ptr != null {
// return true
// }
// timer -= 1
// }
// return false
// }
new := fn(props: WindowProps): ?Window {
if server_id == null {
init()
}
buffer.write(?MessageHeader, &@as(?MessageHeader, .(message.syn, @sizeof(WindowProps))), @unwrap(server_id))
log.info("client: sent syn\0")
timer := 0
response := memory.uninit(MessageHeader)
// if wait_for_message(MessageHeader, &response, @unwrap(server_id)) == false {
// return null
// }
loop if timer < 1000 {
buffer.recv(?MessageHeader, @unwrap(server_id), &response)
if response != null {
break
}
timer += 1
} else {
log.error("client: no response in timeout\0")
return null
}
send_message(MessageHeader, .(message.syn, 0), server_id)
log.debug("client: sent syn\0")
response := await_message(MessageHeader, server_id)
if response.kind != message.ack {
log.error("client: refused\0")
log.error("client: refused syn\0")
return null
}
log.info("client: received ack\0")
log.debug("client: got ack\0")
buffer_id := response.data
buffer.write(?WindowProps, &@as(?WindowProps, props), buffer_id)
log.info("client: sent props\0")
send_message(WindowProps, props, buffer_id)
log.debug("client: sent props\0")
timer = 0
response2 := memory.uninit(WindowData)
loop if timer < 1000 {
buffer.recv(?WindowData, buffer_id, &response2)
if response2 != null {
log.info("client: received window data\0")
surface := new_surface(
response2 := await_message(WindowData, buffer_id)
log.debug("client: got window data\0")
surface := render.new_surface(
response2.props.dimensions.x,
response2.props.dimensions.y,
)
return .(@as(WindowData, response2), surface)
}
timer += 1
}
return null
}
// ! client buffers are not being read by the server yet
quit := fn(client: Window): void {
send_message(MessageHeader, .(message.quit, 0), client.data.buffer_id)
}
shutdown_server := fn(): void {
send_message(MessageHeader, .(message.shutdown, 0), server_id)
}
update_props := fn(client: Window): bool {
log.error("client: update props unimplemented\0")
return false
}
//! temporarily just throw our window at the screen
frame_ready := fn(client: Window): void {
send_message(MessageHeader, .(message.ready, 0), client.data.buffer_id)
log.warn("client: we are blitting to screen from the client\n\r this is temporary behaviour\0")
render.put_surface(screen, client.surface, client.data.props.position, false)
}

View file

@ -1,4 +1,4 @@
.{math: .{Vec2}} := @use("../../stn/src/lib.hb");
.{math: .{Vec2}, buffer, memory} := @use("../../stn/src/lib.hb");
.{Surface} := @use("../../render/src/lib.hb")
$BUFFER := "sunset\0"
@ -7,6 +7,34 @@ client := @use("./client.hb")
server := @use("./server.hb")
message := @use("./message.hb")
receive_message := fn($Expr: type, buffer_id: uint): ?Expr {
recv := @as(?Expr, null)
@inline(buffer.recv, ?Expr, buffer_id, &recv)
return recv
}
send_message := fn($Expr: type, msg: Expr, buffer_id: uint): void {
@inline(buffer.write, ?Expr, buffer_id, &@as(?Expr, msg))
}
await_buffer := fn(name: ^u8): uint {
id := 0
loop if id != 0 return id else id = buffer.search(BUFFER)
}
await_message := fn($Expr: type, buffer_id: uint): Expr {
response := @as(?Expr, null)
loop {
@inline(buffer.recv, ?Expr, buffer_id, &response)
if response != null {
i := 0
return @as(Expr, response)
}
}
}
// ! we need a better message format but this will do for now.
// enums would be nice
MessageHeader := packed struct {
kind: uint,
data: uint,
@ -15,7 +43,7 @@ MessageHeader := packed struct {
WindowProps := struct {
position: Vec2(uint),
dimensions: Vec2(uint),
// replace with owned string type later
// ! replace with owned string type later
title: ^u8,
}

View file

@ -1,6 +1,8 @@
// ! all values in this file are subject to change.
$syn := 1
$ack := 2
$refused := 3
$quit := 4
$update_props := 5
$shutdown := 6
$ready := 7

View file

@ -1,65 +1,46 @@
.{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
.{Surface, new_surface} := @use("../../render/src/lib.hb");
.{Window, WindowProps, WindowData, MessageHeader, BUFFER, message} := @use("./lib.hb")
.{Window, WindowProps, WindowData, MessageHeader, BUFFER, message, receive_message, send_message, await_message} := @use("./lib.hb")
WindowServer := struct {
window_count: uint,
id: uint,
// replace this with an actual collection when we get an allocator
// ! replace this with an actual collection when we get an allocator
windows: ^WindowData,
}
server := @as(?WindowServer, null)
// ! in the future this should be safely handled
server := @as(WindowServer, idk)
init := fn(): void {
if server != null {
return
}
log.info("server: starting server\0")
start := fn(): void {
windows := memory.alloc(WindowData, 10)
server = .(0, buffer.create(BUFFER), windows)
log.debug("server: started server\0")
}
// ! this function will be rewritten to several functions that allow the server mainloop to handle these itself
handle_connections := fn(): bool {
if server == null {
return false
}
recv := memory.uninit(MessageHeader)
buffer.recv(?MessageHeader, @unwrap(server).id, &recv)
recv := receive_message(MessageHeader, server.id)
if recv == null {
return true
} else if recv.kind == message.syn {
buffer_id := buffer.create("asdf\0")
buffer.write(?MessageHeader, &@as(?MessageHeader, .(message.ack, buffer_id)), @unwrap(server).id)
log.info("server: sent ack\0")
}
if recv.kind == message.syn {
buffer_id := buffer.create_without_name()
send_message(MessageHeader, .(message.ack, buffer_id), server.id)
log.debug("server: sent ack\0")
resp := await_message(WindowProps, buffer_id)
log.debug("server: received props\0")
timer := 0
resp := memory.uninit(WindowProps)
loop if timer < 1000 {
buffer.recv(?WindowProps, buffer_id, &resp)
if resp != null {
break
}
timer += 1
} else {
log.error("server: no props in timeout\0")
return true
}
log.info("server: received props\0")
surface := new_surface(resp.dimensions.x, resp.dimensions.y)
data := WindowData.(@as(WindowProps, resp), buffer_id)
buffer.write(?WindowData, &@as(?WindowData, data), buffer_id)
log.info("server: sent window data\0");
*(@unwrap(server).windows + @unwrap(server).window_count) = data
@unwrap(server).window_count += 1
} else if recv.kind == message.quit {
// todo: quit
send_message(WindowData, data, buffer_id)
log.debug("server: sent window data\0");
*(server.windows + server.window_count) = data
server.window_count += 1
} else if recv.kind == message.shutdown {
log.warn("server: shutdown handled without validation\n\r this is temporary behaviour\0")
return false
}
return true
}
should_shutdown := fn(): bool {
return false
}

View file

@ -34,7 +34,7 @@ main := fn(): int {
prev_input = input
kevent := KeyEvent.(false, true, input)
buffer.write(KeyEvent, &kevent, buf)
buffer.write(KeyEvent, buf, &kevent)
}
return 0
}

View file

@ -145,7 +145,7 @@ main := fn(): int {
event.x_change = x_change
event.y_change = y_change
buffer.write(MouseEvent, &event, mouse_buffer)
buffer.write(MouseEvent, mouse_buffer, &event)
}
return 0

View file

@ -12,10 +12,10 @@ example := fn(): void {
loop {
render.clear(screen, color)
render.sync(screen)
if (color.b & 255) == 255 | (color.b & 255) == 0 {
n = -n
if color.b == 255 | color.b == 0 {
// compiler bug workaround
n = 0 - n
}
color.b += n
}
return
}

View file

@ -1,12 +1,20 @@
.{log, string} := @use("../../../libraries/stn/src/lib.hb")
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb")
main := fn(): void {
window := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0"))
if window == null {
log.error("client: window was null\0")
sunset.client.find_server()
client := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0"))
if client == null {
log.error("we did not get a window\0")
return
}
log.info("client: window title:\0")
log.info(window.data.props.title)
if sunset.client.update_props(client) == false {
log.error("we did not update props\0")
}
render.put_filled_circle(client.surface, .(50, 50), 20, render.white)
sunset.client.frame_ready(client)
sunset.client.quit(client)
sunset.client.shutdown_server()
}

View file

@ -1,7 +1,7 @@
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
main := fn(): void {
sunset.server.init()
sunset.server.start()
loop if sunset.server.handle_connections() {
}
}