1 Commits

Author SHA1 Message Date
Sanya Kapoor
5723950f42 build: fix alloc 2026-03-11 02:41:10 +05:30
13 changed files with 35 additions and 359 deletions

View File

@@ -1,6 +1,5 @@
[unstable]
build-std = ["core", "compiler_builtins", "alloc"]
json-target-spec = true
[build]
target = "i686-kolibri.json"

View File

@@ -18,10 +18,6 @@ path = "examples/con.rs"
name = "dark"
path = "examples/dark.rs"
[[example]]
name = "net"
path = "examples/net.rs"
[profile.release]
opt-level = "z"
lto = "thin"

View File

@@ -1,65 +0,0 @@
#![no_std]
#![no_main]
extern crate alloc;
use alloc::format;
use kos::{
dll::Console,
network::{self, DeviceType},
threads::exit,
};
#[no_mangle]
pub fn kol_main() {
let con_lib = Console::import(None).expect("Failed to load /sys/lib/console.obj");
con_lib.init(u32::MAX, u32::MAX, u32::MAX, u32::MAX, c"Network Diagnostics");
let count = network::device_count();
con_lib.write_string("Network Subsystem Diagnostics\n");
con_lib.write_string("=============================\n");
con_lib.write_string(&format!("Discovered Devices: {}\n\n", count));
for i in 0..(count as u8) {
if let Ok(name) = network::device_name(i) {
con_lib.write_string(&format!("INTERFACE [{}]\n", i));
con_lib.write_string(&format!(" Name: {}\n", name));
if let Ok(info) = network::device_info(i) {
let dev_type = match info.device_type {
DeviceType::Ethernet => "Ethernet",
DeviceType::Loopback => "Loopback",
DeviceType::Unknown(_id) => "Unknown Hardware",
};
con_lib.write_string(&format!(" Type: {}\n", dev_type));
let up = if info.link.is_up() { "UP" } else { "DOWN" };
let mbps = info.link.speed_mbps().unwrap_or(0);
let duplex = if info.link.is_full_duplex() { "Full" } else { "Half" };
con_lib.write_string(&format!(" State: {} (Speed: {} Mbps, {} Duplex)\n", up, mbps, duplex));
}
if let Ok(stats) = network::device_stats(i) {
con_lib.write_string(&format!(" Stats: RX {} bytes | TX {} bytes\n", stats.rx_bytes, stats.tx_bytes));
con_lib.write_string(&format!(" RX {} pkts | TX {} pkts\n", stats.rx_packets, stats.tx_packets));
if stats.rx_errors > 0 || stats.tx_errors > 0 || stats.tx_dropped > 0 {
con_lib.write_string(&format!(" [!] Errors detected: RX={} TX={} Drops={}\n",
stats.rx_errors, stats.tx_errors, stats.tx_dropped));
}
}
con_lib.write_string("\n");
} else {
con_lib.write_string(&format!("INTERFACE [{}]\n [!] Failed to pull hardware state.\n\n", i));
}
}
con_lib.write_string("Diagnostics complete.");
con_lib.exit(false);
exit();
}

View File

@@ -5,6 +5,7 @@
"dynamic-linking": false,
"executables": true,
"has-rpath": true,
"is-builtin": false,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"llvm-target": "i686-unknown-none-code32",
@@ -13,9 +14,9 @@
"relocation-model": "static",
"position-independent-executables": false,
"relro-level": "off",
"target-c-int-width": 32,
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": 32,
"target-pointer-width": "32",
"vendor": "unknown",
"disable-redzone": true,
"panic-strategy": "abort",

View File

@@ -1,4 +1 @@
[toolchain]
channel = "nightly"
components = ["rust-src", "llvm-tools-preview"]
profile = "default"
nightly

View File

@@ -1,14 +0,0 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = with pkgs; [
rustup
cargo-make
cargo-binutils
fasm
];
shellHook = ''
export PATH="$HOME/.cargo/bin:$PATH"
'';
}

View File

@@ -36,6 +36,7 @@ pub fn init() {
unsafe {
sys::init_heap();
MAIN_SECTOR = sys::alloc(PAGE_SIZE) as usize;
core::ptr::write_bytes(MAIN_SECTOR as *mut u8, 0, PAGE_SIZE); // make sector table start clean
}
}
}
@@ -47,14 +48,14 @@ pub fn malloc(size: usize) -> *mut u8 {
if (addr as usize) != 0 {
let sec = addr;
let mut hdr = *(addr as *const SectorHeader);
let hdr = &mut *(addr as *mut SectorHeader);
let sec_start_blocks = (sec as usize) + size_of::<SectorHeader>();
if hdr.size_left >= size {
let mut j = sec_start_blocks;
let mut first_found_block_addr = 0;
while j <= sec_start_blocks + hdr.size {
let mut block = *(j as *const BlockHeader);
let block = &mut *(j as *mut BlockHeader);
match block.sign {
Sign::Active => {
// If block is occupated - pass
@@ -63,7 +64,7 @@ pub fn malloc(size: usize) -> *mut u8 {
}
Sign::Free => {
if first_found_block_addr != 0 {
if first_found_block_addr == 0 {
first_found_block_addr = j;
}
@@ -73,26 +74,32 @@ pub fn malloc(size: usize) -> *mut u8 {
j += (size_of::<BlockHeader>()) + block.size;
} else if size - sum_size < size_of::<BlockHeader>() {
// Create 2 blocks
let mut main_block =
*(first_found_block_addr as *const BlockHeader);
let main_block =
&mut *(first_found_block_addr as *mut BlockHeader);
main_block.sign = Sign::Active;
main_block.size = size;
let mut secondary_block = *(first_found_block_addr
as *const BlockHeader)
.add(size_of::<BlockHeader>() + size);
secondary_block.sign = Sign::Free;
secondary_block.size =
let secondary_block = (first_found_block_addr
+ size_of::<BlockHeader>()
+ size)
as *mut BlockHeader;
(*secondary_block).sign = Sign::Free;
(*secondary_block).size =
sum_size - size - size_of::<BlockHeader>();
hdr.size_left -= size + size_of::<BlockHeader>();
return (first_found_block_addr as *mut u8)
.add(size_of::<BlockHeader>());
} else {
// Create 1 block
let mut main_block =
*(first_found_block_addr as *const BlockHeader);
let main_block =
&mut *(first_found_block_addr as *mut BlockHeader);
main_block.sign = Sign::Active;
main_block.size = sum_size - size_of::<BlockHeader>();
hdr.size_left -= main_block.size + size_of::<BlockHeader>();
return (first_found_block_addr as *mut u8)
.add(size_of::<BlockHeader>());
}
@@ -117,9 +124,11 @@ pub fn malloc(size: usize) -> *mut u8 {
}
}
} else {
let sec_size = size + PAGE_SIZE - size % PAGE_SIZE;
// round requested size up to whole pages
let sec_size = (size + PAGE_SIZE - 1) & !(PAGE_SIZE - 1);
let new_sec = sys::alloc(sec_size);
let sec_hdr = new_sec as *mut SectorHeader;
*((MAIN_SECTOR + i * 4) as *mut u32) = new_sec as u32; // remember this sector in the table
*sec_hdr = SectorHeader {
size: sec_size,
size_left: sec_size - size_of::<SectorHeader>(),
@@ -138,26 +147,26 @@ pub fn malloc(size: usize) -> *mut u8 {
fn free(block: *const u8) {
unsafe {
let mut block_hdr = *(block.sub(size_of::<BlockHeader>()) as *mut BlockHeader);
let block_hdr = &mut *(block.sub(size_of::<BlockHeader>()) as *mut BlockHeader);
for i in 0..PAGE_SIZE / 4 {
let addr = *((MAIN_SECTOR + i * 4) as *const u32) as *const u8;
let mut hdr = *(addr as *const SectorHeader);
if addr.is_null() {
continue;
}
let hdr = &mut *(addr as *mut SectorHeader);
if addr < block && (block as usize) < (addr as usize) + hdr.size {
hdr.size_left += block_hdr.size;
hdr.size_left += block_hdr.size + size_of::<BlockHeader>();
if hdr.size_left == hdr.size - size_of::<SectorHeader>() {
free(addr)
sys::free(addr); // whole sector is free, hand it back to OS
*((MAIN_SECTOR + i * 4) as *mut u32) = 0; // and drop from the table
} else {
block_hdr.sign = Sign::Free;
}
break;
}
}
if !sys::free(block) {
panic!("Free failed");
}
}
}
@@ -181,4 +190,4 @@ unsafe impl alloc::alloc::GlobalAlloc for GlobalAlloc {
}
#[global_allocator]
static ALLOC: GlobalAlloc = GlobalAlloc;
static ALLOC: GlobalAlloc = GlobalAlloc;

View File

@@ -20,21 +20,3 @@ SF_SYS_MISC = 68
SSF_MEM_ALLOC = 12
SSF_MEM_FREE = 13
SSF_LOAD_DLL = 19
SF_NETWORK_GET = 74
SSF_DEVICE_COUNT = -1
SSF_DEVICE_TYPE = 0
SSF_DEVICE_NAME = 1
SSF_RESET_DEVICE = 2
SSF_STOP_DEVICE = 3
SSF_DEVICE_POINTER = 4
SSF_TX_PACKET_COUNT = 6
SSF_RX_PACKET_COUNT = 7
SSF_TX_BYTE_COUNT = 8
SSF_RX_BYTE_COUNT = 9
SSF_LINK_STATUS = 10
SSF_TX_PACKET_ERROR_COUNT = 11
SSF_TX_PACKET_DROP_COUNT = 12
SSF_TX_PACKET_MISS_COUNT = 13
SSF_RX_PACKET_ERROR_COUNT = 14
SSF_RX_PACKET_DROP_COUNT = 15
SSF_RX_PACKET_MISS_COUNT = 16

View File

@@ -1,6 +1,5 @@
pub mod graphics;
pub mod input;
pub mod network;
pub mod system;
pub mod threads;
pub mod windows;

View File

@@ -1,186 +0,0 @@
use crate::sys;
use alloc::string::String;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NetworkError {
NoDevice,
KernelError(i32),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DeviceType {
Loopback,
Ethernet,
Unknown(u32),
}
impl DeviceType {
fn from_raw(v: u32) -> Self {
match v {
0 => DeviceType::Loopback,
1 => DeviceType::Ethernet,
other => DeviceType::Unknown(other),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LinkStatus(u32);
impl LinkStatus {
pub fn is_up(&self) -> bool {
self.0 & 0b0001 != 0
}
pub fn is_full_duplex(&self) -> bool {
self.0 & 0b0010 != 0
}
pub fn speed_mbps(&self) -> Option<u32> {
match self.0 & 0b1100 {
0b0100 => Some(10),
0b1000 => Some(100),
0b1100 => Some(1000),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct DeviceStats {
pub tx_packets: u32,
pub rx_packets: u32,
pub tx_bytes: u64,
pub rx_bytes: u64,
pub tx_errors: u32,
pub tx_dropped: u32,
pub tx_missed: u32,
pub rx_errors: u32,
pub rx_dropped: u32,
pub rx_missed: u32,
}
#[derive(Debug, Clone, Copy)]
pub struct DeviceInfo {
pub device_type: DeviceType,
pub link: LinkStatus,
}
fn raw_get(subfunc: u8, device: u8) -> Result<i32, NetworkError> {
let r = unsafe { sys::network_get(subfunc, device, 0) };
if r == -1 {
Err(NetworkError::NoDevice)
} else {
Ok(r)
}
}
fn raw_get_u64(subfunc: u8, device: u8) -> Result<u64, NetworkError> {
let mut hi: u32 = 0;
let lo = unsafe { sys::network_get_u64(subfunc, device, &mut hi as *mut u32) };
if lo == -1 {
Err(NetworkError::NoDevice)
} else {
Ok((hi as u64) << 32 | (lo as u32) as u64)
}
}
pub fn device_count() -> u32 {
let r = unsafe { sys::network_get(0xFFu8, 0, 0) };
if r < 0 {
0
} else {
r as u32
}
}
pub fn device_type(device: u8) -> Result<DeviceType, NetworkError> {
raw_get(0, device).map(|v| DeviceType::from_raw(v as u32))
}
pub fn device_name(device: u8) -> Result<String, NetworkError> {
let mut buf = [0u8; 64];
let r = unsafe { sys::network_get(1, device, buf.as_mut_ptr() as u32) };
if r == -1 {
return Err(NetworkError::NoDevice);
}
let len = buf.iter().position(|&c| c == 0).unwrap_or(buf.len());
Ok(String::from(core::str::from_utf8(&buf[..len]).unwrap_or("?")))
}
pub fn reset_device(device: u8) -> Result<(), NetworkError> {
raw_get(2, device).map(|_| ())
}
pub fn stop_device(device: u8) -> Result<(), NetworkError> {
raw_get(3, device).map(|_| ())
}
pub fn device_pointer(device: u8) -> Result<u32, NetworkError> {
raw_get(4, device).map(|v| v as u32)
}
pub fn tx_packet_count(device: u8) -> Result<u32, NetworkError> {
raw_get(6, device).map(|v| v as u32)
}
pub fn rx_packet_count(device: u8) -> Result<u32, NetworkError> {
raw_get(7, device).map(|v| v as u32)
}
pub fn tx_byte_count(device: u8) -> Result<u64, NetworkError> {
raw_get_u64(8, device)
}
pub fn rx_byte_count(device: u8) -> Result<u64, NetworkError> {
raw_get_u64(9, device)
}
pub fn link_status(device: u8) -> Result<LinkStatus, NetworkError> {
raw_get(10, device).map(|v| LinkStatus(v as u32))
}
pub fn tx_error_count(device: u8) -> Result<u32, NetworkError> {
raw_get(11, device).map(|v| v as u32)
}
pub fn tx_drop_count(device: u8) -> Result<u32, NetworkError> {
raw_get(12, device).map(|v| v as u32)
}
pub fn tx_miss_count(device: u8) -> Result<u32, NetworkError> {
raw_get(13, device).map(|v| v as u32)
}
pub fn rx_error_count(device: u8) -> Result<u32, NetworkError> {
raw_get(14, device).map(|v| v as u32)
}
pub fn rx_drop_count(device: u8) -> Result<u32, NetworkError> {
raw_get(15, device).map(|v| v as u32)
}
pub fn rx_miss_count(device: u8) -> Result<u32, NetworkError> {
raw_get(16, device).map(|v| v as u32)
}
pub fn device_info(device: u8) -> Result<DeviceInfo, NetworkError> {
let device_type = device_type(device)?;
let link = link_status(device)?;
Ok(DeviceInfo { device_type, link })
}
pub fn device_stats(device: u8) -> Result<DeviceStats, NetworkError> {
Ok(DeviceStats {
tx_packets: tx_packet_count(device)?,
rx_packets: rx_packet_count(device)?,
tx_bytes: tx_byte_count(device)?,
rx_bytes: rx_byte_count(device)?,
tx_errors: tx_error_count(device)?,
tx_dropped: tx_drop_count(device)?,
tx_missed: tx_miss_count(device)?,
rx_errors: rx_error_count(device)?,
rx_dropped: rx_drop_count(device)?,
rx_missed: rx_miss_count(device)?,
})
}

View File

@@ -31,12 +31,3 @@ pub unsafe extern "C" fn memcmp(s1: *mut u8, s2: *const u8, n: usize) -> i32 {
0
}
#[no_mangle]
pub unsafe extern "C" fn strlen(str: *mut u8) -> usize {
let mut len = 0usize;
loop {
if *str.add(len) == 0 { return len; }
len += 1;
}
}

View File

@@ -67,12 +67,4 @@ extern "C" {
// 68.19
#[link_name = "_load_dll"]
pub fn load_dll(name: *const u8) -> *const u32;
// 74
#[link_name = "_network_get"]
pub fn network_get(subfunc: u8, device: u8, ecx: u32) -> i32;
// 74 (u64 return: eax=lo, ebx=hi via out-ptr)
#[link_name = "_network_get_u64"]
pub fn network_get_u64(subfunc: u8, device: u8, ebx_out: *mut u32) -> i32;
}

View File

@@ -20,8 +20,6 @@ section '.text'
public _get_lang
public _load_dll
public _set_event_mask
public _network_get
public _network_get_u64
_exit:
mov eax, SF_TERMINATE_PROCESS
@@ -145,26 +143,3 @@ _set_event_mask:
int 0x40
ret
_network_get:
push ebx
mov eax, SF_NETWORK_GET
movzx ebx, byte [esp + 4 * 2]
mov bh, byte [esp + 4 * 3]
mov ecx, [esp + 4 * 4]
int 0x40
pop ebx
ret
_network_get_u64:
push ebx
push edi
mov eax, SF_NETWORK_GET
movzx ebx, byte [esp + 4 * 3]
mov bh, byte [esp + 4 * 4]
xor ecx, ecx
mov edi, [esp + 4 * 5]
int 0x40
mov [edi], ebx
pop edi
pop ebx
ret