Compare commits

...

12 commits

Author SHA1 Message Date
Myles "Mellurboo" Wilson
f171ff7278
pr: Standardize string functions for freestanding env #29
Some checks are pending
Nightly Build / build-and-release (push) Waiting to run
2026-05-11 22:10:58 +02:00
Lluciocc
51900ca0a7
Update syscalls id 2026-05-11 21:23:28 +02:00
boreddevnl
4141766c4f doc: Update contributors block README.md 2026-05-11 20:57:00 +02:00
boreddevnl
640c548a4b brand: Add boredshadow.png - Created by naplon74
Co-Authored-By: Naplon <94738563+naplon74@users.noreply.github.com>
2026-05-11 20:55:46 +02:00
Chris
0b31c5bb64
brand: Remove old (kind of ugly) wallpaper 2026-05-11 20:47:46 +02:00
Lluciocc
912bd4a20e
pr: Add ps && hexdump (#26)
* Adding hexdump and ps.c

* Add hexdump and ps command descriptions to help

* Update with missing ;
2026-05-11 20:28:16 +02:00
Lluciocc
2bb15d517f
pr: Create pull_request_template.md (#27)
Add a pull request template for better PR submissions.
2026-05-11 19:56:45 +02:00
boreddevnl
d45a19aac1 docs(appdev): update best practices for loop throttling 2026-05-11 19:52:48 +02:00
boreddevnl
a3a4494265 perf(userland): replace sys_yield with sleep for WAY better idle efficiency 2026-05-11 19:52:43 +02:00
boreddevnl
78a9afebf4 perf(terminal): optimize string rendering via color buffering 2026-05-11 19:52:18 +02:00
boreddevnl
309f68df48 feat(taskman): implement scrollbar and UI optimizations 2026-05-11 19:52:07 +02:00
boreddevnl
d3a353c9f8 legal: Add license header for zeyadhost 2026-05-11 19:38:50 +02:00
48 changed files with 1311 additions and 794 deletions

28
.github/pull_request_template.md vendored Normal file
View file

@ -0,0 +1,28 @@
## Description
Describe the changes made in this PR.
---
## Testing
- [ ] Code has been tested
- [ ] Existing tests pass
Notes:
<!-- Add anything relevant about testing -->
---
## Documentation
- [ ] Documentation updated if needed
Notes:
<!-- Add anything relevant about documentation -->
---
## Additional Notes
<!-- Anything reviewers should know -->

View file

@ -99,13 +99,20 @@
</a><br />
Artwork
</td>
<td align="center">
<td align="center">
<a href="https://github.com/zeyadhost">
<img src="https://github.com/zeyadhost.png?size=80" width="60" /><br />
<sub><b>Zeyadhost</b></sub>
</a><br />
Contributor
</td>
<td align="center">
<a href="https://github.com/naplon74">
<img src="https://github.com/naplon74.png?size=80" width="60" /><br />
<sub><b>Artwork</b></sub>
</a><br />
Contributor
</td>
</tr>
</table>

View file

@ -11,7 +11,7 @@ This example demonstrates how to create an empty window that stays active on the
* Including `libui.h` and the event structure.
* Creating a `ui_window_t` handle.
* Creating an infinite event loop using `ui_get_event()`.
* Yielding CPU time to the kernel via `sys_yield()`.
* Yielding CPU time via `sleep(ms)`.
* Declaring app metadata via source annotations.
---
@ -50,10 +50,11 @@ int main(void) {
}
}
// 4. CRITICAL: Yield the remainder of our timeslice
// 4. CRITICAL: Throttle our loop to save CPU
// If we don't do this, the while(1) loop will consume 100% of the CPU
// and starve the rest of the OS!
sys_yield();
// and starve the rest of the OS! A 10ms sleep allows for ~100 FPS
// event polling while letting the CPU actually idle.
sys_system(SYSTEM_CMD_SLEEP, 10, 0, 0, 0);
}
// Returning from main will automatically destroy the window and exit the process.
@ -66,7 +67,7 @@ int main(void) {
1. **Window Handle (`wid`)**: `ui_window_create` sends a request to the kernel. The kernel allocates the memory for the window and returns a numerical ID (the handle) that we use for all future interactions with that specific window.
2. **The Event Loop**: Graphical programs run forever until closed. The `while (1)` loop serves this purpose.
3. **Polling**: `ui_get_event` asks the kernel, "Hey, did the user click my window or press a key since the last time I asked?". It is non-blocking, so it immediately returns `false` if nothing happened.
4. **CPU Yielding**: Since we are constantly polling in a tight loop, we call `sys_yield()` at the end of the loop frame. This politely tells the OS scheduler, "I'm done checking for events, go ahead and let another program run for a bit."
4. **CPU Throttling**: Since we are constantly polling in a loop, we call `sys_system(SYSTEM_CMD_SLEEP, 10, ...)` at the end of the loop frame. This tells the OS scheduler, "I'm done checking for events, don't run me again for at least 10ms." This allows the CPU to actually enter a low-power state and makes the system much smoother.
5. **`BOREDOS_APP_DESC` / `BOREDOS_APP_ICONS`**: Embedded into the `.elf` by the build system as a BoredOS NOTE section. The Window Manager reads this at runtime to render the app's icon on the Desktop and in the File Explorer. See [`elf_metadata.md`](../elf_metadata.md) for full details.
## Running It

View file

@ -76,8 +76,8 @@ int main(void) {
// Step D: Instruct the compositor to flush our drawing buffer to the physical screen
ui_mark_dirty(wid, 0, 0, W_WIDTH, W_HEIGHT);
// 4. Yield and throttle
sys_yield();
// 4. Yield and throttle (targeting ~60 FPS)
sys_system(SYSTEM_CMD_SLEEP, 16, 0, 0, 0);
}
return 0;
@ -93,4 +93,4 @@ int main(void) {
5. **`BOREDOS_APP_DESC` / `BOREDOS_APP_ICONS`**: Embedded into the compiled `.elf` as a BoredOS NOTE section. The Desktop and File Explorer read this to show the game's icon instead of the generic binary icon. See [`elf_metadata.md`](../elf_metadata.md) for full details.
> [!WARNING]
> Because `sys_yield()`'s pause duration depends heavily on CPU load and how many other processes are running (or QEMU emulation speed), tying physics/movement strictly to loops can make the game run faster on faster computers. Advanced developers will want to calculate delta time (time elapsed since the last frame) for smooth motion.
> Because `sys_system(SYSTEM_CMD_SLEEP, ...)`'s pause duration depends heavily on CPU load and how many other processes are running (or QEMU emulation speed), tying physics/movement strictly to loops can make the game run faster on faster computers. Advanced developers will want to calculate delta time (time elapsed since the last frame) for smooth motion.

View file

@ -94,8 +94,8 @@ Notes:
| 47 | `SYSTEM_CMD_SET_RESOLUTION` | Set display mode |
| 49 | `SYSTEM_CMD_SET_KEYBOARD_LAYOUT` | Set active keyboard layout ID |
| 51 | `SYSTEM_CMD_GET_KEYBOARD_LAYOUT` | Get current keyboard layout ID |
| 78 | `SYSTEM_GET_CURSOR_SCALE` | Get the current BoredWM cursor scale |
| 79 | `SYSTEM_SET_CURSOR_SCALE` | Set the BoredWM cursor scale |
| 52 | `SYSTEM_GET_CURSOR_SCALE` | Get the current BoredWM cursor scale |
| 53 | `SYSTEM_SET_CURSOR_SCALE` | Set the BoredWM cursor scale |
### Time, power, and system state
@ -110,8 +110,8 @@ Notes:
| 28 | `SYSTEM_CMD_GET_SHELL_CONFIG` | Read shell config value |
| 32 | `SYSTEM_CMD_RTC_SET` | Set RTC datetime |
| 41 | `SYSTEM_CMD_SET_RAW_MODE` | Terminal raw-mode control |
| 43 | `SYSTEM_CMD_YIELD` | Yield scheduler timeslice |
| 46 | `SYSTEM_CMD_SLEEP` | Sleep current process |
| 43 | `SYSTEM_CMD_YIELD` | Yield scheduler timeslice (Not recommended for idle loops) |
| 46 | `SYSTEM_CMD_SLEEP` | Sleep current process (Recommended for throttling) |
### Network
@ -187,7 +187,7 @@ Notes:
## Common Wrapper API (`src/userland/libc/syscall.h`)
Typical wrappers used by apps:
- Process/system: `sys_exit`, `sys_yield`, `sys_spawn`, `sys_exec`, `sys_waitpid`, `sys_kill_signal`
- Process/system: `sys_exit`, `sys_yield`, `sys_system` (with `SYSTEM_CMD_SLEEP`), `sys_spawn`, `sys_exec`, `sys_waitpid`
- Filesystem: `sys_open`, `sys_read`, `sys_write_fs`, `sys_close`, `sys_seek`, `sys_tell`, `sys_size`, `sys_list`
- Network: `sys_network_init`, `sys_network_dhcp_acquire`, `sys_udp_send`, `sys_tcp_connect`, `sys_tcp_recv_nb`, `sys_dns_lookup`
- TTY: `sys_tty_create`, `sys_tty_read_out`, `sys_tty_write_in`, `sys_tty_set_fg`

View file

@ -68,9 +68,9 @@ Applications must continuously poll for events inside an infinite `$while(1)` lo
Returns `true` if an event was waiting in the queue, populating the `ev` structure. Returns `false` if the queue is empty.
> [!IMPORTANT]
> Because `ui_get_event` is non-blocking, you must call `sys_yield();` inside your event loop if no event was received. In BoredOS's **Multi-Core (SMP)** architecture, failing to yield will pin a CPU core to 100% usage, potentially starving other processes.
> Because `ui_get_event` is non-blocking, you must call `sleep(ms);` or `sys_system(SYSTEM_CMD_SLEEP, ms, ...)` inside your event loop if no event was received.
>
> All UI syscalls are **Thread-Safe** at the kernel level via the global GUI spinlock.
> Historically, BoredOS used `sys_yield()`, but in the **Multi-Core (SMP)** architecture, yielding alone will still pin a CPU core to 100% usage. Using a short sleep (e.g., 5-10ms) ensures your app remains responsive while allowing the CPU to actually idle.
### Graphical Event Structure

View file

@ -7,18 +7,18 @@
#include "../drivers/acpi.h"
void k_memset(void *dest, int val, size_t len) {
void memset(void *dest, int val, size_t len) {
unsigned char *ptr = (unsigned char *)dest;
while (len-- > 0) *ptr++ = (unsigned char)val;
}
void k_memcpy(void *dest, const void *src, size_t len) {
void memcpy(void *dest, const void *src, size_t len) {
unsigned char *d = (unsigned char *)dest;
const unsigned char *s = (const unsigned char *)src;
while (len-- > 0) *d++ = *s++;
}
int k_memcmp (const void *str1, const void *str2, size_t count) {
int memcmp(const void *str1, const void *str2, size_t count) {
register const unsigned char *s1 = (const unsigned char*)str1;
register const unsigned char *s2 = (const unsigned char*)str2;
@ -29,13 +29,30 @@ int k_memcmp (const void *str1, const void *str2, size_t count) {
return 0;
}
size_t k_strlen(const char *str) {
void *memmove(void *dest, const void *src, uint64_t n) {
uint8_t *pdest = (uint8_t *)dest;
const uint8_t *psrc = (const uint8_t *)src;
if (src > dest) {
for (uint64_t i = 0; i < n; i++) {
pdest[i] = psrc[i];
}
} else if (src < dest) {
for (uint64_t i = n; i > 0; i--) {
pdest[i-1] = psrc[i-1];
}
}
return dest;
}
size_t strlen(const char *str) {
size_t len = 0;
while (str[len]) len++;
return len;
}
int k_strcmp(const char *s1, const char *s2) {
int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
@ -43,7 +60,7 @@ int k_strcmp(const char *s1, const char *s2) {
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
int k_strncmp(const char *s1, const char *s2, size_t n) {
int strncmp(const char *s1, const char *s2, size_t n) {
while (n && *s1 && (*s1 == *s2)) {
s1++;
s2++;
@ -53,12 +70,12 @@ int k_strncmp(const char *s1, const char *s2, size_t n) {
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
}
void k_strcpy(char *dest, const char *src) {
void strcpy(char *dest, const char *src) {
while (*src) *dest++ = *src++;
*dest = 0;
}
int k_atoi(const char *str) {
int atoi(const char *str) {
int res = 0;
int sign = 1;
if (*str == '-') { sign = -1; str++; }
@ -69,7 +86,7 @@ int k_atoi(const char *str) {
return res * sign;
}
void k_itoa(int n, char *buf) {
void itoa(int n, char *buf) {
if (n == 0) {
buf[0] = '0'; buf[1] = 0; return;
}
@ -89,7 +106,7 @@ void k_itoa(int n, char *buf) {
}
}
void k_itoa_hex(uint64_t n, char *buf) {
void itoa_hex(uint64_t n, char *buf) {
const char *digits = "0123456789ABCDEF";
if (n == 0) {
buf[0] = '0';

View file

@ -9,16 +9,17 @@
#include <stdbool.h>
// Kernel string utilities
void k_memset(void *dest, int val, size_t len);
void k_memcpy(void *dest, const void *src, size_t len);
int k_memcmp (const void *str1, const void *str2, size_t count);
size_t k_strlen(const char *str);
int k_strcmp(const char *s1, const char *s2);
int k_strncmp(const char *s1, const char *s2, size_t n);
void k_strcpy(char *dest, const char *src);
int k_atoi(const char *str);
void k_itoa(int n, char *buf);
void k_itoa_hex(uint64_t n, char *buf);
void *memmove(void *dest, const void *src, uint64_t n);
void memset(void *dest, int val, size_t len);
void memcpy(void *dest, const void *src, size_t len);
int memcmp (const void *str1, const void *str2, size_t count);
size_t strlen(const char *str);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
void strcpy(char *dest, const char *src);
int atoi(const char *str);
void itoa(int n, char *buf);
void itoa_hex(uint64_t n, char *buf);
// Kernel timing utilities
void k_delay(int iterations);

View file

@ -237,7 +237,7 @@ static void fat32_mkdir_recursive(const char *path) {
static bool cmdline_has_flag(const char *cmdline, const char *flag) {
if (!cmdline || !flag || !flag[0]) return false;
int flag_len = (int)k_strlen(flag);
int flag_len = (int)strlen(flag);
const char *p = cmdline;
while (*p) {
while (*p == ' ') p++;
@ -245,19 +245,19 @@ static bool cmdline_has_flag(const char *cmdline, const char *flag) {
const char *start = p;
while (*p && *p != ' ') p++;
int len = (int)(p - start);
if (len == flag_len && k_strncmp(start, flag, (size_t)flag_len) == 0) return true;
if (len == flag_len && strncmp(start, flag, (size_t)flag_len) == 0) return true;
}
return false;
}
static bool cmdline_read_value(const char *cmdline, const char *key, char *out, int out_len) {
if (!cmdline || !key || !out || out_len <= 1) return false;
int key_len = (int)k_strlen(key);
int key_len = (int)strlen(key);
const char *p = cmdline;
while (*p) {
while (*p == ' ') p++;
if (!*p) break;
if (k_strncmp(p, key, (size_t)key_len) == 0) {
if (strncmp(p, key, (size_t)key_len) == 0) {
const char *val = p + key_len;
int i = 0;
while (*val && *val != ' ' && i < out_len - 1) {
@ -390,10 +390,10 @@ void kmain(void) {
if (bootloader_info_request.response != NULL) {
if (bootloader_info_request.response->name) {
k_strcpy(g_bootfs_state.bootloader_name, bootloader_info_request.response->name);
strcpy(g_bootfs_state.bootloader_name, bootloader_info_request.response->name);
}
if (bootloader_info_request.response->version) {
k_strcpy(g_bootfs_state.bootloader_version, bootloader_info_request.response->version);
strcpy(g_bootfs_state.bootloader_version, bootloader_info_request.response->version);
}
}

View file

@ -84,17 +84,17 @@ void kernel_panic(registers_t *regs, const char *error_name) {
char hex_buf[17];
serial_write("Vector: 0x");
k_itoa_hex(regs->int_no, hex_buf);
itoa_hex(regs->int_no, hex_buf);
serial_write(hex_buf);
serial_write("\n");
serial_write("Error Code: 0x");
k_itoa_hex(regs->err_code, hex_buf);
itoa_hex(regs->err_code, hex_buf);
serial_write(hex_buf);
serial_write("\n");
serial_write("RIP: 0x");
k_itoa_hex(regs->rip, hex_buf);
itoa_hex(regs->rip, hex_buf);
serial_write(hex_buf);
serial_write("\n");
@ -102,7 +102,7 @@ void kernel_panic(registers_t *regs, const char *error_name) {
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));
serial_write("CR2: 0x");
k_itoa_hex(cr2, hex_buf);
itoa_hex(cr2, hex_buf);
serial_write(hex_buf);
serial_write("\n");
}

View file

@ -105,48 +105,48 @@ void platform_get_cpu_flags(char *flags_str) {
asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1));
// ECX flags
if (ecx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "sse3 ");
if (ecx & (1 << 1)) k_strcpy(flags_str + k_strlen(flags_str), "pclmulqdq ");
if (ecx & (1 << 3)) k_strcpy(flags_str + k_strlen(flags_str), "monitor ");
if (ecx & (1 << 6)) k_strcpy(flags_str + k_strlen(flags_str), "ssse3 ");
if (ecx & (1 << 9)) k_strcpy(flags_str + k_strlen(flags_str), "sdbg ");
if (ecx & (1 << 12)) k_strcpy(flags_str + k_strlen(flags_str), "fma ");
if (ecx & (1 << 13)) k_strcpy(flags_str + k_strlen(flags_str), "cx16 ");
if (ecx & (1 << 19)) k_strcpy(flags_str + k_strlen(flags_str), "sse4_1 ");
if (ecx & (1 << 20)) k_strcpy(flags_str + k_strlen(flags_str), "sse4_2 ");
if (ecx & (1 << 23)) k_strcpy(flags_str + k_strlen(flags_str), "popcnt ");
if (ecx & (1 << 25)) k_strcpy(flags_str + k_strlen(flags_str), "aes ");
if (ecx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "xsave ");
if (ecx & (1 << 28)) k_strcpy(flags_str + k_strlen(flags_str), "avx ");
if (ecx & (1 << 0)) strcpy(flags_str + strlen(flags_str), "sse3 ");
if (ecx & (1 << 1)) strcpy(flags_str + strlen(flags_str), "pclmulqdq ");
if (ecx & (1 << 3)) strcpy(flags_str + strlen(flags_str), "monitor ");
if (ecx & (1 << 6)) strcpy(flags_str + strlen(flags_str), "ssse3 ");
if (ecx & (1 << 9)) strcpy(flags_str + strlen(flags_str), "sdbg ");
if (ecx & (1 << 12)) strcpy(flags_str + strlen(flags_str), "fma ");
if (ecx & (1 << 13)) strcpy(flags_str + strlen(flags_str), "cx16 ");
if (ecx & (1 << 19)) strcpy(flags_str + strlen(flags_str), "sse4_1 ");
if (ecx & (1 << 20)) strcpy(flags_str + strlen(flags_str), "sse4_2 ");
if (ecx & (1 << 23)) strcpy(flags_str + strlen(flags_str), "popcnt ");
if (ecx & (1 << 25)) strcpy(flags_str + strlen(flags_str), "aes ");
if (ecx & (1 << 26)) strcpy(flags_str + strlen(flags_str), "xsave ");
if (ecx & (1 << 28)) strcpy(flags_str + strlen(flags_str), "avx ");
// EDX flags
if (edx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "fpu ");
if (edx & (1 << 3)) k_strcpy(flags_str + k_strlen(flags_str), "pse ");
if (edx & (1 << 4)) k_strcpy(flags_str + k_strlen(flags_str), "tsc ");
if (edx & (1 << 6)) k_strcpy(flags_str + k_strlen(flags_str), "pae ");
if (edx & (1 << 8)) k_strcpy(flags_str + k_strlen(flags_str), "cx8 ");
if (edx & (1 << 9)) k_strcpy(flags_str + k_strlen(flags_str), "apic ");
if (edx & (1 << 11)) k_strcpy(flags_str + k_strlen(flags_str), "sep ");
if (edx & (1 << 15)) k_strcpy(flags_str + k_strlen(flags_str), "cmov ");
if (edx & (1 << 23)) k_strcpy(flags_str + k_strlen(flags_str), "mmx ");
if (edx & (1 << 24)) k_strcpy(flags_str + k_strlen(flags_str), "fxsr ");
if (edx & (1 << 25)) k_strcpy(flags_str + k_strlen(flags_str), "sse ");
if (edx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "sse2 ");
if (edx & (1 << 0)) strcpy(flags_str + strlen(flags_str), "fpu ");
if (edx & (1 << 3)) strcpy(flags_str + strlen(flags_str), "pse ");
if (edx & (1 << 4)) strcpy(flags_str + strlen(flags_str), "tsc ");
if (edx & (1 << 6)) strcpy(flags_str + strlen(flags_str), "pae ");
if (edx & (1 << 8)) strcpy(flags_str + strlen(flags_str), "cx8 ");
if (edx & (1 << 9)) strcpy(flags_str + strlen(flags_str), "apic ");
if (edx & (1 << 11)) strcpy(flags_str + strlen(flags_str), "sep ");
if (edx & (1 << 15)) strcpy(flags_str + strlen(flags_str), "cmov ");
if (edx & (1 << 23)) strcpy(flags_str + strlen(flags_str), "mmx ");
if (edx & (1 << 24)) strcpy(flags_str + strlen(flags_str), "fxsr ");
if (edx & (1 << 25)) strcpy(flags_str + strlen(flags_str), "sse ");
if (edx & (1 << 26)) strcpy(flags_str + strlen(flags_str), "sse2 ");
// Extended leaf 0x80000001 for advanced flags
asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(0x80000001));
if (edx & (1 << 11)) k_strcpy(flags_str + k_strlen(flags_str), "syscall ");
if (edx & (1 << 20)) k_strcpy(flags_str + k_strlen(flags_str), "nx ");
if (edx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "pdpe1gb ");
if (edx & (1 << 27)) k_strcpy(flags_str + k_strlen(flags_str), "rdtscp ");
if (edx & (1 << 29)) k_strcpy(flags_str + k_strlen(flags_str), "lm ");
if (edx & (1 << 11)) strcpy(flags_str + strlen(flags_str), "syscall ");
if (edx & (1 << 20)) strcpy(flags_str + strlen(flags_str), "nx ");
if (edx & (1 << 26)) strcpy(flags_str + strlen(flags_str), "pdpe1gb ");
if (edx & (1 << 27)) strcpy(flags_str + strlen(flags_str), "rdtscp ");
if (edx & (1 << 29)) strcpy(flags_str + strlen(flags_str), "lm ");
if (ecx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "lahf_lm ");
if (ecx & (1 << 5)) k_strcpy(flags_str + k_strlen(flags_str), "abm ");
if (ecx & (1 << 0)) strcpy(flags_str + strlen(flags_str), "lahf_lm ");
if (ecx & (1 << 5)) strcpy(flags_str + strlen(flags_str), "abm ");
// Remove trailing space
int len = k_strlen(flags_str);
int len = strlen(flags_str);
if (len > 0 && flags_str[len-1] == ' ') {
flags_str[len-1] = '\0';
}

View file

@ -55,7 +55,7 @@ static struct acpi_sdt *acpi_get_sdt(const char signature[4]) {
for (size_t i = 0; i < entries; i++) {
struct acpi_sdt *tbl = (struct acpi_sdt *)p2v(acpi_xsdt->tables[i]);
if (!tbl) continue;
if (!k_memcmp(tbl->signature, signature, 4))
if (!memcmp(tbl->signature, signature, 4))
return tbl;
}
}
@ -74,7 +74,7 @@ static struct acpi_sdt *acpi_get_sdt(const char signature[4]) {
for (size_t i = 0; i < entries; i++) {
struct acpi_sdt *tbl = (struct acpi_sdt *)p2v(tables[i]);
if (!tbl) continue;
if (!k_memcmp(tbl->signature, signature, 4))
if (!memcmp(tbl->signature, signature, 4))
return tbl;
}
@ -89,14 +89,14 @@ void acpi_parse_s5(void) {
char *dsdt = (char *)p2v((uintptr_t)acpi_fadt->dsdt);
if (k_memcmp(dsdt, "DSDT", 4) != 0) return;
if (memcmp(dsdt, "DSDT", 4) != 0) return;
uint32_t dsdt_len = *(uint32_t*)(dsdt + 4);
char *ptr = dsdt + 36;
char *end = dsdt + dsdt_len;
while (ptr < end) {
if (k_memcmp(ptr, "_S5_", 4) == 0) {
if (memcmp(ptr, "_S5_", 4) == 0) {
ptr += 4;
if (*ptr == 0x12) {
ptr += 3;

View file

@ -70,7 +70,7 @@ static char g_limine_conf_path[64] = "";
static bootfs_custom_file_t *bootfs_find_custom(const char *name) {
bootfs_custom_file_t *f = (bootfs_custom_file_t*)g_bootfs_state.custom_files;
while (f) {
if (k_strcmp(f->name, name) == 0) return f;
if (strcmp(f->name, name) == 0) return f;
f = f->next;
}
return NULL;
@ -82,8 +82,8 @@ void bootfs_register_file(const char *name, void *data, uint32_t size) {
if (!f) {
f = (bootfs_custom_file_t*)kmalloc(sizeof(bootfs_custom_file_t));
if (!f) return;
k_memset(f, 0, sizeof(bootfs_custom_file_t));
k_strcpy(f->name, name);
memset(f, 0, sizeof(bootfs_custom_file_t));
strcpy(f->name, name);
f->next = (bootfs_custom_file_t*)g_bootfs_state.custom_files;
g_bootfs_state.custom_files = f;
}
@ -94,13 +94,13 @@ void bootfs_register_file(const char *name, void *data, uint32_t size) {
static bool is_metadata_path(const char *path) {
if (!path) return false;
return k_strncmp(path, "metadata", 8) == 0;
return strncmp(path, "metadata", 8) == 0;
}
static bool is_metadata_file(const char *path) {
if (k_strcmp(path, "metadata/boot_time") == 0) return true;
if (k_strcmp(path, "metadata/boot_flags") == 0) return true;
if (k_strcmp(path, "metadata/version") == 0) return true;
if (strcmp(path, "metadata/boot_time") == 0) return true;
if (strcmp(path, "metadata/boot_flags") == 0) return true;
if (strcmp(path, "metadata/version") == 0) return true;
return false;
}
@ -111,8 +111,8 @@ static void* bootfs_open(void *fs_private, const char *path, const char *mode) {
bootfs_handle_t *h = (bootfs_handle_t*)kmalloc(sizeof(bootfs_handle_t));
if (!h) return NULL;
k_memset(h, 0, sizeof(bootfs_handle_t));
k_strcpy(h->path, path);
memset(h, 0, sizeof(bootfs_handle_t));
strcpy(h->path, path);
h->offset = 0;
if (path[0] == '\0') {
@ -134,28 +134,28 @@ static int generate_metadata_content(const char *file, char *buffer, int max_siz
buffer[0] = '\0';
int len = 0;
if (k_strcmp(file, "metadata/boot_time") == 0) {
if (strcmp(file, "metadata/boot_time") == 0) {
extern uint32_t wm_get_ticks(void);
uint32_t ticks = wm_get_ticks();
k_strcpy(buffer, "Boot time: ");
strcpy(buffer, "Boot time: ");
char time_buf[32];
k_itoa(g_bootfs_state.boot_time_ms, time_buf);
k_strcpy(buffer + k_strlen(buffer), time_buf);
k_strcpy(buffer + k_strlen(buffer), " ms\nTicks: ");
k_itoa(ticks, time_buf);
k_strcpy(buffer + k_strlen(buffer), time_buf);
k_strcpy(buffer + k_strlen(buffer), "\n");
len = k_strlen(buffer);
} else if (k_strcmp(file, "metadata/version") == 0) {
k_strcpy(buffer, "Bootloader: ");
k_strcpy(buffer + k_strlen(buffer), g_bootfs_state.bootloader_name);
k_strcpy(buffer + k_strlen(buffer), "\nVersion: ");
k_strcpy(buffer + k_strlen(buffer), g_bootfs_state.bootloader_version);
k_strcpy(buffer + k_strlen(buffer), "\n");
len = k_strlen(buffer);
} else if (k_strcmp(file, "metadata/boot_flags") == 0) {
k_strcpy(buffer, "Boot flags: 0x");
itoa(g_bootfs_state.boot_time_ms, time_buf);
strcpy(buffer + strlen(buffer), time_buf);
strcpy(buffer + strlen(buffer), " ms\nTicks: ");
itoa(ticks, time_buf);
strcpy(buffer + strlen(buffer), time_buf);
strcpy(buffer + strlen(buffer), "\n");
len = strlen(buffer);
} else if (strcmp(file, "metadata/version") == 0) {
strcpy(buffer, "Bootloader: ");
strcpy(buffer + strlen(buffer), g_bootfs_state.bootloader_name);
strcpy(buffer + strlen(buffer), "\nVersion: ");
strcpy(buffer + strlen(buffer), g_bootfs_state.bootloader_version);
strcpy(buffer + strlen(buffer), "\n");
len = strlen(buffer);
} else if (strcmp(file, "metadata/boot_flags") == 0) {
strcpy(buffer, "Boot flags: 0x");
char flags_buf[8];
uint8_t flags = g_bootfs_state.boot_flags;
int hex_digit = (flags >> 4) & 0xF;
@ -164,8 +164,8 @@ static int generate_metadata_content(const char *file, char *buffer, int max_siz
flags_buf[1] = hex_digit < 10 ? '0' + hex_digit : 'a' + (hex_digit - 10);
flags_buf[2] = '\n';
flags_buf[3] = '\0';
k_strcpy(buffer + k_strlen(buffer), flags_buf);
len = k_strlen(buffer);
strcpy(buffer + strlen(buffer), flags_buf);
len = strlen(buffer);
}
return len;
@ -180,30 +180,30 @@ static int bootfs_read(void *fs_private, void *handle, void *buf, int size) {
int content_len = 0;
if (k_strcmp(h->path, "limine.conf") == 0) {
k_memcpy(content_buffer, g_bootfs_state.limine_conf,
if (strcmp(h->path, "limine.conf") == 0) {
memcpy(content_buffer, g_bootfs_state.limine_conf,
g_bootfs_state.limine_conf_len);
content_len = g_bootfs_state.limine_conf_len;
} else if (k_strcmp(h->path, "kernel") == 0) {
k_strcpy(content_buffer, "Kernel reference\nSize: ");
} else if (strcmp(h->path, "kernel") == 0) {
strcpy(content_buffer, "Kernel reference\nSize: ");
char size_buf[32];
k_itoa(g_bootfs_state.kernel_size, size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), " bytes\n");
content_len = k_strlen(content_buffer);
} else if (k_strcmp(h->path, "initrd") == 0) {
k_strcpy(content_buffer, "Initial ramdisk reference\nSize: ");
itoa(g_bootfs_state.kernel_size, size_buf);
strcpy(content_buffer + strlen(content_buffer), size_buf);
strcpy(content_buffer + strlen(content_buffer), " bytes\n");
content_len = strlen(content_buffer);
} else if (strcmp(h->path, "initrd") == 0) {
strcpy(content_buffer, "Initial ramdisk reference\nSize: ");
char size_buf[32];
k_itoa(g_bootfs_state.initrd_size, size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), " bytes\n");
content_len = k_strlen(content_buffer);
} else if (k_strcmp(h->path, "initrd.tar") == 0) {
itoa(g_bootfs_state.initrd_size, size_buf);
strcpy(content_buffer + strlen(content_buffer), size_buf);
strcpy(content_buffer + strlen(content_buffer), " bytes\n");
content_len = strlen(content_buffer);
} else if (strcmp(h->path, "initrd.tar") == 0) {
kfree(content_buffer);
if (h->offset >= (int)g_bootfs_state.initrd_size) return 0;
int avail = (int)g_bootfs_state.initrd_size - h->offset;
int to_read = (size < avail) ? size : avail;
k_memcpy(buf, (uint8_t*)g_bootfs_state.initrd_ptr + h->offset, to_read);
memcpy(buf, (uint8_t*)g_bootfs_state.initrd_ptr + h->offset, to_read);
h->offset += to_read;
return to_read;
} else if (is_metadata_file(h->path)) {
@ -215,7 +215,7 @@ static int bootfs_read(void *fs_private, void *handle, void *buf, int size) {
if (h->offset >= (int)cf->size) return 0;
int avail = (int)cf->size - h->offset;
int to_read = (avail < size) ? avail : size;
k_memcpy(buf, cf->data + h->offset, to_read);
memcpy(buf, cf->data + h->offset, to_read);
h->offset += to_read;
return to_read;
}
@ -232,7 +232,7 @@ static int bootfs_read(void *fs_private, void *handle, void *buf, int size) {
int available = content_len - h->offset;
int read_size = (available < size) ? available : size;
k_memcpy(buf, content_buffer + h->offset, read_size);
memcpy(buf, content_buffer + h->offset, read_size);
h->offset += read_size;
kfree(content_buffer);
@ -243,7 +243,7 @@ static int bootfs_write(void *fs_private, void *handle, const void *buf, int siz
bootfs_handle_t *h = (bootfs_handle_t*)handle;
if (!h || !buf || size <= 0) return -1;
if (k_strcmp(h->path, "limine.conf") != 0) {
if (strcmp(h->path, "limine.conf") != 0) {
return -1;
}
@ -251,7 +251,7 @@ static int bootfs_write(void *fs_private, void *handle, const void *buf, int siz
if (max_write <= 0) return -1;
int write_size = (size < max_write) ? size : max_write;
k_memcpy(g_bootfs_state.limine_conf + h->offset, buf, write_size);
memcpy(g_bootfs_state.limine_conf + h->offset, buf, write_size);
h->offset += write_size;
if (h->offset > g_bootfs_state.limine_conf_len) {
@ -299,49 +299,49 @@ static int bootfs_readdir(void *fs_private, const char *rel_path, vfs_dirent_t *
if (rel_path[0] == '\0') {
if (count < max) {
k_strcpy(entries[count].name, "limine.conf");
strcpy(entries[count].name, "limine.conf");
entries[count].size = g_bootfs_state.limine_conf_len;
entries[count].is_directory = 0;
count++;
}
if (count < max) {
k_strcpy(entries[count].name, "kernel");
strcpy(entries[count].name, "kernel");
entries[count].size = g_bootfs_state.kernel_size;
entries[count].is_directory = 0;
count++;
}
if (count < max) {
k_strcpy(entries[count].name, "initrd");
strcpy(entries[count].name, "initrd");
entries[count].size = g_bootfs_state.initrd_size;
entries[count].is_directory = 0;
count++;
}
if (count < max) {
k_strcpy(entries[count].name, "initrd.tar");
strcpy(entries[count].name, "initrd.tar");
entries[count].size = g_bootfs_state.initrd_size;
entries[count].is_directory = 0;
count++;
}
if (count < max) {
k_strcpy(entries[count].name, "metadata");
strcpy(entries[count].name, "metadata");
entries[count].size = 0;
entries[count].is_directory = 1;
count++;
}
bootfs_custom_file_t *cf = (bootfs_custom_file_t*)g_bootfs_state.custom_files;
while (cf && count < max) {
k_strcpy(entries[count].name, cf->name);
strcpy(entries[count].name, cf->name);
entries[count].size = cf->size;
entries[count].is_directory = 0;
count++;
cf = cf->next;
}
}
else if (k_strcmp(rel_path, "metadata") == 0) {
else if (strcmp(rel_path, "metadata") == 0) {
const char *meta_files[] = {
"boot_time",
"boot_flags",
@ -349,7 +349,7 @@ static int bootfs_readdir(void *fs_private, const char *rel_path, vfs_dirent_t *
};
for (int i = 0; i < 3 && count < max; i++) {
k_strcpy(entries[count].name, meta_files[i]);
strcpy(entries[count].name, meta_files[i]);
entries[count].size = 0;
entries[count].is_directory = 0;
count++;
@ -367,7 +367,7 @@ static bool bootfs_rmdir(void *fs_private, const char *rel_path) {
if (!rel_path) rel_path = "";
if (rel_path[0] == '/') rel_path++;
if (k_strcmp(rel_path, "metadata") == 0) {
if (strcmp(rel_path, "metadata") == 0) {
return false; /* metadata directory is protected */
}
@ -379,7 +379,7 @@ static bool bootfs_unlink(void *fs_private, const char *rel_path) {
if (rel_path[0] == '/') rel_path++;
/* Only limine.conf can be deleted */
if (k_strcmp(rel_path, "limine.conf") != 0) {
if (strcmp(rel_path, "limine.conf") != 0) {
return false;
}
@ -411,24 +411,24 @@ static bool bootfs_rename(void *fs_private, const char *old_path, const char *ne
if (new_rel[0] == '/') new_rel++;
/* Only limine.conf can be renamed */
if (k_strcmp(old_rel, "limine.conf") != 0) {
if (strcmp(old_rel, "limine.conf") != 0) {
return false;
}
/* kernel and initrd are protected */
if (k_strcmp(new_rel, "kernel") == 0 || k_strcmp(new_rel, "initrd") == 0) {
if (strcmp(new_rel, "kernel") == 0 || strcmp(new_rel, "initrd") == 0) {
return false;
}
/* metadata directory is protected */
if (k_strncmp(new_rel, "metadata", 8) == 0) {
if (strncmp(new_rel, "metadata", 8) == 0) {
return false;
}
extern bool vfs_rename(const char *old_path, const char *new_path);
char new_partition_path[256];
k_strcpy(new_partition_path, "/");
strcpy(new_partition_path, "/");
/* Manually append new_rel to new_partition_path */
int path_len = 0;
@ -442,7 +442,7 @@ static bool bootfs_rename(void *fs_private, const char *old_path, const char *ne
return false;
}
k_memcpy(new_partition_path + path_len, new_rel, rel_len + 1);
memcpy(new_partition_path + path_len, new_rel, rel_len + 1);
/* Rename on partition filesystem */
bool result = vfs_rename("/limine.conf", new_partition_path);
@ -466,13 +466,13 @@ static bool bootfs_exists(void *fs_private, const char *rel_path) {
if (rel_path[0] == '\0') return true;
if (k_strcmp(rel_path, "limine.conf") == 0) return true;
if (k_strcmp(rel_path, "efi") == 0) return true;
if (k_strcmp(rel_path, "kernel") == 0) return true;
if (k_strcmp(rel_path, "initrd") == 0) return true;
if (k_strcmp(rel_path, "initrd.tar") == 0) return true;
if (strcmp(rel_path, "limine.conf") == 0) return true;
if (strcmp(rel_path, "efi") == 0) return true;
if (strcmp(rel_path, "kernel") == 0) return true;
if (strcmp(rel_path, "initrd") == 0) return true;
if (strcmp(rel_path, "initrd.tar") == 0) return true;
if (k_strcmp(rel_path, "metadata") == 0) return true;
if (strcmp(rel_path, "metadata") == 0) return true;
if (is_metadata_file(rel_path)) return true;
if (bootfs_find_custom(rel_path)) return true;
@ -484,8 +484,8 @@ static bool bootfs_is_dir(void *fs_private, const char *rel_path) {
if (rel_path[0] == '/') rel_path++;
if (rel_path[0] == '\0') return true;
if (k_strcmp(rel_path, "efi") == 0) return true;
if (k_strcmp(rel_path, "metadata") == 0) return true;
if (strcmp(rel_path, "efi") == 0) return true;
if (strcmp(rel_path, "metadata") == 0) return true;
return false;
}
@ -495,42 +495,42 @@ static int bootfs_get_info(void *fs_private, const char *rel_path, vfs_dirent_t
if (!rel_path) rel_path = "";
if (rel_path[0] == '/') rel_path++;
k_memset(info, 0, sizeof(vfs_dirent_t));
memset(info, 0, sizeof(vfs_dirent_t));
if (rel_path[0] == '\0') {
k_strcpy(info->name, "/");
strcpy(info->name, "/");
info->is_directory = 1;
return 0;
}
if (k_strcmp(rel_path, "limine.conf") == 0) {
k_strcpy(info->name, "limine.conf");
if (strcmp(rel_path, "limine.conf") == 0) {
strcpy(info->name, "limine.conf");
info->size = g_bootfs_state.limine_conf_len;
info->is_directory = 0;
return 0;
}
if (k_strcmp(rel_path, "kernel") == 0) {
k_strcpy(info->name, "kernel");
if (strcmp(rel_path, "kernel") == 0) {
strcpy(info->name, "kernel");
info->size = g_bootfs_state.kernel_size;
info->is_directory = 0;
return 0;
} else if (k_strcmp(rel_path, "initrd") == 0) {
k_strcpy(info->name, "initrd");
} else if (strcmp(rel_path, "initrd") == 0) {
strcpy(info->name, "initrd");
info->size = g_bootfs_state.initrd_size;
info->is_directory = 0;
return 0;
} else if (k_strcmp(rel_path, "initrd.tar") == 0) {
k_strcpy(info->name, "initrd.tar");
} else if (strcmp(rel_path, "initrd.tar") == 0) {
strcpy(info->name, "initrd.tar");
info->size = g_bootfs_state.initrd_size;
info->is_directory = 0;
return 0;
} else if (k_strcmp(rel_path, "metadata") == 0) {
k_strcpy(info->name, "metadata");
} else if (strcmp(rel_path, "metadata") == 0) {
strcpy(info->name, "metadata");
info->is_directory = 1;
return 0;
} else if (k_strcmp(rel_path, "efi") == 0) {
k_strcpy(info->name, "efi");
} else if (strcmp(rel_path, "efi") == 0) {
strcpy(info->name, "efi");
info->is_directory = 1;
return 0;
}
@ -538,7 +538,7 @@ static int bootfs_get_info(void *fs_private, const char *rel_path, vfs_dirent_t
if (is_metadata_file(rel_path)) {
char temp_buf[4096];
int len = generate_metadata_content(rel_path, temp_buf, 4096);
k_strcpy(info->name, rel_path + 9);
strcpy(info->name, rel_path + 9);
info->size = len;
info->is_directory = 0;
return 0;
@ -546,7 +546,7 @@ static int bootfs_get_info(void *fs_private, const char *rel_path, vfs_dirent_t
bootfs_custom_file_t *cf = bootfs_find_custom(rel_path);
if (cf) {
k_strcpy(info->name, cf->name);
strcpy(info->name, cf->name);
info->size = cf->size;
info->is_directory = 0;
return 0;
@ -565,13 +565,13 @@ static uint32_t bootfs_get_size(void *file_handle) {
bootfs_handle_t *h = (bootfs_handle_t*)file_handle;
if (!h) return 0;
if (k_strcmp(h->path, "limine.conf") == 0) {
if (strcmp(h->path, "limine.conf") == 0) {
return g_bootfs_state.limine_conf_len;
} else if (k_strcmp(h->path, "kernel") == 0) {
} else if (strcmp(h->path, "kernel") == 0) {
return g_bootfs_state.kernel_size;
} else if (k_strcmp(h->path, "initrd") == 0) {
} else if (strcmp(h->path, "initrd") == 0) {
return g_bootfs_state.initrd_size;
} else if (k_strcmp(h->path, "initrd.tar") == 0) {
} else if (strcmp(h->path, "initrd.tar") == 0) {
return g_bootfs_state.initrd_size;
} else if (is_metadata_file(h->path)) {
char temp_buf[4096];
@ -589,10 +589,10 @@ vfs_fs_ops_t* bootfs_get_ops(void) {
}
void bootfs_state_init(void) {
k_memset(&g_bootfs_state, 0, sizeof(bootfs_state_t));
memset(&g_bootfs_state, 0, sizeof(bootfs_state_t));
k_strcpy(g_bootfs_state.bootloader_name, "Limine");
k_strcpy(g_bootfs_state.bootloader_version, "6.0.0");
strcpy(g_bootfs_state.bootloader_name, "Limine");
strcpy(g_bootfs_state.bootloader_version, "6.0.0");
g_bootfs_state.limine_conf[0] = '\0';
@ -637,11 +637,11 @@ void bootfs_refresh_from_disk(void) {
vfs_file_t *boot_conf = vfs_open("/boot/efi/limine.conf", "r");
if (boot_conf) {
k_strcpy(g_limine_conf_path, "/boot/efi/limine.conf");
strcpy(g_limine_conf_path, "/boot/efi/limine.conf");
} else {
boot_conf = vfs_open("/limine.conf", "r");
if (boot_conf) {
k_strcpy(g_limine_conf_path, "/limine.conf");
strcpy(g_limine_conf_path, "/limine.conf");
}
}

View file

@ -17,7 +17,7 @@ void* procfs_open(void *fs_private, const char *path, const char *mode) {
if (path[0] == '/') path++;
procfs_handle_t *h = (procfs_handle_t*)kmalloc(sizeof(procfs_handle_t));
k_memset(h, 0, sizeof(procfs_handle_t));
memset(h, 0, sizeof(procfs_handle_t));
h->offset = 0;
if (path[0] == '\0') {
@ -33,10 +33,10 @@ void* procfs_open(void *fs_private, const char *path, const char *mode) {
i++;
}
pid_str[i] = 0;
h->pid = k_atoi(pid_str);
h->pid = atoi(pid_str);
if (path[i] == '/') {
k_strcpy(h->type, path + i + 1);
strcpy(h->type, path + i + 1);
} else {
h->type[0] = 0;
}
@ -44,7 +44,7 @@ void* procfs_open(void *fs_private, const char *path, const char *mode) {
}
h->pid = 0xFFFFFFFF;
k_strcpy(h->type, path);
strcpy(h->type, path);
return h;
}
@ -61,33 +61,33 @@ int procfs_read(void *fs_private, void *handle, void *buf, int size) {
out[0] = 0;
if (h->pid == 0xFFFFFFFF) {
if (k_strcmp(h->type, "version") == 0) {
if (strcmp(h->type, "version") == 0) {
extern void get_os_info(os_info_t *info);
os_info_t info;
get_os_info(&info);
k_strcpy(out, info.os_name);
k_strcpy(out + k_strlen(out), " [");
k_strcpy(out + k_strlen(out), info.os_codename);
k_strcpy(out + k_strlen(out), "] Version ");
k_strcpy(out + k_strlen(out), info.os_version);
k_strcpy(out + k_strlen(out), "\nKernel: ");
k_strcpy(out + k_strlen(out), info.kernel_name);
k_strcpy(out + k_strlen(out), " ");
k_strcpy(out + k_strlen(out), info.kernel_version);
k_strcpy(out + k_strlen(out), "\nBuild: ");
k_strcpy(out + k_strlen(out), info.build_date);
k_strcpy(out + k_strlen(out), " ");
k_strcpy(out + k_strlen(out), info.build_time);
k_strcpy(out + k_strlen(out), "\n");
} else if (k_strcmp(h->type, "uptime") == 0) {
strcpy(out, info.os_name);
strcpy(out + strlen(out), " [");
strcpy(out + strlen(out), info.os_codename);
strcpy(out + strlen(out), "] Version ");
strcpy(out + strlen(out), info.os_version);
strcpy(out + strlen(out), "\nKernel: ");
strcpy(out + strlen(out), info.kernel_name);
strcpy(out + strlen(out), " ");
strcpy(out + strlen(out), info.kernel_version);
strcpy(out + strlen(out), "\nBuild: ");
strcpy(out + strlen(out), info.build_date);
strcpy(out + strlen(out), " ");
strcpy(out + strlen(out), info.build_time);
strcpy(out + strlen(out), "\n");
} else if (strcmp(h->type, "uptime") == 0) {
extern uint32_t wm_get_ticks(void);
uint32_t ticks = wm_get_ticks();
k_itoa(ticks / 60, out);
k_strcpy(out + k_strlen(out), " seconds\nRaw_Ticks:");
char t_s[16]; k_itoa(ticks, t_s);
k_strcpy(out + k_strlen(out), t_s);
k_strcpy(out + k_strlen(out), "\n");
} else if (k_strcmp(h->type, "cpuinfo") == 0) {
itoa(ticks / 60, out);
strcpy(out + strlen(out), " seconds\nRaw_Ticks:");
char t_s[16]; itoa(ticks, t_s);
strcpy(out + strlen(out), t_s);
strcpy(out + strlen(out), "\n");
} else if (strcmp(h->type, "cpuinfo") == 0) {
extern uint32_t smp_cpu_count(void);
extern void platform_get_cpu_model(char *model);
extern void platform_get_cpu_vendor(char *vendor);
@ -111,35 +111,35 @@ int procfs_read(void *fs_private, void *handle, void *buf, int size) {
for (uint32_t i = 0; i < cpu_count; i++) {
char buf[32];
k_strcpy(out + k_strlen(out), "processor\t: ");
k_itoa(i, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "processor\t: ");
itoa(i, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "vendor_id\t: ");
k_strcpy(out + k_strlen(out), vendor);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "vendor_id\t: ");
strcpy(out + strlen(out), vendor);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cpu family\t: ");
k_itoa(info.family, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "cpu family\t: ");
itoa(info.family, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "model\t\t: ");
k_itoa(info.model, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "model\t\t: ");
itoa(info.model, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "model name\t: ");
k_strcpy(out + k_strlen(out), model);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "model name\t: ");
strcpy(out + strlen(out), model);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "stepping\t: ");
k_itoa(info.stepping, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "stepping\t: ");
itoa(info.stepping, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "microcode\t: 0x");
strcpy(out + strlen(out), "microcode\t: 0x");
char hex[16];
int temp = info.microcode;
int hex_pos = 0;
@ -148,217 +148,217 @@ int procfs_read(void *fs_private, void *handle, void *buf, int size) {
hex[hex_pos++] = digit < 10 ? '0' + digit : 'a' + (digit - 10);
}
hex[hex_pos] = '\0';
k_strcpy(out + k_strlen(out), hex);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), hex);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cache size\t: ");
k_itoa(info.cache_size, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), " KB\n");
strcpy(out + strlen(out), "cache size\t: ");
itoa(info.cache_size, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), " KB\n");
k_strcpy(out + k_strlen(out), "physical id\t: 0\n");
k_strcpy(out + k_strlen(out), "siblings\t: ");
k_itoa(cpu_count, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "physical id\t: 0\n");
strcpy(out + strlen(out), "siblings\t: ");
itoa(cpu_count, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "core id\t\t: ");
k_itoa(i, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "core id\t\t: ");
itoa(i, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cpu cores\t: ");
k_itoa(cpu_count, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "cpu cores\t: ");
itoa(cpu_count, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "apicid\t\t: ");
k_itoa(i, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "apicid\t\t: ");
itoa(i, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "initial apicid\t: ");
k_itoa(i, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "initial apicid\t: ");
itoa(i, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "fpu\t\t: yes\n");
k_strcpy(out + k_strlen(out), "fpu_exception\t: yes\n");
strcpy(out + strlen(out), "fpu\t\t: yes\n");
strcpy(out + strlen(out), "fpu_exception\t: yes\n");
k_strcpy(out + k_strlen(out), "cpuid level\t: 13\n");
strcpy(out + strlen(out), "cpuid level\t: 13\n");
k_strcpy(out + k_strlen(out), "wp\t\t: yes\n");
strcpy(out + strlen(out), "wp\t\t: yes\n");
k_strcpy(out + k_strlen(out), "flags\t\t: ");
k_strcpy(out + k_strlen(out), flags);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "flags\t\t: ");
strcpy(out + strlen(out), flags);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "bugs\t\t: \n");
k_strcpy(out + k_strlen(out), "bogomips\t: 4800.00\n");
strcpy(out + strlen(out), "bugs\t\t: \n");
strcpy(out + strlen(out), "bogomips\t: 4800.00\n");
if (i < cpu_count - 1) {
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "\n");
}
}
} else if (k_strcmp(h->type, "datetime") == 0) {
} else if (strcmp(h->type, "datetime") == 0) {
extern void rtc_get_datetime(int *year, int *month, int *day, int *hour, int *minute, int *second);
int y, m, d, h_val, min, s;
rtc_get_datetime(&y, &m, &d, &h_val, &min, &s);
char buf[16];
k_itoa(y, buf);
k_strcpy(out, buf);
k_strcpy(out + k_strlen(out), "-");
if (m < 10) k_strcpy(out + k_strlen(out), "0");
k_itoa(m, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "-");
if (d < 10) k_strcpy(out + k_strlen(out), "0");
k_itoa(d, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), " ");
if (h_val < 10) k_strcpy(out + k_strlen(out), "0");
k_itoa(h_val, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), ":");
if (min < 10) k_strcpy(out + k_strlen(out), "0");
k_itoa(min, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), ":");
if (s < 10) k_strcpy(out + k_strlen(out), "0");
k_itoa(s, buf);
k_strcpy(out + k_strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n");
} else if (k_strcmp(h->type, "meminfo") == 0) {
itoa(y, buf);
strcpy(out, buf);
strcpy(out + strlen(out), "-");
if (m < 10) strcpy(out + strlen(out), "0");
itoa(m, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "-");
if (d < 10) strcpy(out + strlen(out), "0");
itoa(d, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), " ");
if (h_val < 10) strcpy(out + strlen(out), "0");
itoa(h_val, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), ":");
if (min < 10) strcpy(out + strlen(out), "0");
itoa(min, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), ":");
if (s < 10) strcpy(out + strlen(out), "0");
itoa(s, buf);
strcpy(out + strlen(out), buf);
strcpy(out + strlen(out), "\n");
} else if (strcmp(h->type, "meminfo") == 0) {
extern MemStats memory_get_stats(void);
MemStats stats = memory_get_stats();
char m_s[32];
k_strcpy(out, "MemTotal:\t");
k_itoa(stats.total_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n");
strcpy(out, "MemTotal:\t");
itoa(stats.total_memory / 1024, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "MemFree:\t");
k_itoa(stats.available_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n");
strcpy(out + strlen(out), "MemFree:\t");
itoa(stats.available_memory / 1024, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "MemAvailable:\t");
k_itoa(stats.available_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n");
strcpy(out + strlen(out), "MemAvailable:\t");
itoa(stats.available_memory / 1024, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "Buffers:\t0 kB\n");
k_strcpy(out + k_strlen(out), "Cached:\t\t0 kB\n");
strcpy(out + strlen(out), "Buffers:\t0 kB\n");
strcpy(out + strlen(out), "Cached:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "MemUsed:\t");
k_itoa(stats.used_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n");
strcpy(out + strlen(out), "MemUsed:\t");
itoa(stats.used_memory / 1024, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "MemPeak:\t");
k_itoa(stats.peak_memory_used / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n");
strcpy(out + strlen(out), "MemPeak:\t");
itoa(stats.peak_memory_used / 1024, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "SwapTotal:\t0 kB\n");
k_strcpy(out + k_strlen(out), "SwapFree:\t0 kB\n");
strcpy(out + strlen(out), "SwapTotal:\t0 kB\n");
strcpy(out + strlen(out), "SwapFree:\t0 kB\n");
k_strcpy(out + k_strlen(out), "Dirty:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "Writeback:\t0 kB\n");
k_strcpy(out + k_strlen(out), "AnonPages:\t");
k_itoa(stats.used_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n");
strcpy(out + strlen(out), "Dirty:\t\t0 kB\n");
strcpy(out + strlen(out), "Writeback:\t0 kB\n");
strcpy(out + strlen(out), "AnonPages:\t");
itoa(stats.used_memory / 1024, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "Mapped:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "Shmem:\t\t0 kB\n");
strcpy(out + strlen(out), "Mapped:\t\t0 kB\n");
strcpy(out + strlen(out), "Shmem:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "Blocks:\t\t");
k_itoa(stats.allocated_blocks, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "Blocks:\t\t");
itoa(stats.allocated_blocks, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "FreeBlocks:\t");
k_itoa(stats.free_blocks, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "FreeBlocks:\t");
itoa(stats.free_blocks, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "Fragmentation:\t");
k_itoa(stats.fragmentation_percent, m_s);
k_strcpy(out + k_strlen(out), m_s);
k_strcpy(out + k_strlen(out), "%\n");
} else if (k_strcmp(h->type, "devices") == 0) {
strcpy(out + strlen(out), "Fragmentation:\t");
itoa(stats.fragmentation_percent, m_s);
strcpy(out + strlen(out), m_s);
strcpy(out + strlen(out), "%\n");
} else if (strcmp(h->type, "devices") == 0) {
extern int disk_get_count(void);
extern Disk* disk_get_by_index(int index);
int dcount = disk_get_count();
out[0] = '\0';
k_strcpy(out, "Character devices:\n");
k_strcpy(out + k_strlen(out), " 1 mem\n");
k_strcpy(out + k_strlen(out), " 4 tty\n");
k_strcpy(out + k_strlen(out), " 5 cua\n");
k_strcpy(out + k_strlen(out), " 7 vcs\n");
k_strcpy(out + k_strlen(out), " 8 stdin\n");
k_strcpy(out + k_strlen(out), " 13 input\n");
k_strcpy(out + k_strlen(out), " 14 sound\n");
k_strcpy(out + k_strlen(out), " 29 fb\n");
k_strcpy(out + k_strlen(out), "189 usb\n\n");
strcpy(out, "Character devices:\n");
strcpy(out + strlen(out), " 1 mem\n");
strcpy(out + strlen(out), " 4 tty\n");
strcpy(out + strlen(out), " 5 cua\n");
strcpy(out + strlen(out), " 7 vcs\n");
strcpy(out + strlen(out), " 8 stdin\n");
strcpy(out + strlen(out), " 13 input\n");
strcpy(out + strlen(out), " 14 sound\n");
strcpy(out + strlen(out), " 29 fb\n");
strcpy(out + strlen(out), "189 usb\n\n");
k_strcpy(out + k_strlen(out), "Block devices:\n");
strcpy(out + strlen(out), "Block devices:\n");
for (int i = 0; i < dcount; i++) {
Disk *d = disk_get_by_index(i);
if (d && !d->is_partition) {
k_strcpy(out + k_strlen(out), " 8 ");
k_strcpy(out + k_strlen(out), d->devname);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), " 8 ");
strcpy(out + strlen(out), d->devname);
strcpy(out + strlen(out), "\n");
}
}
k_strcpy(out + k_strlen(out), " 11 sr\n");
k_strcpy(out + k_strlen(out), "253 virtblk\n");
strcpy(out + strlen(out), " 11 sr\n");
strcpy(out + strlen(out), "253 virtblk\n");
}
}
else {
process_t *proc = process_get_by_pid(h->pid);
if (!proc) { kfree(out); return -1; }
if (k_strcmp(h->type, "name") == 0 || k_strcmp(h->type, "cmdline") == 0) {
k_strcpy(out, proc->name);
k_strcpy(out + k_strlen(out), "\n");
} else if (k_strcmp(h->type, "cwd") == 0) {
k_strcpy(out, proc->cwd);
k_strcpy(out + k_strlen(out), "\n");
} else if (k_strcmp(h->type, "status") == 0) {
k_strcpy(out, "Name: ");
k_strcpy(out + k_strlen(out), proc->name);
k_strcpy(out + k_strlen(out), "\nPID: ");
char pid_s[16]; k_itoa(proc->pid, pid_s);
k_strcpy(out + k_strlen(out), pid_s);
k_strcpy(out + k_strlen(out), "\nState: RUNNING\nMemory: ");
if (strcmp(h->type, "name") == 0 || strcmp(h->type, "cmdline") == 0) {
strcpy(out, proc->name);
strcpy(out + strlen(out), "\n");
} else if (strcmp(h->type, "cwd") == 0) {
strcpy(out, proc->cwd);
strcpy(out + strlen(out), "\n");
} else if (strcmp(h->type, "status") == 0) {
strcpy(out, "Name: ");
strcpy(out + strlen(out), proc->name);
strcpy(out + strlen(out), "\nPID: ");
char pid_s[16]; itoa(proc->pid, pid_s);
strcpy(out + strlen(out), pid_s);
strcpy(out + strlen(out), "\nState: RUNNING\nMemory: ");
uint64_t mem_val = proc->used_memory;
if (h->pid == 0) {
extern MemStats memory_get_stats(void);
mem_val = memory_get_stats().used_memory;
}
char mem_s[32]; k_itoa(mem_val / 1024, mem_s);
k_strcpy(out + k_strlen(out), mem_s);
k_strcpy(out + k_strlen(out), " KB\nTicks: ");
char tick_s[32]; k_itoa(proc->ticks, tick_s);
k_strcpy(out + k_strlen(out), tick_s);
k_strcpy(out + k_strlen(out), "\nIdle: ");
k_strcpy(out + k_strlen(out), proc->is_idle ? "1" : "0");
k_strcpy(out + k_strlen(out), "\n");
char mem_s[32]; itoa(mem_val / 1024, mem_s);
strcpy(out + strlen(out), mem_s);
strcpy(out + strlen(out), " KB\nTicks: ");
char tick_s[32]; itoa(proc->ticks, tick_s);
strcpy(out + strlen(out), tick_s);
strcpy(out + strlen(out), "\nIdle: ");
strcpy(out + strlen(out), proc->is_idle ? "1" : "0");
strcpy(out + strlen(out), "\n");
}
}
int len = k_strlen(out);
int len = strlen(out);
if (h->offset >= len) { kfree(out); return 0; }
int to_copy = len - h->offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + h->offset, to_copy);
memcpy(buf, out + h->offset, to_copy);
h->offset += to_copy;
kfree(out);
return to_copy;
@ -368,13 +368,13 @@ int procfs_write(void *fs_private, void *handle, const void *buf, int size) {
procfs_handle_t *h = (procfs_handle_t*)handle;
if (!h || h->pid == 0xFFFFFFFF) return -1;
if (k_strcmp(h->type, "signal") == 0) {
if (strcmp(h->type, "signal") == 0) {
char cmd[16];
int to_copy = size < 15 ? size : 15;
k_memcpy(cmd, buf, to_copy);
memcpy(cmd, buf, to_copy);
cmd[to_copy] = 0;
if (k_strcmp(cmd, "9") == 0 || k_strcmp(cmd, "kill") == 0) {
if (strcmp(cmd, "9") == 0 || strcmp(cmd, "kill") == 0) {
process_t *proc = process_get_by_pid(h->pid);
if (proc && proc->pid != 0) {
process_terminate(proc);
@ -391,23 +391,23 @@ int procfs_readdir(void *fs_private, const char *path, vfs_dirent_t *entries, in
if (path[0] == '\0') {
int out = 0;
k_strcpy(entries[out++].name, "version");
strcpy(entries[out++].name, "version");
entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "uptime");
strcpy(entries[out++].name, "uptime");
entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "cpuinfo");
strcpy(entries[out++].name, "cpuinfo");
entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "meminfo");
strcpy(entries[out++].name, "meminfo");
entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "datetime");
strcpy(entries[out++].name, "datetime");
entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "devices");
strcpy(entries[out++].name, "devices");
entries[out-1].is_directory = 0;
extern process_t processes[];
for (int i = 0; i < 16 && out < max; i++) {
if (processes[i].pid != 0xFFFFFFFF) {
k_itoa(processes[i].pid, entries[out].name);
itoa(processes[i].pid, entries[out].name);
entries[out].is_directory = 1;
entries[out].size = 0;
out++;
@ -418,11 +418,11 @@ int procfs_readdir(void *fs_private, const char *path, vfs_dirent_t *entries, in
if (path[0] >= '0' && path[0] <= '9') {
int out = 0;
k_strcpy(entries[out++].name, "name");
k_strcpy(entries[out++].name, "status");
k_strcpy(entries[out++].name, "cmdline");
k_strcpy(entries[out++].name, "cwd");
k_strcpy(entries[out++].name, "signal");
strcpy(entries[out++].name, "name");
strcpy(entries[out++].name, "status");
strcpy(entries[out++].name, "cmdline");
strcpy(entries[out++].name, "cwd");
strcpy(entries[out++].name, "signal");
for(int i=0; i<out; i++) entries[i].is_directory = 0;
return out;
}
@ -442,13 +442,13 @@ bool procfs_exists(void *fs_private, const char *path) {
i++;
}
pid_str[i] = 0;
uint32_t pid = k_atoi(pid_str);
uint32_t pid = atoi(pid_str);
if (process_get_by_pid(pid)) return true;
}
if (k_strcmp(path, "version") == 0 || k_strcmp(path, "uptime") == 0) return true;
if (k_strcmp(path, "cpuinfo") == 0 || k_strcmp(path, "meminfo") == 0) return true;
if (k_strcmp(path, "datetime") == 0 || k_strcmp(path, "devices") == 0) return true;
if (strcmp(path, "version") == 0 || strcmp(path, "uptime") == 0) return true;
if (strcmp(path, "cpuinfo") == 0 || strcmp(path, "meminfo") == 0) return true;
if (strcmp(path, "datetime") == 0 || strcmp(path, "devices") == 0) return true;
return false;
}

View file

@ -19,14 +19,14 @@ static void* sysfs_open(void *fs_private, const char *path, const char *mode) {
if (last_slash != -1) {
char prefix[64];
k_memcpy(prefix, path, last_slash);
memcpy(prefix, path, last_slash);
prefix[last_slash] = 0;
sub = subsystem_get_by_name(prefix);
if (sub) {
const char *filename = path + last_slash + 1;
for (int j = 0; j < sub->file_count; j++) {
if (k_strcmp(sub->files[j].name, filename) == 0) {
if (strcmp(sub->files[j].name, filename) == 0) {
sysfs_handle_t *h = (sysfs_handle_t*)kmalloc(sizeof(sysfs_handle_t));
h->sub = sub;
h->file = &sub->files[j];
@ -70,7 +70,7 @@ static int sysfs_readdir(void *fs_private, const char *path, vfs_dirent_t *entri
if (exact_sub) {
for (int i = 0; i < exact_sub->file_count && out < max; i++) {
k_strcpy(entries[out].name, exact_sub->files[i].name);
strcpy(entries[out].name, exact_sub->files[i].name);
entries[out].is_directory = 0;
entries[out].size = 0;
out++;
@ -78,11 +78,11 @@ static int sysfs_readdir(void *fs_private, const char *path, vfs_dirent_t *entri
}
int count = subsystem_get_count();
int path_len = k_strlen(path);
int path_len = strlen(path);
for (int i = 0; i < count && out < max; i++) {
kernel_subsystem_t *s = subsystem_get_by_index(i);
if (path_len == 0 || (k_strlen(s->name) > path_len && k_strncmp(s->name, path, path_len) == 0 && s->name[path_len] == '/')) {
if (path_len == 0 || (strlen(s->name) > path_len && strncmp(s->name, path, path_len) == 0 && s->name[path_len] == '/')) {
const char *sub_path = s->name + (path_len ? path_len + 1 : 0);
char comp[64];
int j = 0;
@ -96,13 +96,13 @@ static int sysfs_readdir(void *fs_private, const char *path, vfs_dirent_t *entri
bool found = false;
for (int k = 0; k < out; k++) {
if (k_strcmp(entries[k].name, comp) == 0) {
if (strcmp(entries[k].name, comp) == 0) {
found = true;
break;
}
}
if (!found) {
k_strcpy(entries[out].name, comp);
strcpy(entries[out].name, comp);
entries[out].is_directory = 1;
entries[out].size = 0;
out++;
@ -123,22 +123,22 @@ static bool sysfs_exists(void *fs_private, const char *path) {
for (int j = 0; path[j]; j++) if (path[j] == '/') last_slash = j;
if (last_slash != -1) {
char prefix[64];
k_memcpy(prefix, path, last_slash);
memcpy(prefix, path, last_slash);
prefix[last_slash] = 0;
kernel_subsystem_t *sub = subsystem_get_by_name(prefix);
if (sub) {
const char *filename = path + last_slash + 1;
for (int j = 0; j < sub->file_count; j++) {
if (k_strcmp(sub->files[j].name, filename) == 0) return true;
if (strcmp(sub->files[j].name, filename) == 0) return true;
}
}
}
int count = subsystem_get_count();
int path_len = k_strlen(path);
int path_len = strlen(path);
for (int i = 0; i < count; i++) {
kernel_subsystem_t *s = subsystem_get_by_index(i);
if (k_strlen(s->name) > path_len && k_strncmp(s->name, path, path_len) == 0 && s->name[path_len] == '/') return true;
if (strlen(s->name) > path_len && strncmp(s->name, path, path_len) == 0 && s->name[path_len] == '/') return true;
}
return false;
@ -152,13 +152,13 @@ static bool sysfs_is_dir(void *fs_private, const char *path) {
for (int j = 0; path[j]; j++) if (path[j] == '/') last_slash = j;
if (last_slash != -1) {
char prefix[64];
k_memcpy(prefix, path, last_slash);
memcpy(prefix, path, last_slash);
prefix[last_slash] = 0;
kernel_subsystem_t *sub = subsystem_get_by_name(prefix);
if (sub) {
const char *filename = path + last_slash + 1;
for (int j = 0; j < sub->file_count; j++) {
if (k_strcmp(sub->files[j].name, filename) == 0) return false;
if (strcmp(sub->files[j].name, filename) == 0) return false;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 776 KiB

View file

@ -353,11 +353,11 @@ static void *slab_alloc(int cls) {
// Freelist head must be a kernel higher-half address. Treat anything below the conservative
// threshold 0xFFFF000000000000 as corruption (canonical boundary is 0xFFFF800000000000).
if ((uintptr_t)obj < 0xFFFF000000000000ULL) {
char b[17]; extern void k_itoa_hex(uint64_t, char *);
char b[17]; extern void itoa_hex(uint64_t, char *);
serial_write("[SLAB] corrupt freelist cls=");
k_itoa_hex((uint64_t)cls, b); serial_write(b);
serial_write(" page="); k_itoa_hex((uint64_t)page, b); serial_write(b);
serial_write(" fl="); k_itoa_hex((uint64_t)obj, b); serial_write(b);
itoa_hex((uint64_t)cls, b); serial_write(b);
serial_write(" page="); itoa_hex((uint64_t)page, b); serial_write(b);
serial_write(" fl="); itoa_hex((uint64_t)obj, b); serial_write(b);
serial_write("\n");
// Remove the corrupted page from the list to avoid hitting it again

View file

@ -58,7 +58,7 @@ static void mem_write32(int addr, int val) {
static void vm_reset(void) {
sp = 0;
k_memset(memory, 0, VM_MEMORY_SIZE);
memset(memory, 0, VM_MEMORY_SIZE);
vm_heap_ptr = 8192;
}
@ -167,7 +167,7 @@ static void vm_syscall(int id) {
case VM_SYS_STRLEN: {
int addr = pop();
if (addr >= 0 && addr < VM_MEMORY_SIZE) {
push(k_strlen((char*)&memory[addr]));
push(strlen((char*)&memory[addr]));
} else push(0);
break;
}
@ -175,7 +175,7 @@ static void vm_syscall(int id) {
int a2 = pop();
int a1 = pop();
if (a1 >= 0 && a1 < VM_MEMORY_SIZE && a2 >= 0 && a2 < VM_MEMORY_SIZE) {
push(k_strcmp((char*)&memory[a1], (char*)&memory[a2]));
push(strcmp((char*)&memory[a1], (char*)&memory[a2]));
} else push(0);
break;
}
@ -183,7 +183,7 @@ static void vm_syscall(int id) {
int src = pop();
int dest = pop();
if (dest >= 0 && dest < VM_MEMORY_SIZE && src >= 0 && src < VM_MEMORY_SIZE) {
k_strcpy((char*)&memory[dest], (char*)&memory[src]);
strcpy((char*)&memory[dest], (char*)&memory[src]);
push(dest);
} else push(0);
break;
@ -198,7 +198,7 @@ static void vm_syscall(int id) {
int val = pop();
int ptr = pop();
if (ptr >= 0 && ptr + n <= VM_MEMORY_SIZE) {
k_memset(&memory[ptr], val, n);
memset(&memory[ptr], val, n);
push(ptr);
} else push(0);
break;
@ -322,7 +322,7 @@ static void vm_syscall(int id) {
case VM_SYS_ATOI: {
int addr = pop();
if (addr >= 0 && addr < VM_MEMORY_SIZE) {
push(k_atoi((char*)&memory[addr]));
push(atoi((char*)&memory[addr]));
} else push(0);
break;
}
@ -330,7 +330,7 @@ static void vm_syscall(int id) {
int addr = pop();
int val = pop();
if (addr >= 0 && addr < VM_MEMORY_SIZE) {
k_itoa(val, (char*)&memory[addr]);
itoa(val, (char*)&memory[addr]);
}
push(0);
break;
@ -503,7 +503,7 @@ int vm_exec(const uint8_t *code, int code_size) {
}
// Load program into memory at address 0
k_memset(memory, 0, VM_MEMORY_SIZE);
memset(memory, 0, VM_MEMORY_SIZE);
for(int i=0; i<code_size; i++) memory[i] = code[i];
int pc = 8; // Skip header

View file

@ -92,10 +92,10 @@ int network_init(void) {
extern void serial_write(const char *str);
serial_write("[NET] IP Assigned: ");
char buf[32];
k_itoa(ip.bytes[0], buf); serial_write(buf); serial_write(".");
k_itoa(ip.bytes[1], buf); serial_write(buf); serial_write(".");
k_itoa(ip.bytes[2], buf); serial_write(buf); serial_write(".");
k_itoa(ip.bytes[3], buf); serial_write(buf); serial_write("\n");
itoa(ip.bytes[0], buf); serial_write(buf); serial_write(".");
itoa(ip.bytes[1], buf); serial_write(buf); serial_write(".");
itoa(ip.bytes[2], buf); serial_write(buf); serial_write(".");
itoa(ip.bytes[3], buf); serial_write(buf); serial_write("\n");
} else {
extern void serial_write(const char *str);
serial_write("[NET] DHCP Failed during init\n");

View file

@ -37,13 +37,13 @@ int e1000_init(pci_device_t* pci_dev) {
extern void serial_write(const char *str);
serial_write("[E1000] MMIO Base (virt): 0x");
char hex_buf[32];
k_itoa_hex((uint64_t)mmio_base, hex_buf);
itoa_hex((uint64_t)mmio_base, hex_buf);
serial_write(hex_buf);
serial_write("\n");
uint32_t status_reg = e1000_read_reg(mmio_base, E1000_REG_STATUS);
serial_write("[E1000] Status: 0x");
k_itoa_hex(status_reg, hex_buf);
itoa_hex(status_reg, hex_buf);
serial_write(hex_buf);
serial_write("\n");
@ -69,7 +69,7 @@ int e1000_init(pci_device_t* pci_dev) {
serial_write("[E1000] MAC: ");
for(int i=0; i<6; i++) {
char buf[4];
k_itoa_hex(e1000_dev.mac_address.bytes[i], buf);
itoa_hex(e1000_dev.mac_address.bytes[i], buf);
serial_write(buf);
if(i<5) serial_write(":");
}
@ -81,8 +81,8 @@ int e1000_init(pci_device_t* pci_dev) {
e1000_dev.tx_descriptors = tx_descriptors;
e1000_dev.tx_head = 0;
e1000_dev.tx_tail = 0;
k_memset(tx_descriptors, 0, sizeof(tx_descriptors));
k_memset(tx_buffers, 0, sizeof(tx_buffers));
memset(tx_descriptors, 0, sizeof(tx_descriptors));
memset(tx_buffers, 0, sizeof(tx_buffers));
for (int i = 0; i < E1000_TX_RING_SIZE; i++) {
e1000_dev.tx_buffers[i] = tx_buffers[i];
@ -102,8 +102,8 @@ int e1000_init(pci_device_t* pci_dev) {
e1000_dev.rx_descriptors = rx_descriptors;
e1000_dev.rx_head = 0;
e1000_dev.rx_tail = E1000_RX_RING_SIZE - 1;
k_memset(rx_descriptors, 0, sizeof(rx_descriptors));
k_memset(rx_buffers, 0, sizeof(rx_buffers));
memset(rx_descriptors, 0, sizeof(rx_descriptors));
memset(rx_buffers, 0, sizeof(rx_buffers));
for (int i = 0; i < E1000_RX_RING_SIZE; i++) {
e1000_dev.rx_buffers[i] = rx_buffers[i];
e1000_dev.rx_descriptors[i].buffer_addr = v2p((uint64_t)(uintptr_t)rx_buffers[i]);

View file

@ -85,7 +85,7 @@ int rtl8111_init(pci_device_t* pci_dev) {
extern void serial_write(const char *str);
serial_write("[RTL8111] MMIO Base: 0x");
char hex_buf[32]; k_itoa_hex(mmio_base_addr, hex_buf); serial_write(hex_buf); serial_write("\n");
char hex_buf[32]; itoa_hex(mmio_base_addr, hex_buf); serial_write(hex_buf); serial_write("\n");
rtl8111_outb(RTL8111_CR, RTL8111_CR_RST);
for (int i = 0; i < 100000; i++) {
@ -103,14 +103,14 @@ int rtl8111_init(pci_device_t* pci_dev) {
serial_write("[RTL8111] MAC: ");
for(int i=0; i<6; i++) {
char buf[4]; k_itoa_hex(mac_addr[i], buf); serial_write(buf);
char buf[4]; itoa_hex(mac_addr[i], buf); serial_write(buf);
if(i<5) serial_write(":");
}
serial_write("\n");
rtl8111_outb(0x50, 0xC0);
k_memset(rx_desc, 0, sizeof(rx_desc));
memset(rx_desc, 0, sizeof(rx_desc));
for (int i = 0; i < RTL8111_NUM_RX_DESC; i++) {
uint64_t buf_phys = v2p((uint64_t)(uintptr_t)rx_buffers[i]);
rx_desc[i].buf_addr = buf_phys;
@ -125,7 +125,7 @@ int rtl8111_init(pci_device_t* pci_dev) {
rtl8111_outl(RTL8111_RDSAR, (uint32_t)rx_ring_phys);
rtl8111_outl(RTL8111_RDSAR + 4, (uint32_t)(rx_ring_phys >> 32));
k_memset(tx_desc, 0, sizeof(tx_desc));
memset(tx_desc, 0, sizeof(tx_desc));
uint64_t tx_ring_phys = v2p((uint64_t)(uintptr_t)tx_desc);
rtl8111_outl(RTL8111_TDSAR, (uint32_t)tx_ring_phys);
rtl8111_outl(RTL8111_TDSAR + 4, (uint32_t)(tx_ring_phys >> 32));

View file

@ -65,7 +65,7 @@ int rtl8139_init(pci_device_t* pci_dev) {
extern void serial_write(const char *str);
serial_write("[RTL8139] MMIO Base: 0x");
char hex_buf[32]; k_itoa_hex(mmio_base_addr, hex_buf); serial_write(hex_buf); serial_write("\n");
char hex_buf[32]; itoa_hex(mmio_base_addr, hex_buf); serial_write(hex_buf); serial_write("\n");
// Power on (CONFIG1)
rtl8139_outb(RTL8139_CONFIG_1, 0x00);
@ -89,7 +89,7 @@ int rtl8139_init(pci_device_t* pci_dev) {
serial_write("[RTL8139] MAC: ");
for(int i=0; i<6; i++) {
char buf[4];
k_itoa_hex(mac_addr[i], buf);
itoa_hex(mac_addr[i], buf);
serial_write(buf);
if(i<5) serial_write(":");
}

View file

@ -87,7 +87,7 @@ static void virtqueue_init(struct virtqueue* vq, uint8_t* mem, uint16_t qsize) {
uintptr_t used_start = (avail_end + 4095) & ~4095;
vq->used = (struct vq_used*)used_start;
k_memset(mem, 0, 16384);
memset(mem, 0, 16384);
}
int virtio_net_init(pci_device_t* pci_dev) {
@ -105,7 +105,7 @@ int virtio_net_init(pci_device_t* pci_dev) {
extern void serial_write(const char *str);
serial_write("[VIRTIO-NET] I/O Base: 0x");
char hex_buf[32]; k_itoa_hex(io_base, hex_buf); serial_write(hex_buf); serial_write("\n");
char hex_buf[32]; itoa_hex(io_base, hex_buf); serial_write(hex_buf); serial_write("\n");
outb(io_base + VIRTIO_PCI_STATUS, 0);
@ -145,7 +145,7 @@ int virtio_net_init(pci_device_t* pci_dev) {
serial_write("[VIRTIO-NET] MAC: ");
for(int i=0; i<6; i++) {
char buf[4];
k_itoa_hex(mac_addr[i], buf);
itoa_hex(mac_addr[i], buf);
serial_write(buf);
if(i<5) serial_write(":");
}
@ -176,7 +176,7 @@ int virtio_net_send_packet(const void* data, size_t length) {
uint16_t head = tx_vq.last_avail_idx % (tx_vq.q_size / 2);
uint16_t d_idx = head * 2;
k_memset(&tx_hdr[head], 0, sizeof(struct virtio_net_hdr));
memset(&tx_hdr[head], 0, sizeof(struct virtio_net_hdr));
tx_vq.desc[d_idx].addr = v2p((uint64_t)(uintptr_t)&tx_hdr[head]);
tx_vq.desc[d_idx].len = sizeof(struct virtio_net_hdr);
tx_vq.desc[d_idx].flags = VRING_DESC_F_NEXT;

View file

@ -3,7 +3,7 @@
#include "kutils.h"
#define atoi k_atoi
#define atoi atoi
#define rand() 0
#define exit(x) while(1)

View file

@ -1,78 +1,15 @@
#ifndef LWIP_STRING_H
#define LWIP_STRING_H
/*
Forward Facing header, if you want to remove it
replace its references with kutils!
or it wont compile
probably
myles
*/
#include "kutils.h"
#define memcpy k_memcpy
#define memset k_memset
#define strlen k_strlen
#define strcmp k_strcmp
#define strcpy k_strcpy
static inline int memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *p1 = (const unsigned char *)s1;
const unsigned char *p2 = (const unsigned char *)s2;
while (n--) {
if (*p1 != *p2) return (int)*p1 - (int)*p2;
p1++; p2++;
}
return 0;
}
static inline void *memmove(void *dest, const void *src, size_t n) {
unsigned char *d = (unsigned char *)dest;
const unsigned char *s = (const unsigned char *)src;
if (d < s) {
while (n--) *d++ = *s++;
} else {
d += n;
s += n;
while (n--) *--d = *--s;
}
return dest;
}
static inline char *strchr(const char *s, int c) {
while (*s) {
if (*s == (char)c) return (char *)s;
s++;
}
if (c == 0) return (char *)s;
return (void*)0;
}
static inline int strncmp(const char *s1, const char *s2, size_t n) {
while (n && *s1 && (*s1 == *s2)) {
s1++;
s2++;
n--;
}
if (n == 0) return 0;
return (int)*(const unsigned char *)s1 - (int)*(const unsigned char *)s2;
}
static inline char *strncpy(char *dest, const char *src, size_t n) {
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
for ( ; i < n; i++)
dest[i] = '\0';
return dest;
}
static inline char *strstr(const char *haystack, const char *needle) {
if (!*needle) return (char *)haystack;
for (; *haystack; haystack++) {
if (*haystack == *needle) {
const char *h = haystack;
const char *n = needle;
while (*h && *n && *h == *n) {
h++; n++;
}
if (!*n) return (char *)haystack;
}
}
return (void*)0;
}
#endif

View file

@ -35,13 +35,13 @@ void cmd_putchar(char c) {
void cmd_write_int(int n) {
char buf[32];
k_itoa(n, buf);
itoa(n, buf);
cmd_write(buf);
}
void cmd_write_hex(uint64_t n) {
char buf[17];
k_itoa_hex(n, buf);
itoa_hex(n, buf);
cmd_write("0x");
cmd_write(buf);
}

View file

@ -52,19 +52,19 @@ uint64_t exception_handler_c(registers_t *regs) {
// Serial Mirror
serial_write("\n*** EXCEPTION ***\nVector: ");
k_itoa_hex(vector, buf);
itoa_hex(vector, buf);
serial_write("0x");
serial_write(buf);
if ((regs->cs & 0x3) != 0) {
serial_write("\n*** USER MODE EXCEPTION ***\nVector: 0x");
k_itoa_hex(vector, buf);
itoa_hex(vector, buf);
serial_write(buf);
serial_write("\nRIP: 0x");
k_itoa_hex(regs->rip, buf);
itoa_hex(regs->rip, buf);
serial_write(buf);
serial_write("\nError Code: 0x");
k_itoa_hex(regs->err_code, buf);
itoa_hex(regs->err_code, buf);
serial_write(buf);
serial_write("\nTerminating process.\n");
@ -77,12 +77,12 @@ uint64_t exception_handler_c(registers_t *regs) {
// Kernel mode exception
const char *name = (vector < 32) ? exception_messages[vector] : "Unknown Kernel Exception";
serial_write("\nRIP: 0x"); k_itoa_hex(regs->rip, buf); serial_write(buf);
serial_write("\nErr: 0x"); k_itoa_hex(regs->err_code, buf); serial_write(buf);
serial_write("\nRIP: 0x"); itoa_hex(regs->rip, buf); serial_write(buf);
serial_write("\nErr: 0x"); itoa_hex(regs->err_code, buf); serial_write(buf);
if (vector == 14) {
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));
serial_write("\nCR2: 0x"); k_itoa_hex(cr2, buf); serial_write(buf);
serial_write("\nCR2: 0x"); itoa_hex(cr2, buf); serial_write(buf);
}
serial_write("\n");
kernel_panic(regs, name);

View file

@ -110,9 +110,9 @@ static void ap_entry(struct limine_smp_info *info) {
process_t *ap_idle = process_create(NULL, false);
ap_idle->cpu_affinity = my_id;
ap_idle->is_idle = true;
k_strcpy(ap_idle->name, "idle:");
char id_s[8]; k_itoa(my_id, id_s);
k_strcpy(ap_idle->name + 5, id_s);
strcpy(ap_idle->name, "idle:");
char id_s[8]; itoa(my_id, id_s);
strcpy(ap_idle->name + 5, id_s);
process_set_current_for_cpu(my_id, ap_idle);
asm volatile("sti");

View file

@ -1338,7 +1338,7 @@ static uint64_t fs_cmd_list(const syscall_args_t *args) {
if (count > 0) {
for (int i = 0; i < count; i++) {
// Direct copy as layouts are now aligned
k_strcpy(u_entries[i].name, v_entries[i].name);
strcpy(u_entries[i].name, v_entries[i].name);
u_entries[i].size = v_entries[i].size;
u_entries[i].is_directory = v_entries[i].is_directory;
u_entries[i].start_cluster = v_entries[i].start_cluster;
@ -1371,7 +1371,7 @@ static uint64_t fs_cmd_get_info(const syscall_args_t *args) {
vfs_dirent_t v_info;
int res = vfs_get_info(normalized, &v_info);
if (res == 0) {
k_strcpy(u_info->name, v_info.name);
strcpy(u_info->name, v_info.name);
u_info->size = v_info.size;
u_info->is_directory = v_info.is_directory;
u_info->start_cluster = v_info.start_cluster;
@ -1398,9 +1398,9 @@ static uint64_t fs_cmd_getcwd(const syscall_args_t *args) {
char *buf = (char *)args->arg2;
int size = (int)args->arg3;
if (!buf || size <= 0) return -1;
int len = (int)k_strlen(proc->cwd);
int len = (int)strlen(proc->cwd);
if (len >= size) return -1;
k_strcpy(buf, proc->cwd);
strcpy(buf, proc->cwd);
return (uint64_t)len;
}
@ -1411,7 +1411,7 @@ static uint64_t fs_cmd_chdir(const syscall_args_t *args) {
char normalized[VFS_MAX_PATH];
vfs_normalize_path(proc->cwd, path, normalized);
if (vfs_is_directory(normalized)) {
k_strcpy(proc->cwd, normalized);
strcpy(proc->cwd, normalized);
return 0;
}
return -1;
@ -1699,13 +1699,13 @@ static uint64_t sys_cmd_set_text_color(const syscall_args_t *args) {
seq[pos++] = ';';
char num[8];
k_itoa(r, num);
itoa(r, num);
for (int i = 0; num[i] && pos < (int)sizeof(seq) - 1; i++) seq[pos++] = num[i];
seq[pos++] = ';';
k_itoa(g, num);
itoa(g, num);
for (int i = 0; num[i] && pos < (int)sizeof(seq) - 1; i++) seq[pos++] = num[i];
seq[pos++] = ';';
k_itoa(b, num);
itoa(b, num);
for (int i = 0; num[i] && pos < (int)sizeof(seq) - 1; i++) seq[pos++] = num[i];
seq[pos++] = 'm';

View file

@ -11,33 +11,33 @@
// --- Helper: itoa ---
static void sys_itoa(int n, char *s) {
k_itoa(n, s);
itoa(n, s);
}
// --- Graphics Implementation ---
static int read_gfx_drm(char *buf, int size, int offset) {
char out[512];
k_memset(out, 0, 512);
k_strcpy(out, "Driver: Simple Framebuffer\n");
k_strcpy(out + k_strlen(out), "Resolution: ");
char s[32]; k_itoa(get_screen_width(), s);
k_strcpy(out + k_strlen(out), s);
k_strcpy(out + k_strlen(out), "x");
k_itoa(get_screen_height(), s);
k_strcpy(out + k_strlen(out), s);
k_strcpy(out + k_strlen(out), "\nDepth: ");
k_itoa(graphics_get_fb_bpp(), s);
k_strcpy(out + k_strlen(out), s);
k_strcpy(out + k_strlen(out), " bpp\nAddress: 0x");
k_itoa_hex(graphics_get_fb_addr(), s);
k_strcpy(out + k_strlen(out), s);
k_strcpy(out + k_strlen(out), "\n");
memset(out, 0, 512);
strcpy(out, "Driver: Simple Framebuffer\n");
strcpy(out + strlen(out), "Resolution: ");
char s[32]; itoa(get_screen_width(), s);
strcpy(out + strlen(out), s);
strcpy(out + strlen(out), "x");
itoa(get_screen_height(), s);
strcpy(out + strlen(out), s);
strcpy(out + strlen(out), "\nDepth: ");
itoa(graphics_get_fb_bpp(), s);
strcpy(out + strlen(out), s);
strcpy(out + strlen(out), " bpp\nAddress: 0x");
itoa_hex(graphics_get_fb_addr(), s);
strcpy(out + strlen(out), s);
strcpy(out + strlen(out), "\n");
int len = (int)k_strlen(out);
int len = (int)strlen(out);
if (offset >= len) return 0;
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
return to_copy;
}
@ -45,22 +45,22 @@ static int read_gfx_drm(char *buf, int size, int offset) {
static int read_mem_tracking(char *buf, int size, int offset) {
MemStats stats = memory_get_stats();
char out[1024];
k_memset(out, 0, 1024);
memset(out, 0, 1024);
k_strcpy(out, "--- Kernel Heap Tracking ---\n");
k_strcpy(out + k_strlen(out), "Allocated Blocks: ");
char s[32]; k_itoa(stats.allocated_blocks, s);
k_strcpy(out + k_strlen(out), s);
k_strcpy(out + k_strlen(out), "\nFragmentation: ");
k_itoa(stats.fragmentation_percent, s);
k_strcpy(out + k_strlen(out), s);
k_strcpy(out + k_strlen(out), "%\n");
strcpy(out, "--- Kernel Heap Tracking ---\n");
strcpy(out + strlen(out), "Allocated Blocks: ");
char s[32]; itoa(stats.allocated_blocks, s);
strcpy(out + strlen(out), s);
strcpy(out + strlen(out), "\nFragmentation: ");
itoa(stats.fragmentation_percent, s);
strcpy(out + strlen(out), s);
strcpy(out + strlen(out), "%\n");
int len = (int)k_strlen(out);
int len = (int)strlen(out);
if (offset >= len) return 0;
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
return to_copy;
}
@ -71,19 +71,19 @@ static int read_sys_modules(char *buf, int size, int offset) {
for (int i = 0; i < count; i++) {
kernel_module_t *mod = module_manager_get_index(i);
k_strcpy(out + k_strlen(out), " - ");
k_strcpy(out + k_strlen(out), mod->name);
k_strcpy(out + k_strlen(out), " (");
char sz_s[16]; k_itoa(mod->size / 1024, sz_s);
k_strcpy(out + k_strlen(out), sz_s);
k_strcpy(out + k_strlen(out), " KB)\n");
strcpy(out + strlen(out), " - ");
strcpy(out + strlen(out), mod->name);
strcpy(out + strlen(out), " (");
char sz_s[16]; itoa(mod->size / 1024, sz_s);
strcpy(out + strlen(out), sz_s);
strcpy(out + strlen(out), " KB)\n");
}
int len = k_strlen(out);
int len = strlen(out);
if (offset >= len) return 0;
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
return to_copy;
}
@ -93,40 +93,40 @@ static int read_pci_bus(char *buf, int size, int offset) {
int count = pci_enumerate_devices(devices, 64);
char out[4096];
k_memset(out, 0, 4096);
k_strcpy(out, "PCI Bus Devices:\n");
memset(out, 0, 4096);
strcpy(out, "PCI Bus Devices:\n");
for (int i = 0; i < count; i++) {
char line[128];
k_strcpy(line, " [");
char b_s[8]; k_itoa(devices[i].bus, b_s);
k_strcpy(line + k_strlen(line), b_s);
k_strcpy(line + k_strlen(line), ":");
k_itoa(devices[i].device, b_s);
k_strcpy(line + k_strlen(line), b_s);
k_strcpy(line + k_strlen(line), ":");
k_itoa(devices[i].function, b_s);
k_strcpy(line + k_strlen(line), b_s);
k_strcpy(line + k_strlen(line), "] Vendor:");
k_itoa_hex(devices[i].vendor_id, b_s);
k_strcpy(line + k_strlen(line), b_s);
k_strcpy(line + k_strlen(line), " Device:");
k_itoa_hex(devices[i].device_id, b_s);
k_strcpy(line + k_strlen(line), b_s);
k_strcpy(line + k_strlen(line), " Class:");
k_itoa_hex(devices[i].class_code, b_s);
k_strcpy(line + k_strlen(line), b_s);
k_strcpy(line + k_strlen(line), "\n");
strcpy(line, " [");
char b_s[8]; itoa(devices[i].bus, b_s);
strcpy(line + strlen(line), b_s);
strcpy(line + strlen(line), ":");
itoa(devices[i].device, b_s);
strcpy(line + strlen(line), b_s);
strcpy(line + strlen(line), ":");
itoa(devices[i].function, b_s);
strcpy(line + strlen(line), b_s);
strcpy(line + strlen(line), "] Vendor:");
itoa_hex(devices[i].vendor_id, b_s);
strcpy(line + strlen(line), b_s);
strcpy(line + strlen(line), " Device:");
itoa_hex(devices[i].device_id, b_s);
strcpy(line + strlen(line), b_s);
strcpy(line + strlen(line), " Class:");
itoa_hex(devices[i].class_code, b_s);
strcpy(line + strlen(line), b_s);
strcpy(line + strlen(line), "\n");
if (k_strlen(out) + k_strlen(line) < 4095) {
k_strcpy(out + k_strlen(out), line);
if (strlen(out) + strlen(line) < 4095) {
strcpy(out + strlen(out), line);
}
}
int len = (int)k_strlen(out);
int len = (int)strlen(out);
if (offset >= len) return 0;
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
return to_copy;
}
@ -151,35 +151,35 @@ static int read_cpu_info(char *buf, int size, int offset) {
for (uint32_t i = 0; i < cpu_count; i++) {
char c_s[32];
k_strcpy(out + k_strlen(out), "processor\t: ");
k_itoa(i, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "processor\t: ");
itoa(i, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "vendor_id\t: ");
k_strcpy(out + k_strlen(out), vendor);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "vendor_id\t: ");
strcpy(out + strlen(out), vendor);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cpu family\t: ");
k_itoa(info.family, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "cpu family\t: ");
itoa(info.family, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "model\t\t: ");
k_itoa(info.model, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "model\t\t: ");
itoa(info.model, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "model name\t: ");
k_strcpy(out + k_strlen(out), model);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "model name\t: ");
strcpy(out + strlen(out), model);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "stepping\t: ");
k_itoa(info.stepping, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "stepping\t: ");
itoa(info.stepping, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "microcode\t: 0x");
strcpy(out + strlen(out), "microcode\t: 0x");
char hex[16];
int temp = info.microcode;
int hex_pos = 0;
@ -188,64 +188,64 @@ static int read_cpu_info(char *buf, int size, int offset) {
hex[hex_pos++] = digit < 10 ? '0' + digit : 'a' + (digit - 10);
}
hex[hex_pos] = '\0';
k_strcpy(out + k_strlen(out), hex);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), hex);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cache size\t: ");
k_itoa(info.cache_size, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), " KB\n");
strcpy(out + strlen(out), "cache size\t: ");
itoa(info.cache_size, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), " KB\n");
k_strcpy(out + k_strlen(out), "physical id\t: 0\n");
k_strcpy(out + k_strlen(out), "siblings\t: ");
k_itoa(cpu_count, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "physical id\t: 0\n");
strcpy(out + strlen(out), "siblings\t: ");
itoa(cpu_count, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "core id\t\t: ");
k_itoa(i, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "core id\t\t: ");
itoa(i, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cpu cores\t: ");
k_itoa(cpu_count, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "cpu cores\t: ");
itoa(cpu_count, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "apicid\t\t: ");
k_itoa(i, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "apicid\t\t: ");
itoa(i, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "initial apicid\t: ");
k_itoa(i, c_s);
k_strcpy(out + k_strlen(out), c_s);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "initial apicid\t: ");
itoa(i, c_s);
strcpy(out + strlen(out), c_s);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "fpu\t\t: yes\n");
k_strcpy(out + k_strlen(out), "fpu_exception\t: yes\n");
strcpy(out + strlen(out), "fpu\t\t: yes\n");
strcpy(out + strlen(out), "fpu_exception\t: yes\n");
k_strcpy(out + k_strlen(out), "cpuid level\t: 13\n");
strcpy(out + strlen(out), "cpuid level\t: 13\n");
k_strcpy(out + k_strlen(out), "wp\t\t: yes\n");
strcpy(out + strlen(out), "wp\t\t: yes\n");
k_strcpy(out + k_strlen(out), "flags\t\t: ");
k_strcpy(out + k_strlen(out), flags);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "flags\t\t: ");
strcpy(out + strlen(out), flags);
strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "bugs\t\t: \n");
k_strcpy(out + k_strlen(out), "bogomips\t: 4800.00\n");
strcpy(out + strlen(out), "bugs\t\t: \n");
strcpy(out + strlen(out), "bogomips\t: 4800.00\n");
if (i < cpu_count - 1) {
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), "\n");
}
}
int len = (int)k_strlen(out);
int len = (int)strlen(out);
if (offset >= len) { kfree(out); return 0; }
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
kfree(out);
return to_copy;
}
@ -253,57 +253,57 @@ static int read_cpu_info(char *buf, int size, int offset) {
// --- Devices Implementation ---
static int read_sys_devices(char *buf, int size, int offset) {
char out[2048];
k_memset(out, 0, 2048);
memset(out, 0, 2048);
extern int disk_get_count(void);
extern Disk* disk_get_by_index(int index);
int dcount = disk_get_count();
k_strcpy(out, "Block Devices:\n");
strcpy(out, "Block Devices:\n");
for (int i = 0; i < dcount; i++) {
Disk *d = disk_get_by_index(i);
if (d && !d->is_partition) {
k_strcpy(out + k_strlen(out), " ");
k_strcpy(out + k_strlen(out), d->devname);
k_strcpy(out + k_strlen(out), " - ");
k_strcpy(out + k_strlen(out), d->label);
k_strcpy(out + k_strlen(out), "\n");
strcpy(out + strlen(out), " ");
strcpy(out + strlen(out), d->devname);
strcpy(out + strlen(out), " - ");
strcpy(out + strlen(out), d->label);
strcpy(out + strlen(out), "\n");
}
}
k_strcpy(out + k_strlen(out), "\nCharacter Devices:\n");
k_strcpy(out + k_strlen(out), " console - System console\n");
k_strcpy(out + k_strlen(out), " tty - Terminal devices\n");
k_strcpy(out + k_strlen(out), " psmouse - Mouse input\n");
k_strcpy(out + k_strlen(out), " keyboard - Keyboard input\n");
k_strcpy(out + k_strlen(out), " framebuffer - Framebuffer device\n");
strcpy(out + strlen(out), "\nCharacter Devices:\n");
strcpy(out + strlen(out), " console - System console\n");
strcpy(out + strlen(out), " tty - Terminal devices\n");
strcpy(out + strlen(out), " psmouse - Mouse input\n");
strcpy(out + strlen(out), " keyboard - Keyboard input\n");
strcpy(out + strlen(out), " framebuffer - Framebuffer device\n");
int len = (int)k_strlen(out);
int len = (int)strlen(out);
if (offset >= len) return 0;
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
return to_copy;
}
// --- Class Implementation ---
static int read_sys_class(char *buf, int size, int offset) {
char out[1024];
k_memset(out, 0, 1024);
memset(out, 0, 1024);
k_strcpy(out, "Classes:\n");
k_strcpy(out + k_strlen(out), " block - Block device class\n");
k_strcpy(out + k_strlen(out), " input - Input device class\n");
k_strcpy(out + k_strlen(out), " tty - TTY device class\n");
k_strcpy(out + k_strlen(out), " sound - Sound device class\n");
k_strcpy(out + k_strlen(out), " video - Video device class\n");
k_strcpy(out + k_strlen(out), " net - Network device class\n");
strcpy(out, "Classes:\n");
strcpy(out + strlen(out), " block - Block device class\n");
strcpy(out + strlen(out), " input - Input device class\n");
strcpy(out + strlen(out), " tty - TTY device class\n");
strcpy(out + strlen(out), " sound - Sound device class\n");
strcpy(out + strlen(out), " video - Video device class\n");
strcpy(out + strlen(out), " net - Network device class\n");
int len = (int)k_strlen(out);
int len = (int)strlen(out);
if (offset >= len) return 0;
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
return to_copy;
}
@ -311,15 +311,15 @@ static int read_sys_class(char *buf, int size, int offset) {
static int read_gpio_debug(char *buf, int size, int offset) {
uint8_t p64 = inb(0x64);
char out[64] = "Port 0x64 Status: ";
char s[16]; k_itoa(p64, s);
k_strcpy(out + k_strlen(out), s);
k_strcpy(out + k_strlen(out), "\n");
char s[16]; itoa(p64, s);
strcpy(out + strlen(out), s);
strcpy(out + strlen(out), "\n");
int len = k_strlen(out);
int len = strlen(out);
if (offset >= len) return 0;
int to_copy = len - offset;
if (to_copy > size) to_copy = size;
k_memcpy(buf, out + offset, to_copy);
memcpy(buf, out + offset, to_copy);
return to_copy;
}

View file

@ -5,7 +5,7 @@ CC = x86_64-elf-gcc
AS = nasm
LD = x86_64-elf-ld
CFLAGS = -Wall -Wextra -std=gnu11 -ffreestanding -O2 -fno-stack-protector -fno-stack-check -fno-lto -fno-pie -m64 -march=x86-64 -mno-red-zone -I. -Ilibc -I../sys
CFLAGS = -Wall -Wextra -std=gnu11 -ffreestanding -O2 -fno-stack-protector -fno-stack-check -fno-lto -fno-pie -m64 -march=x86-64 -mno-red-zone -I. -Ilibc -I../sys -I../wm
LDFLAGS = -m elf_x86_64 -nostdlib -static -no-pie -Ttext=0x40000000 --no-dynamic-linker -z text -z max-page-size=0x1000 -e _start
BIN_DIR = bin

View file

@ -1438,7 +1438,7 @@ static int read_line(char *out, int max_len, const char *prompt_tmpl) {
int got = sys_tty_read_in(&ch, 1);
if (got <= 0) {
// Throttle idle input polling to avoid pegging the CPU at 100%
sleep(1);
sleep(50);
continue;
}

View file

@ -25,6 +25,8 @@ int main(int argc, char **argv) {
printf("date - Print current date and time\n");
printf("uptime - Print system uptime\n");
printf("meminfo - Print memory information\n");
printf("hexdump <file> - Display file contents in hexadecimal.\n");
printf("ps [options] - List running processes\n");
printf("lsblk - List block devices and partitions\n");
printf("cowsay [msg] - Fun cow says something\n");
printf("beep - Make a beep sound\n");

111
src/userland/cli/hexdump.c Normal file
View file

@ -0,0 +1,111 @@
// Copyright (c) 2023-2026 Chris (boreddevnl)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
// BOREDOS_APP_DESC: Display file contents in hexadecimal.
#include "syscall.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#define BYTES_PER_LINE 16
static int sc_strcmp(const char *a, const char *b) {
while (*a && *a == *b) {
a++;
b++;
}
return (unsigned char)*a - (unsigned char)*b;
}
static void print_usage(void) {
printf("Usage: hexdump <file>\n");
printf("\n");
printf("Display file contents in hexadecimal.\n");
}
static void print_hex_byte(unsigned char b) {
const char *hex = "0123456789ABCDEF";
putchar(hex[(b >> 4) & 0xF]);
putchar(hex[b & 0xF]);
}
static void print_hex32(unsigned int v) {
const char *hex = "0123456789ABCDEF";
for (int i = 7; i >= 0; i--) {
putchar(hex[(v >> (i * 4)) & 0xF]);
}
}
int main(int argc, char **argv) {
int fd;
int offset = 0;
unsigned char buf[BYTES_PER_LINE];
if (argc < 2) {
print_usage();
return 1;
}
if (sc_strcmp(argv[1], "-h") == 0 ||
sc_strcmp(argv[1], "--help") == 0) {
print_usage();
return 0;
}
fd = sys_open(argv[1], "r");
if (fd < 0) {
printf("hexdump: cannot open '%s'\n", argv[1]);
return 1;
}
while (1) {
int bytes = sys_read(fd, buf, BYTES_PER_LINE);
if (bytes <= 0)
break;
// Offset
print_hex32(offset);
printf(" ");
// Hex bytes
for (int i = 0; i < BYTES_PER_LINE; i++) {
if (i < bytes) {
print_hex_byte(buf[i]);
} else {
printf(" ");
}
printf(" ");
if (i == 7)
printf(" ");
}
printf(" |");
// ASCII preview
for (int i = 0; i < bytes; i++) {
unsigned char c = buf[i];
if (c >= 32 && c <= 126)
putchar(c);
else
putchar('.');
}
printf("|\n");
offset += bytes;
}
sys_close(fd);
return 0;
}

299
src/userland/cli/ps.c Normal file
View file

@ -0,0 +1,299 @@
// Copyright (c) 2023-2026 Chris (boreddevnl)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
// BOREDOS_APP_DESC: List running processes.
#include "../libc/syscall.h"
#include "../libc/stdlib.h"
#include "../libc/string.h"
#include "../libc/stdio.h"
#define MAX_PROC_ENTRIES 64
static int sc_strcmp(const char *a, const char *b) {
while (*a && *a == *b) {
a++;
b++;
}
return (unsigned char)*a - (unsigned char)*b;
}
static int is_numeric(const char *s) {
int i = 0;
if (!s || !s[0])
return 0;
while (s[i]) {
if (s[i] < '0' || s[i] > '9')
return 0;
i++;
}
return 1;
}
static void print_spaces(int count) {
for (int i = 0; i < count; i++)
printf(" ");
}
static void print_padded(const char *s, int width) {
int len;
if (!s)
s = "";
printf("%s", s);
len = (int)strlen(s);
if (len < width)
print_spaces(width - len);
else
printf(" ");
}
static int find_value(const char *buf, const char *key) {
char *p = (char*)buf;
int key_len = strlen(key);
while (*p) {
if (memcmp(p, key, key_len) == 0 && p[key_len] == ':') {
p += key_len + 1;
while (*p == ' ' || *p == '\t')
p++;
return atoi(p);
}
while (*p && *p != '\n')
p++;
if (*p == '\n')
p++;
}
return 0;
}
static void find_string(const char *buf,
const char *key,
char *out,
int max_len) {
char *p = (char*)buf;
int key_len = strlen(key);
out[0] = 0;
while (*p) {
if (memcmp(p, key, key_len) == 0 && p[key_len] == ':') {
int i = 0;
p += key_len + 1;
while (*p == ' ' || *p == '\t')
p++;
while (*p &&
*p != '\n' &&
*p != '\r' &&
i < max_len - 1) {
out[i++] = *p++;
}
out[i] = 0;
return;
}
while (*p && *p != '\n')
p++;
if (*p == '\n')
p++;
}
}
static int read_file_to_buf(const char *path,
char *buf,
int max_len) {
int fd;
int bytes;
fd = sys_open(path, "r");
if (fd < 0)
return -1;
bytes = sys_read(fd, buf, max_len - 1);
sys_close(fd);
if (bytes < 0)
return -1;
buf[bytes] = 0;
return bytes;
}
static void format_mem(int kb, char *out) {
char tmp[32];
if (kb < 1024) {
itoa(kb, tmp);
strcpy(out, tmp);
strcat(out, " KB");
} else {
int mb = kb / 1024;
int frac = ((kb % 1024) * 10) / 1024;
itoa(mb, tmp);
strcpy(out, tmp);
strcat(out, ".");
itoa(frac, tmp);
strcat(out, tmp);
strcat(out, " MiB");
}
}
static void print_usage(void) {
printf("Usage: ps [options]\n");
printf("\n");
printf("Options:\n");
printf(" -a Show all processes\n");
printf(" -i Include idle tasks\n");
printf(" -m Show memory usage\n");
printf(" -t Show scheduler ticks\n");
printf(" -p PID Show only one process\n");
printf(" -h Show this help\n");
}
static void print_header(int show_mem,
int show_ticks,
int show_idle) {
print_padded("PID", 8);
print_padded("NAME", 22);
if (show_mem)
print_padded("MEMORY", 14);
if (show_ticks)
print_padded("TICKS", 12);
if (show_idle)
print_padded("IDLE", 8);
printf("\n");
}
int main(int argc, char **argv) {
int show_mem = 0;
int show_ticks = 0;
int include_idle = 0;
int show_idle_col = 0;
int filter_pid = -1;
FAT32_FileInfo entries[MAX_PROC_ENTRIES];
for (int i = 1; i < argc; i++) {
if (sc_strcmp(argv[i], "-m") == 0) {
show_mem = 1;
} else if (sc_strcmp(argv[i], "-t") == 0) {
show_ticks = 1;
} else if (sc_strcmp(argv[i], "-a") == 0) {
include_idle = 1;
show_idle_col = 1;
} else if (sc_strcmp(argv[i], "-i") == 0) {
include_idle = 1;
show_idle_col = 1;
} else if (sc_strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
filter_pid = atoi(argv[++i]);
} else if (sc_strcmp(argv[i], "-h") == 0) {
print_usage();
return 0;
} else {
print_usage();
return 1;
}
}
int count = sys_list("/proc", entries, MAX_PROC_ENTRIES);
if (count < 0) {
printf("ps: failed to read /proc\n");
return 1;
}
print_header(show_mem, show_ticks, show_idle_col);
for (int i = 0; i < count; i++) {
char path[96];
char buf[512];
char name[64];
char mem_str[32];
char tmp[32];
int pid;
int memory_kb;
int ticks;
int idle;
if (!entries[i].is_directory)
continue;
if (!is_numeric(entries[i].name))
continue;
pid = atoi(entries[i].name);
if (filter_pid >= 0 && pid != filter_pid)
continue;
strcpy(path, "/proc/");
strcat(path, entries[i].name);
strcat(path, "/status");
if (read_file_to_buf(path, buf, sizeof(buf)) <= 0)
continue;
find_string(buf, "Name", name, sizeof(name));
memory_kb = find_value(buf, "Memory");
ticks = find_value(buf, "Ticks");
idle = find_value(buf, "Idle");
if (idle && !include_idle)
continue;
itoa(pid, tmp);
print_padded(tmp, 8);
if (!name[0])
strcpy(name, "Unknown");
print_padded(name, 22);
if (show_mem) {
format_mem(memory_kb, mem_str);
print_padded(mem_str, 14);
}
if (show_ticks) {
itoa(ticks, tmp);
print_padded(tmp, 12);
}
if (show_idle_col) {
print_padded(idle ? "yes" : "no", 8);
}
printf("\n");
}
return 0;
}

View file

@ -496,7 +496,7 @@ int main(int argc, char **argv) {
ui_mark_dirty(win, 0, 0, WINDOW_W, WINDOW_H);
}
} else {
sys_yield();
sys_system(SYSTEM_CMD_SLEEP, 10, 0, 0, 0);
}
}

View file

@ -1988,7 +1988,7 @@ int main(int argc, char **argv) {
ui_mark_dirty(win, 0, 0, win_w, win_h);
needs_repaint = 0;
} else {
sys_yield();
sys_system(SYSTEM_CMD_SLEEP, 16, 0, 0, 0);
}
}
return 0;

View file

@ -54,7 +54,7 @@ int main(void) {
draw(win);
ui_mark_dirty(win, 0, 0, WINDOW_W, WINDOW_H);
} else {
sys_yield();
sys_system(SYSTEM_CMD_SLEEP, 10, 0, 0, 0);
}
}

View file

@ -271,7 +271,7 @@ static void generate_lumberjack_pattern(void) {
}
}
static void k_itoa_hex(uint64_t num, char* str) {
static void itoa_hex(uint64_t num, char* str) {
if (num == 0) {
str[0] = '0';
str[1] = '\0';
@ -731,7 +731,7 @@ static void control_panel_paint_network(ui_window_t win) {
char b[4];
mac_str[0] = 0;
for (int i=0; i<6; i++) {
k_itoa_hex(mac.bytes[i], b);
itoa_hex(mac.bytes[i], b);
if (b[1] == 0) { b[1] = b[0]; b[0] = '0'; b[2] = 0; } // zero pad
strcat(mac_str, b);
if (i < 5) strcat(mac_str, ":");

View file

@ -5,6 +5,7 @@
#include "syscall.h"
#include "libui.h"
#include "stdlib.h"
#include "libwidget.h"
#define COLOR_DARK_BG 0xFF121212
#define COLOR_DARK_PANEL 0xFF1E1E1E
@ -20,7 +21,7 @@
#define GRAPH_POINTS 60
static ui_window_t win_taskman;
static ProcessInfo proc_list[32];
static ProcessInfo proc_list[64];
static int proc_count = 0;
static int selected_proc = -1;
@ -36,14 +37,49 @@ static uint64_t used_mem_system = 0;
static char cpu_model_name[64] = "Unknown CPU";
static int cpu_cores = 1;
// libwidget integration
static widget_context_t ctx;
static widget_scrollbar_t proc_sb;
static int scroll_offset = 0;
static void ctx_draw_rect(void *user_data, int x, int y, int w, int h, uint32_t color) {
ui_draw_rect((ui_window_t)(uintptr_t)user_data, x, y, w, h, color);
}
static void ctx_draw_rounded_rect_filled(void *user_data, int x, int y, int w, int h, int r, uint32_t color) {
ui_draw_rounded_rect_filled((ui_window_t)(uintptr_t)user_data, x, y, w, h, r, color);
}
static void ctx_draw_string(void *user_data, int x, int y, const char *str, uint32_t color) {
ui_draw_string((ui_window_t)(uintptr_t)user_data, x, y, str, color);
}
static int ctx_measure_string_width(void *user_data, const char *str) {
(void)user_data;
return (int)ui_get_string_width(str);
}
static void ctx_mark_dirty(void *user_data, int x, int y, int w, int h) {
ui_mark_dirty((ui_window_t)(uintptr_t)user_data, x, y, w, h);
}
static void on_scroll_proc(void *user_data, int new_scroll_y) {
(void)user_data;
scroll_offset = new_scroll_y;
}
static int find_value(const char *buf, const char *key) {
char *p = (char*)buf;
int key_len = strlen(key);
while (*p) {
if (memcmp(p, key, key_len) == 0 && p[key_len] == ':') {
p += key_len + 1;
while (*p == ' ') p++;
return atoi(p);
if (memcmp(p, key, key_len) == 0) {
char *tp = p + key_len;
while (*tp == ' ' || *tp == '\t') tp++;
if (*tp == ':') {
tp++;
while (*tp == ' ' || *tp == '\t') tp++;
return atoi(tp);
}
}
while (*p && *p != '\n') p++;
if (*p == '\n') p++;
@ -55,15 +91,19 @@ static void find_string(const char *buf, const char *key, char *out, int max_len
char *p = (char*)buf;
int key_len = strlen(key);
while (*p) {
if (memcmp(p, key, key_len) == 0 && p[key_len] == ':') {
p += key_len + 1;
while (*p == ' ') p++;
int i = 0;
while (*p && *p != '\n' && i < max_len - 1) {
out[i++] = *p++;
if (memcmp(p, key, key_len) == 0) {
char *tp = p + key_len;
while (*tp == ' ' || *tp == '\t') tp++;
if (*tp == ':') {
tp++;
while (*tp == ' ' || *tp == '\t') tp++;
int i = 0;
while (*tp && *tp != '\n' && i < max_len - 1) {
out[i++] = *tp++;
}
out[i] = 0;
return;
}
out[i] = 0;
return;
}
while (*p && *p != '\n') p++;
if (*p == '\n') p++;
@ -72,8 +112,8 @@ static void find_string(const char *buf, const char *key, char *out, int max_len
}
static void update_proc_list(void) {
FAT32_FileInfo entries[64];
int count = sys_list("/proc", entries, 64);
FAT32_FileInfo entries[128];
int count = sys_list("/proc", entries, 128);
if (count < 0) return;
proc_count = 0;
@ -105,18 +145,20 @@ static void update_proc_list(void) {
sys_close(fd);
if (bytes > 0) {
buf[bytes] = 0;
proc_list[proc_count].pid = pid;
find_string(buf, "Name", proc_list[proc_count].name, 64);
proc_list[proc_count].used_memory = (size_t)find_value(buf, "Memory") * 1024;
uint64_t ticks = (uint64_t)find_value(buf, "Ticks");
proc_list[proc_count].ticks = ticks;
bool is_idle = find_value(buf, "Idle") == 1;
total_ticks_now += ticks;
proc_list[proc_count].is_idle = find_value(buf, "Idle") == 1;
if (!proc_list[proc_count].is_idle) user_ticks_now += ticks;
proc_count++;
if (proc_count >= 32) break;
if (proc_count < 64 && !is_idle) {
proc_list[proc_count].pid = pid;
find_string(buf, "Name", proc_list[proc_count].name, 64);
proc_list[proc_count].used_memory = (size_t)find_value(buf, "Memory") * 1024;
proc_list[proc_count].ticks = ticks;
proc_list[proc_count].is_idle = is_idle;
user_ticks_now += ticks;
proc_count++;
}
}
}
}
@ -268,18 +310,39 @@ static void draw_taskman(void) {
ui_draw_string(win_taskman, 60, 125, "NAME", COLOR_DIM_TEXT);
ui_draw_string(win_taskman, 250, 125, "MEMORY", COLOR_DIM_TEXT);
// Process Rows
int row = 0;
for (int i = 0; i < proc_count && row < MAX_VISIBLE_PROCS; i++) {
int list_x = 10;
int list_y = 150;
int list_w = 380;
int list_h = 480 - 150 - 80; // Leave space for kill button
int row_h = 26;
int content_h = proc_count * row_h;
widget_scrollbar_update(&proc_sb, content_h, scroll_offset);
// Draw scrollbar if content exceeds height
if (content_h > list_h) {
proc_sb.h = list_h;
proc_sb.x = list_x + list_w - 12;
proc_sb.y = list_y;
widget_scrollbar_draw(&ctx, &proc_sb);
list_w -= 15; // Shrink list area to make room for scrollbar
}
// Clipping and Drawing rows
for (int i = 0; i < proc_count; i++) {
if (proc_list[i].pid == 0xFFFFFFFF) continue;
int ry = 150 + row * 26;
uint32_t bg = (selected_proc == row) ? 0xFF334455 : COLOR_DARK_PANEL;
ui_draw_rounded_rect_filled(win_taskman, 10, ry, 380, 24, 4, bg);
int ry = list_y + (i * row_h) - scroll_offset;
if (ry + row_h <= list_y || ry >= list_y + list_h) continue;
uint32_t bg = (selected_proc == i) ? 0xFF334455 : COLOR_DARK_PANEL;
ui_draw_rounded_rect_filled(win_taskman, list_x, ry, list_w, row_h - 2, 4, bg);
char pid_str[16];
itoa(proc_list[i].pid, pid_str);
ui_draw_string(win_taskman, 20, ry + 6, pid_str, COLOR_DARK_TEXT);
ui_draw_string(win_taskman, list_x + 10, ry + 6, pid_str, COLOR_DARK_TEXT);
char name_disp[28];
if (strlen(proc_list[i].name) > 22) {
@ -288,13 +351,11 @@ static void draw_taskman(void) {
} else {
strcpy(name_disp, proc_list[i].name);
}
ui_draw_string(win_taskman, 65, ry + 6, name_disp, COLOR_DARK_TEXT);
ui_draw_string(win_taskman, list_x + 55, ry + 6, name_disp, COLOR_DARK_TEXT);
char m_str[32];
format_mem_smart(proc_list[i].used_memory, m_str);
ui_draw_string(win_taskman, 255, ry + 6, m_str, COLOR_DARK_TEXT);
row++;
ui_draw_string(win_taskman, list_x + 245, ry + 6, m_str, COLOR_DARK_TEXT);
}
// Kill button (Positioned relative to window height)
@ -329,6 +390,18 @@ static void draw_taskman(void) {
int main(void) {
win_taskman = ui_window_create("Task Manager", 100, 100, 400, 480);
// Initialize libwidget context
ctx.user_data = (void*)(uintptr_t)win_taskman;
ctx.draw_rect = ctx_draw_rect;
ctx.draw_rounded_rect_filled = ctx_draw_rounded_rect_filled;
ctx.draw_string = ctx_draw_string;
ctx.measure_string_width = ctx_measure_string_width;
ctx.mark_dirty = ctx_mark_dirty;
ctx.use_light_theme = false;
widget_scrollbar_init(&proc_sb, 388, 150, 12, 250);
proc_sb.on_scroll = on_scroll_proc;
int fd_c = sys_open("/proc/cpuinfo", "r");
if (fd_c >= 0) {
char buf[1024];
@ -336,8 +409,8 @@ int main(void) {
sys_close(fd_c);
if (bytes > 0) {
buf[bytes] = 0;
find_string(buf, "Processor", cpu_model_name, 64);
int cores = find_value(buf, "Cores");
find_string(buf, "model name", cpu_model_name, 64);
int cores = find_value(buf, "cpu cores");
if (cores > 0) cpu_cores = cores;
}
}
@ -346,60 +419,76 @@ int main(void) {
gui_event_t ev;
uint64_t last_update = 30; // Force update on start
while (1) {
bool needs_redraw = false;
// Drain events
while (ui_get_event(win_taskman, &ev)) {
if (ev.type == GUI_EVENT_CLOSE) {
sys_exit(0);
} else if (ev.type == GUI_EVENT_CLICK) {
} else if (ev.type == GUI_EVENT_CLICK || ev.type == GUI_EVENT_MOUSE_DOWN) {
int mx = ev.arg1;
int my = ev.arg2;
if (mx >= 10 && mx < 390 && my >= 150 && my < 150 + MAX_VISIBLE_PROCS * 26) {
int idx = (my - 150) / 26;
int valid_count = 0;
int target_i = -1;
for (int i = 0; i < proc_count; i++) {
if (proc_list[i].pid != 0xFFFFFFFF) {
if (valid_count == idx) { target_i = i; break; }
valid_count++;
bool clicked = (ev.type == GUI_EVENT_CLICK);
bool down = (ev.type == GUI_EVENT_MOUSE_DOWN);
// Handle scrollbar
if (widget_scrollbar_handle_mouse(&proc_sb, mx, my, down, NULL)) {
needs_redraw = true;
} else if (clicked) {
// Handle process selection
int list_x = 10;
int list_y = 150;
int list_h = 480 - 150 - 80;
int row_h = 26;
if (mx >= list_x && mx < list_x + 380 && my >= list_y && my < list_y + list_h) {
int idx = (my - list_y + scroll_offset) / row_h;
if (idx >= 0 && idx < proc_count) {
selected_proc = idx;
} else {
selected_proc = -1;
}
}
if (target_i != -1) selected_proc = idx;
else selected_proc = -1;
draw_taskman();
ui_mark_dirty(win_taskman, 0, 0, 400, 480);
} else if (mx >= 290 && mx < 390 && my >= 410 && my < 440) {
if (selected_proc != -1) {
int valid_count = 0;
for (int i = 0; i < proc_count; i++) {
if (proc_list[i].pid != 0xFFFFFFFF) {
if (valid_count == selected_proc) {
if (proc_list[i].pid != 0) sys_kill(proc_list[i].pid);
break;
}
valid_count++;
}
needs_redraw = true;
} else if (mx >= 290 && mx < 390 && my >= 410 && my < 440) {
// Kill button
if (selected_proc != -1) {
if (proc_list[selected_proc].pid != 0) sys_kill(proc_list[selected_proc].pid);
selected_proc = -1;
update_proc_list();
needs_redraw = true;
}
selected_proc = -1;
update_proc_list();
draw_taskman();
ui_mark_dirty(win_taskman, 0, 0, 400, 480);
}
}
} else if (ev.type == GUI_EVENT_MOUSE_MOVE) {
if (proc_sb.is_dragging) {
widget_scrollbar_handle_mouse(&proc_sb, ev.arg1, ev.arg2, true, NULL);
needs_redraw = true;
}
} else if (ev.type == GUI_EVENT_MOUSE_WHEEL) {
scroll_offset -= (ev.arg1 * 20); // 20px per notch
if (scroll_offset < 0) scroll_offset = 0;
int max_scroll = (proc_count * 26) - (480 - 150 - 80);
if (max_scroll < 0) max_scroll = 0;
if (scroll_offset > max_scroll) scroll_offset = max_scroll;
needs_redraw = true;
} else if (ev.type == GUI_EVENT_PAINT) {
draw_taskman();
ui_mark_dirty(win_taskman, 0, 0, 400, 480);
needs_redraw = true;
}
}
update_proc_list();
draw_taskman();
ui_mark_dirty(win_taskman, 0, 0, 400, 480);
if (last_update++ >= 30) {
update_proc_list();
needs_redraw = true;
last_update = 0;
}
// Proper blocking sleep (200ms)
sys_system(SYSTEM_CMD_SLEEP, 200, 0, 0, 0);
if (needs_redraw) {
draw_taskman();
ui_mark_dirty(win_taskman, 0, 0, 400, 480);
}
sys_system(SYSTEM_CMD_SLEEP, 16, 0, 0, 0);
}
return 0;

View file

@ -793,6 +793,11 @@ static void draw_session(TerminalSession *s) {
int input_end = input_start + cmd_char_len;
if (input_end > g_cols) input_end = g_cols;
char row_buf[512];
int buf_idx = 0;
uint32_t current_color = 0;
int start_col = -1;
for (int col = 0; col < g_cols; col++) {
uint32_t ch = ' ';
uint32_t color = s->fg_color;
@ -809,13 +814,28 @@ static void draw_session(TerminalSession *s) {
}
}
char out[5];
int len = text_encode_utf8(ch, out);
out[len] = 0;
int x = col * g_char_w;
int y = base_y + row * g_line_h;
ui_draw_string(g_win, x, y, out, color);
if (start_col == -1) {
start_col = col;
current_color = color;
buf_idx = 0;
} else if (color != current_color || buf_idx > 480) {
// Flush buffer
row_buf[buf_idx] = 0;
ui_draw_string(g_win, start_col * g_char_w, base_y + row * g_line_h, row_buf, current_color);
start_col = col;
current_color = color;
buf_idx = 0;
}
char utf8[5];
int len = text_encode_utf8(ch, utf8);
for (int k = 0; k < len; k++) row_buf[buf_idx++] = utf8[k];
}
if (start_col != -1 && buf_idx > 0) {
row_buf[buf_idx] = 0;
ui_draw_string(g_win, start_col * g_char_w, base_y + row * g_line_h, row_buf, current_color);
}
}
@ -1265,8 +1285,9 @@ int main(void) {
if (dirty) {
draw_tabs();
draw_session(&g_tabs[g_active_tab]);
dirty = false;
} else {
sys_yield();
sys_system(SYSTEM_CMD_SLEEP, 50, 0, 0, 0);
}
}

View file

@ -158,7 +158,7 @@ static int _b_pipe_read(fd_handle_t *h, void *buf, size_t count) {
}
break;
}
sys_yield();
sleep(1);
continue;
}
@ -193,7 +193,7 @@ static int _b_pipe_write(fd_handle_t *h, const void *buf, size_t count) {
}
break;
}
sys_yield();
sleep(1);
continue;
}

View file

@ -3,6 +3,7 @@
#include "errno.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/types.h"
#include "sys/wait.h"
@ -219,6 +220,6 @@ __attribute__((weak)) pid_t waitpid(pid_t pid, int *status, int options) {
errno = ECHILD;
return -1;
}
sys_yield();
sleep(1);
}
}

View file

@ -363,7 +363,7 @@ int main(int argc, char **argv) {
connected = 0;
break;
}
sys_yield();
sys_system(SYSTEM_CMD_SLEEP, 10, 0, 0, 0);
continue;
}

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 zeyadhost (https://github.com/zeyadhost)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

View file

@ -160,7 +160,7 @@ void wallpaper_save_setting(const char *path) {
serial_str("[WALLPAPER] Failed to save setting\n");
return;
}
fat32_write(fh, path, (uint32_t)k_strlen(path));
fat32_write(fh, path, (uint32_t)strlen(path));
fat32_close(fh);
serial_str("[WALLPAPER] Setting saved: ");
serial_str(path);

View file

@ -100,7 +100,7 @@ static void* rootfs_get_mount_private(const char *mount_path) {
int mc = vfs_get_mount_count();
for (int i = 0; i < mc; i++) {
vfs_mount_t *m = vfs_get_mount(i);
if (m && m->active && k_strcmp(m->path, mount_path) == 0) {
if (m && m->active && strcmp(m->path, mount_path) == 0) {
return m->fs_private;
}
}
@ -152,7 +152,7 @@ static void rootfs_write_marker(void) {
FAT32_FileHandle *fh = fat32_open(ROOT_MARKER_PATH, "w");
if (!fh || !fh->valid) return;
const char *msg = "boredos root\n";
fat32_write(fh, msg, (uint32_t)k_strlen(msg));
fat32_write(fh, msg, (uint32_t)strlen(msg));
fat32_close(fh);
}
@ -887,8 +887,8 @@ static bool dock_icon_decode_into_entry(dock_icon_entry_t *entry) {
if (!entry || !entry->filename) return false;
char full_path[192];
k_strcpy(full_path, DOCK_ICON_BASE_PATH);
k_strcpy(full_path + k_strlen(full_path), entry->filename);
strcpy(full_path, DOCK_ICON_BASE_PATH);
strcpy(full_path + strlen(full_path), entry->filename);
FAT32_FileHandle *fh = fat32_open(full_path, "r");
if (!fh) return false;
@ -929,7 +929,7 @@ static bool dock_icon_decode_into_entry(dock_icon_entry_t *entry) {
int img_max_x = img_w - 1;
int img_max_y = img_h - 1;
k_memset(entry->pixels, 0, sizeof(entry->pixels));
memset(entry->pixels, 0, sizeof(entry->pixels));
for (int ty = 0; ty < DOCK_ICON_SIZE; ty++) {
for (int tx = 0; tx < DOCK_ICON_SIZE; tx++) {
int sx = (DOCK_ICON_SIZE > 1) ? (tx * img_max_x) / (DOCK_ICON_SIZE - 1) : 0;
@ -1150,7 +1150,7 @@ static void dock_label_from_target(const char *target, char *out_label, int out_
}
dock_copy_text(out_label, out_size, name);
int len = (int)k_strlen(out_label);
int len = (int)strlen(out_label);
if (len > 4 && str_ends_with(out_label, ".elf")) {
out_label[len - 4] = 0;
} else if (len > 9 && str_ends_with(out_label, ".shortcut")) {
@ -1280,14 +1280,14 @@ static void dock_save_config(void) {
if (!fh) return;
const char *header = "v1\n";
fat32_write(fh, header, (int)k_strlen(header));
fat32_write(fh, header, (int)strlen(header));
for (int i = 0; i < dock_item_count; i++) {
dock_write_int(fh, dock_items[i].icon_slot);
fat32_write(fh, "|", 1);
fat32_write(fh, dock_items[i].label, (int)k_strlen(dock_items[i].label));
fat32_write(fh, dock_items[i].label, (int)strlen(dock_items[i].label));
fat32_write(fh, "|", 1);
fat32_write(fh, dock_items[i].target, (int)k_strlen(dock_items[i].target));
fat32_write(fh, dock_items[i].target, (int)strlen(dock_items[i].target));
fat32_write(fh, "\n", 1);
}
@ -2654,8 +2654,8 @@ static void wm_paint_region(int y_start, int y_end, DirtyRect dirty, int pass) {
if (msg_box_visible) {
ttf_font_t *_ttf = graphics_get_current_ttf();
int title_w = _ttf ? font_manager_get_string_width(_ttf, msg_box_title) : (int)(k_strlen(msg_box_title) * 8);
int text_w = _ttf ? font_manager_get_string_width(_ttf, msg_box_text) : (int)(k_strlen(msg_box_text) * 8);
int title_w = _ttf ? font_manager_get_string_width(_ttf, msg_box_title) : (int)(strlen(msg_box_title) * 8);
int text_w = _ttf ? font_manager_get_string_width(_ttf, msg_box_text) : (int)(strlen(msg_box_text) * 8);
int content_w = (title_w > text_w) ? title_w : text_w;
int padding = 30; // horizontal padding on each side
int mw = content_w + padding * 2;