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

@ -106,6 +106,13 @@
</a><br /> </a><br />
Contributor Contributor
</td> </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> </tr>
</table> </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. * Including `libui.h` and the event structure.
* Creating a `ui_window_t` handle. * Creating a `ui_window_t` handle.
* Creating an infinite event loop using `ui_get_event()`. * 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. * 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 // If we don't do this, the while(1) loop will consume 100% of the CPU
// and starve the rest of the OS! // and starve the rest of the OS! A 10ms sleep allows for ~100 FPS
sys_yield(); // 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. // 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. 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. 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. 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. 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 ## 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 // Step D: Instruct the compositor to flush our drawing buffer to the physical screen
ui_mark_dirty(wid, 0, 0, W_WIDTH, W_HEIGHT); ui_mark_dirty(wid, 0, 0, W_WIDTH, W_HEIGHT);
// 4. Yield and throttle // 4. Yield and throttle (targeting ~60 FPS)
sys_yield(); sys_system(SYSTEM_CMD_SLEEP, 16, 0, 0, 0);
} }
return 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. 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] > [!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 | | 47 | `SYSTEM_CMD_SET_RESOLUTION` | Set display mode |
| 49 | `SYSTEM_CMD_SET_KEYBOARD_LAYOUT` | Set active keyboard layout ID | | 49 | `SYSTEM_CMD_SET_KEYBOARD_LAYOUT` | Set active keyboard layout ID |
| 51 | `SYSTEM_CMD_GET_KEYBOARD_LAYOUT` | Get current 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 | | 52 | `SYSTEM_GET_CURSOR_SCALE` | Get the current BoredWM cursor scale |
| 79 | `SYSTEM_SET_CURSOR_SCALE` | Set the BoredWM cursor scale | | 53 | `SYSTEM_SET_CURSOR_SCALE` | Set the BoredWM cursor scale |
### Time, power, and system state ### Time, power, and system state
@ -110,8 +110,8 @@ Notes:
| 28 | `SYSTEM_CMD_GET_SHELL_CONFIG` | Read shell config value | | 28 | `SYSTEM_CMD_GET_SHELL_CONFIG` | Read shell config value |
| 32 | `SYSTEM_CMD_RTC_SET` | Set RTC datetime | | 32 | `SYSTEM_CMD_RTC_SET` | Set RTC datetime |
| 41 | `SYSTEM_CMD_SET_RAW_MODE` | Terminal raw-mode control | | 41 | `SYSTEM_CMD_SET_RAW_MODE` | Terminal raw-mode control |
| 43 | `SYSTEM_CMD_YIELD` | Yield scheduler timeslice | | 43 | `SYSTEM_CMD_YIELD` | Yield scheduler timeslice (Not recommended for idle loops) |
| 46 | `SYSTEM_CMD_SLEEP` | Sleep current process | | 46 | `SYSTEM_CMD_SLEEP` | Sleep current process (Recommended for throttling) |
### Network ### Network
@ -187,7 +187,7 @@ Notes:
## Common Wrapper API (`src/userland/libc/syscall.h`) ## Common Wrapper API (`src/userland/libc/syscall.h`)
Typical wrappers used by apps: 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` - 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` - 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` - 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. Returns `true` if an event was waiting in the queue, populating the `ev` structure. Returns `false` if the queue is empty.
> [!IMPORTANT] > [!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 ### Graphical Event Structure

View file

@ -7,18 +7,18 @@
#include "../drivers/acpi.h" #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; unsigned char *ptr = (unsigned char *)dest;
while (len-- > 0) *ptr++ = (unsigned char)val; 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; unsigned char *d = (unsigned char *)dest;
const unsigned char *s = (const unsigned char *)src; const unsigned char *s = (const unsigned char *)src;
while (len-- > 0) *d++ = *s++; 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 *s1 = (const unsigned char*)str1;
register const unsigned char *s2 = (const unsigned char*)str2; 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; 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; size_t len = 0;
while (str[len]) len++; while (str[len]) len++;
return len; return len;
} }
int k_strcmp(const char *s1, const char *s2) { int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) { while (*s1 && (*s1 == *s2)) {
s1++; s1++;
s2++; s2++;
@ -43,7 +60,7 @@ int k_strcmp(const char *s1, const char *s2) {
return *(const unsigned char*)s1 - *(const unsigned 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)) { while (n && *s1 && (*s1 == *s2)) {
s1++; s1++;
s2++; 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; 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++; while (*src) *dest++ = *src++;
*dest = 0; *dest = 0;
} }
int k_atoi(const char *str) { int atoi(const char *str) {
int res = 0; int res = 0;
int sign = 1; int sign = 1;
if (*str == '-') { sign = -1; str++; } if (*str == '-') { sign = -1; str++; }
@ -69,7 +86,7 @@ int k_atoi(const char *str) {
return res * sign; return res * sign;
} }
void k_itoa(int n, char *buf) { void itoa(int n, char *buf) {
if (n == 0) { if (n == 0) {
buf[0] = '0'; buf[1] = 0; return; 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"; const char *digits = "0123456789ABCDEF";
if (n == 0) { if (n == 0) {
buf[0] = '0'; buf[0] = '0';

View file

@ -9,16 +9,17 @@
#include <stdbool.h> #include <stdbool.h>
// Kernel string utilities // Kernel string utilities
void k_memset(void *dest, int val, size_t len); void *memmove(void *dest, const void *src, uint64_t n);
void k_memcpy(void *dest, const void *src, size_t len); void memset(void *dest, int val, size_t len);
int k_memcmp (const void *str1, const void *str2, size_t count); void memcpy(void *dest, const void *src, size_t len);
size_t k_strlen(const char *str); int memcmp (const void *str1, const void *str2, size_t count);
int k_strcmp(const char *s1, const char *s2); size_t strlen(const char *str);
int k_strncmp(const char *s1, const char *s2, size_t n); int strcmp(const char *s1, const char *s2);
void k_strcpy(char *dest, const char *src); int strncmp(const char *s1, const char *s2, size_t n);
int k_atoi(const char *str); void strcpy(char *dest, const char *src);
void k_itoa(int n, char *buf); int atoi(const char *str);
void k_itoa_hex(uint64_t n, char *buf); void itoa(int n, char *buf);
void itoa_hex(uint64_t n, char *buf);
// Kernel timing utilities // Kernel timing utilities
void k_delay(int iterations); 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) { static bool cmdline_has_flag(const char *cmdline, const char *flag) {
if (!cmdline || !flag || !flag[0]) return false; if (!cmdline || !flag || !flag[0]) return false;
int flag_len = (int)k_strlen(flag); int flag_len = (int)strlen(flag);
const char *p = cmdline; const char *p = cmdline;
while (*p) { while (*p) {
while (*p == ' ') p++; while (*p == ' ') p++;
@ -245,19 +245,19 @@ static bool cmdline_has_flag(const char *cmdline, const char *flag) {
const char *start = p; const char *start = p;
while (*p && *p != ' ') p++; while (*p && *p != ' ') p++;
int len = (int)(p - start); 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; return false;
} }
static bool cmdline_read_value(const char *cmdline, const char *key, char *out, int out_len) { 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; 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; const char *p = cmdline;
while (*p) { while (*p) {
while (*p == ' ') p++; while (*p == ' ') p++;
if (!*p) break; 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; const char *val = p + key_len;
int i = 0; int i = 0;
while (*val && *val != ' ' && i < out_len - 1) { 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 != NULL) {
if (bootloader_info_request.response->name) { 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) { 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]; char hex_buf[17];
serial_write("Vector: 0x"); 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(hex_buf);
serial_write("\n"); serial_write("\n");
serial_write("Error Code: 0x"); 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(hex_buf);
serial_write("\n"); serial_write("\n");
serial_write("RIP: 0x"); serial_write("RIP: 0x");
k_itoa_hex(regs->rip, hex_buf); itoa_hex(regs->rip, hex_buf);
serial_write(hex_buf); serial_write(hex_buf);
serial_write("\n"); serial_write("\n");
@ -102,7 +102,7 @@ void kernel_panic(registers_t *regs, const char *error_name) {
uint64_t cr2; uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2)); asm volatile("mov %%cr2, %0" : "=r"(cr2));
serial_write("CR2: 0x"); serial_write("CR2: 0x");
k_itoa_hex(cr2, hex_buf); itoa_hex(cr2, hex_buf);
serial_write(hex_buf); serial_write(hex_buf);
serial_write("\n"); 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)); asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1));
// ECX flags // ECX flags
if (ecx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "sse3 "); if (ecx & (1 << 0)) strcpy(flags_str + strlen(flags_str), "sse3 ");
if (ecx & (1 << 1)) k_strcpy(flags_str + k_strlen(flags_str), "pclmulqdq "); if (ecx & (1 << 1)) strcpy(flags_str + strlen(flags_str), "pclmulqdq ");
if (ecx & (1 << 3)) k_strcpy(flags_str + k_strlen(flags_str), "monitor "); if (ecx & (1 << 3)) strcpy(flags_str + strlen(flags_str), "monitor ");
if (ecx & (1 << 6)) k_strcpy(flags_str + k_strlen(flags_str), "ssse3 "); if (ecx & (1 << 6)) strcpy(flags_str + strlen(flags_str), "ssse3 ");
if (ecx & (1 << 9)) k_strcpy(flags_str + k_strlen(flags_str), "sdbg "); if (ecx & (1 << 9)) strcpy(flags_str + strlen(flags_str), "sdbg ");
if (ecx & (1 << 12)) k_strcpy(flags_str + k_strlen(flags_str), "fma "); if (ecx & (1 << 12)) strcpy(flags_str + strlen(flags_str), "fma ");
if (ecx & (1 << 13)) k_strcpy(flags_str + k_strlen(flags_str), "cx16 "); if (ecx & (1 << 13)) strcpy(flags_str + strlen(flags_str), "cx16 ");
if (ecx & (1 << 19)) k_strcpy(flags_str + k_strlen(flags_str), "sse4_1 "); if (ecx & (1 << 19)) strcpy(flags_str + strlen(flags_str), "sse4_1 ");
if (ecx & (1 << 20)) k_strcpy(flags_str + k_strlen(flags_str), "sse4_2 "); if (ecx & (1 << 20)) strcpy(flags_str + strlen(flags_str), "sse4_2 ");
if (ecx & (1 << 23)) k_strcpy(flags_str + k_strlen(flags_str), "popcnt "); if (ecx & (1 << 23)) strcpy(flags_str + strlen(flags_str), "popcnt ");
if (ecx & (1 << 25)) k_strcpy(flags_str + k_strlen(flags_str), "aes "); if (ecx & (1 << 25)) strcpy(flags_str + strlen(flags_str), "aes ");
if (ecx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "xsave "); if (ecx & (1 << 26)) strcpy(flags_str + strlen(flags_str), "xsave ");
if (ecx & (1 << 28)) k_strcpy(flags_str + k_strlen(flags_str), "avx "); if (ecx & (1 << 28)) strcpy(flags_str + strlen(flags_str), "avx ");
// EDX flags // EDX flags
if (edx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "fpu "); if (edx & (1 << 0)) strcpy(flags_str + strlen(flags_str), "fpu ");
if (edx & (1 << 3)) k_strcpy(flags_str + k_strlen(flags_str), "pse "); if (edx & (1 << 3)) strcpy(flags_str + strlen(flags_str), "pse ");
if (edx & (1 << 4)) k_strcpy(flags_str + k_strlen(flags_str), "tsc "); if (edx & (1 << 4)) strcpy(flags_str + strlen(flags_str), "tsc ");
if (edx & (1 << 6)) k_strcpy(flags_str + k_strlen(flags_str), "pae "); if (edx & (1 << 6)) strcpy(flags_str + strlen(flags_str), "pae ");
if (edx & (1 << 8)) k_strcpy(flags_str + k_strlen(flags_str), "cx8 "); if (edx & (1 << 8)) strcpy(flags_str + strlen(flags_str), "cx8 ");
if (edx & (1 << 9)) k_strcpy(flags_str + k_strlen(flags_str), "apic "); if (edx & (1 << 9)) strcpy(flags_str + strlen(flags_str), "apic ");
if (edx & (1 << 11)) k_strcpy(flags_str + k_strlen(flags_str), "sep "); if (edx & (1 << 11)) strcpy(flags_str + strlen(flags_str), "sep ");
if (edx & (1 << 15)) k_strcpy(flags_str + k_strlen(flags_str), "cmov "); if (edx & (1 << 15)) strcpy(flags_str + strlen(flags_str), "cmov ");
if (edx & (1 << 23)) k_strcpy(flags_str + k_strlen(flags_str), "mmx "); if (edx & (1 << 23)) strcpy(flags_str + strlen(flags_str), "mmx ");
if (edx & (1 << 24)) k_strcpy(flags_str + k_strlen(flags_str), "fxsr "); if (edx & (1 << 24)) strcpy(flags_str + strlen(flags_str), "fxsr ");
if (edx & (1 << 25)) k_strcpy(flags_str + k_strlen(flags_str), "sse "); if (edx & (1 << 25)) strcpy(flags_str + strlen(flags_str), "sse ");
if (edx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "sse2 "); if (edx & (1 << 26)) strcpy(flags_str + strlen(flags_str), "sse2 ");
// Extended leaf 0x80000001 for advanced flags // Extended leaf 0x80000001 for advanced flags
asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(0x80000001)); 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 << 11)) strcpy(flags_str + strlen(flags_str), "syscall ");
if (edx & (1 << 20)) k_strcpy(flags_str + k_strlen(flags_str), "nx "); if (edx & (1 << 20)) strcpy(flags_str + strlen(flags_str), "nx ");
if (edx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "pdpe1gb "); if (edx & (1 << 26)) strcpy(flags_str + strlen(flags_str), "pdpe1gb ");
if (edx & (1 << 27)) k_strcpy(flags_str + k_strlen(flags_str), "rdtscp "); if (edx & (1 << 27)) strcpy(flags_str + strlen(flags_str), "rdtscp ");
if (edx & (1 << 29)) k_strcpy(flags_str + k_strlen(flags_str), "lm "); 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 << 0)) strcpy(flags_str + strlen(flags_str), "lahf_lm ");
if (ecx & (1 << 5)) k_strcpy(flags_str + k_strlen(flags_str), "abm "); if (ecx & (1 << 5)) strcpy(flags_str + strlen(flags_str), "abm ");
// Remove trailing space // Remove trailing space
int len = k_strlen(flags_str); int len = strlen(flags_str);
if (len > 0 && flags_str[len-1] == ' ') { if (len > 0 && flags_str[len-1] == ' ') {
flags_str[len-1] = '\0'; 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++) { for (size_t i = 0; i < entries; i++) {
struct acpi_sdt *tbl = (struct acpi_sdt *)p2v(acpi_xsdt->tables[i]); struct acpi_sdt *tbl = (struct acpi_sdt *)p2v(acpi_xsdt->tables[i]);
if (!tbl) continue; if (!tbl) continue;
if (!k_memcmp(tbl->signature, signature, 4)) if (!memcmp(tbl->signature, signature, 4))
return tbl; 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++) { for (size_t i = 0; i < entries; i++) {
struct acpi_sdt *tbl = (struct acpi_sdt *)p2v(tables[i]); struct acpi_sdt *tbl = (struct acpi_sdt *)p2v(tables[i]);
if (!tbl) continue; if (!tbl) continue;
if (!k_memcmp(tbl->signature, signature, 4)) if (!memcmp(tbl->signature, signature, 4))
return tbl; return tbl;
} }
@ -89,14 +89,14 @@ void acpi_parse_s5(void) {
char *dsdt = (char *)p2v((uintptr_t)acpi_fadt->dsdt); 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); uint32_t dsdt_len = *(uint32_t*)(dsdt + 4);
char *ptr = dsdt + 36; char *ptr = dsdt + 36;
char *end = dsdt + dsdt_len; char *end = dsdt + dsdt_len;
while (ptr < end) { while (ptr < end) {
if (k_memcmp(ptr, "_S5_", 4) == 0) { if (memcmp(ptr, "_S5_", 4) == 0) {
ptr += 4; ptr += 4;
if (*ptr == 0x12) { if (*ptr == 0x12) {
ptr += 3; 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) { 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; bootfs_custom_file_t *f = (bootfs_custom_file_t*)g_bootfs_state.custom_files;
while (f) { while (f) {
if (k_strcmp(f->name, name) == 0) return f; if (strcmp(f->name, name) == 0) return f;
f = f->next; f = f->next;
} }
return NULL; return NULL;
@ -82,8 +82,8 @@ void bootfs_register_file(const char *name, void *data, uint32_t size) {
if (!f) { if (!f) {
f = (bootfs_custom_file_t*)kmalloc(sizeof(bootfs_custom_file_t)); f = (bootfs_custom_file_t*)kmalloc(sizeof(bootfs_custom_file_t));
if (!f) return; if (!f) return;
k_memset(f, 0, sizeof(bootfs_custom_file_t)); memset(f, 0, sizeof(bootfs_custom_file_t));
k_strcpy(f->name, name); strcpy(f->name, name);
f->next = (bootfs_custom_file_t*)g_bootfs_state.custom_files; f->next = (bootfs_custom_file_t*)g_bootfs_state.custom_files;
g_bootfs_state.custom_files = f; 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) { static bool is_metadata_path(const char *path) {
if (!path) return false; 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) { static bool is_metadata_file(const char *path) {
if (k_strcmp(path, "metadata/boot_time") == 0) return true; if (strcmp(path, "metadata/boot_time") == 0) return true;
if (k_strcmp(path, "metadata/boot_flags") == 0) return true; if (strcmp(path, "metadata/boot_flags") == 0) return true;
if (k_strcmp(path, "metadata/version") == 0) return true; if (strcmp(path, "metadata/version") == 0) return true;
return false; 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)); bootfs_handle_t *h = (bootfs_handle_t*)kmalloc(sizeof(bootfs_handle_t));
if (!h) return NULL; if (!h) return NULL;
k_memset(h, 0, sizeof(bootfs_handle_t)); memset(h, 0, sizeof(bootfs_handle_t));
k_strcpy(h->path, path); strcpy(h->path, path);
h->offset = 0; h->offset = 0;
if (path[0] == '\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'; buffer[0] = '\0';
int len = 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); extern uint32_t wm_get_ticks(void);
uint32_t ticks = wm_get_ticks(); uint32_t ticks = wm_get_ticks();
k_strcpy(buffer, "Boot time: "); strcpy(buffer, "Boot time: ");
char time_buf[32]; char time_buf[32];
k_itoa(g_bootfs_state.boot_time_ms, time_buf); itoa(g_bootfs_state.boot_time_ms, time_buf);
k_strcpy(buffer + k_strlen(buffer), time_buf); strcpy(buffer + strlen(buffer), time_buf);
k_strcpy(buffer + k_strlen(buffer), " ms\nTicks: "); strcpy(buffer + strlen(buffer), " ms\nTicks: ");
k_itoa(ticks, time_buf); itoa(ticks, time_buf);
k_strcpy(buffer + k_strlen(buffer), time_buf); strcpy(buffer + strlen(buffer), time_buf);
k_strcpy(buffer + k_strlen(buffer), "\n"); strcpy(buffer + strlen(buffer), "\n");
len = k_strlen(buffer); len = strlen(buffer);
} else if (k_strcmp(file, "metadata/version") == 0) { } else if (strcmp(file, "metadata/version") == 0) {
k_strcpy(buffer, "Bootloader: "); strcpy(buffer, "Bootloader: ");
k_strcpy(buffer + k_strlen(buffer), g_bootfs_state.bootloader_name); strcpy(buffer + strlen(buffer), g_bootfs_state.bootloader_name);
k_strcpy(buffer + k_strlen(buffer), "\nVersion: "); strcpy(buffer + strlen(buffer), "\nVersion: ");
k_strcpy(buffer + k_strlen(buffer), g_bootfs_state.bootloader_version); strcpy(buffer + strlen(buffer), g_bootfs_state.bootloader_version);
k_strcpy(buffer + k_strlen(buffer), "\n"); strcpy(buffer + strlen(buffer), "\n");
len = k_strlen(buffer); len = strlen(buffer);
} else if (k_strcmp(file, "metadata/boot_flags") == 0) { } else if (strcmp(file, "metadata/boot_flags") == 0) {
k_strcpy(buffer, "Boot flags: 0x"); strcpy(buffer, "Boot flags: 0x");
char flags_buf[8]; char flags_buf[8];
uint8_t flags = g_bootfs_state.boot_flags; uint8_t flags = g_bootfs_state.boot_flags;
int hex_digit = (flags >> 4) & 0xF; 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[1] = hex_digit < 10 ? '0' + hex_digit : 'a' + (hex_digit - 10);
flags_buf[2] = '\n'; flags_buf[2] = '\n';
flags_buf[3] = '\0'; flags_buf[3] = '\0';
k_strcpy(buffer + k_strlen(buffer), flags_buf); strcpy(buffer + strlen(buffer), flags_buf);
len = k_strlen(buffer); len = strlen(buffer);
} }
return len; return len;
@ -180,30 +180,30 @@ static int bootfs_read(void *fs_private, void *handle, void *buf, int size) {
int content_len = 0; int content_len = 0;
if (k_strcmp(h->path, "limine.conf") == 0) { if (strcmp(h->path, "limine.conf") == 0) {
k_memcpy(content_buffer, g_bootfs_state.limine_conf, memcpy(content_buffer, g_bootfs_state.limine_conf,
g_bootfs_state.limine_conf_len); g_bootfs_state.limine_conf_len);
content_len = g_bootfs_state.limine_conf_len; content_len = g_bootfs_state.limine_conf_len;
} else if (k_strcmp(h->path, "kernel") == 0) { } else if (strcmp(h->path, "kernel") == 0) {
k_strcpy(content_buffer, "Kernel reference\nSize: "); strcpy(content_buffer, "Kernel reference\nSize: ");
char size_buf[32]; char size_buf[32];
k_itoa(g_bootfs_state.kernel_size, size_buf); itoa(g_bootfs_state.kernel_size, size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), size_buf); strcpy(content_buffer + strlen(content_buffer), size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), " bytes\n"); strcpy(content_buffer + strlen(content_buffer), " bytes\n");
content_len = k_strlen(content_buffer); content_len = strlen(content_buffer);
} else if (k_strcmp(h->path, "initrd") == 0) { } else if (strcmp(h->path, "initrd") == 0) {
k_strcpy(content_buffer, "Initial ramdisk reference\nSize: "); strcpy(content_buffer, "Initial ramdisk reference\nSize: ");
char size_buf[32]; char size_buf[32];
k_itoa(g_bootfs_state.initrd_size, size_buf); itoa(g_bootfs_state.initrd_size, size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), size_buf); strcpy(content_buffer + strlen(content_buffer), size_buf);
k_strcpy(content_buffer + k_strlen(content_buffer), " bytes\n"); strcpy(content_buffer + strlen(content_buffer), " bytes\n");
content_len = k_strlen(content_buffer); content_len = strlen(content_buffer);
} else if (k_strcmp(h->path, "initrd.tar") == 0) { } else if (strcmp(h->path, "initrd.tar") == 0) {
kfree(content_buffer); kfree(content_buffer);
if (h->offset >= (int)g_bootfs_state.initrd_size) return 0; if (h->offset >= (int)g_bootfs_state.initrd_size) return 0;
int avail = (int)g_bootfs_state.initrd_size - h->offset; int avail = (int)g_bootfs_state.initrd_size - h->offset;
int to_read = (size < avail) ? size : avail; 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; h->offset += to_read;
return to_read; return to_read;
} else if (is_metadata_file(h->path)) { } 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; if (h->offset >= (int)cf->size) return 0;
int avail = (int)cf->size - h->offset; int avail = (int)cf->size - h->offset;
int to_read = (avail < size) ? avail : size; 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; h->offset += to_read;
return 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 available = content_len - h->offset;
int read_size = (available < size) ? available : size; 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; h->offset += read_size;
kfree(content_buffer); 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; bootfs_handle_t *h = (bootfs_handle_t*)handle;
if (!h || !buf || size <= 0) return -1; if (!h || !buf || size <= 0) return -1;
if (k_strcmp(h->path, "limine.conf") != 0) { if (strcmp(h->path, "limine.conf") != 0) {
return -1; 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; if (max_write <= 0) return -1;
int write_size = (size < max_write) ? size : max_write; 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; h->offset += write_size;
if (h->offset > g_bootfs_state.limine_conf_len) { 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 (rel_path[0] == '\0') {
if (count < max) { 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].size = g_bootfs_state.limine_conf_len;
entries[count].is_directory = 0; entries[count].is_directory = 0;
count++; count++;
} }
if (count < max) { if (count < max) {
k_strcpy(entries[count].name, "kernel"); strcpy(entries[count].name, "kernel");
entries[count].size = g_bootfs_state.kernel_size; entries[count].size = g_bootfs_state.kernel_size;
entries[count].is_directory = 0; entries[count].is_directory = 0;
count++; count++;
} }
if (count < max) { if (count < max) {
k_strcpy(entries[count].name, "initrd"); strcpy(entries[count].name, "initrd");
entries[count].size = g_bootfs_state.initrd_size; entries[count].size = g_bootfs_state.initrd_size;
entries[count].is_directory = 0; entries[count].is_directory = 0;
count++; count++;
} }
if (count < max) { 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].size = g_bootfs_state.initrd_size;
entries[count].is_directory = 0; entries[count].is_directory = 0;
count++; count++;
} }
if (count < max) { if (count < max) {
k_strcpy(entries[count].name, "metadata"); strcpy(entries[count].name, "metadata");
entries[count].size = 0; entries[count].size = 0;
entries[count].is_directory = 1; entries[count].is_directory = 1;
count++; count++;
} }
bootfs_custom_file_t *cf = (bootfs_custom_file_t*)g_bootfs_state.custom_files; bootfs_custom_file_t *cf = (bootfs_custom_file_t*)g_bootfs_state.custom_files;
while (cf && count < max) { while (cf && count < max) {
k_strcpy(entries[count].name, cf->name); strcpy(entries[count].name, cf->name);
entries[count].size = cf->size; entries[count].size = cf->size;
entries[count].is_directory = 0; entries[count].is_directory = 0;
count++; count++;
cf = cf->next; cf = cf->next;
} }
} }
else if (k_strcmp(rel_path, "metadata") == 0) { else if (strcmp(rel_path, "metadata") == 0) {
const char *meta_files[] = { const char *meta_files[] = {
"boot_time", "boot_time",
"boot_flags", "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++) { 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].size = 0;
entries[count].is_directory = 0; entries[count].is_directory = 0;
count++; count++;
@ -367,7 +367,7 @@ static bool bootfs_rmdir(void *fs_private, const char *rel_path) {
if (!rel_path) rel_path = ""; if (!rel_path) rel_path = "";
if (rel_path[0] == '/') 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 */ 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++; if (rel_path[0] == '/') rel_path++;
/* Only limine.conf can be deleted */ /* Only limine.conf can be deleted */
if (k_strcmp(rel_path, "limine.conf") != 0) { if (strcmp(rel_path, "limine.conf") != 0) {
return false; 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++; if (new_rel[0] == '/') new_rel++;
/* Only limine.conf can be renamed */ /* Only limine.conf can be renamed */
if (k_strcmp(old_rel, "limine.conf") != 0) { if (strcmp(old_rel, "limine.conf") != 0) {
return false; return false;
} }
/* kernel and initrd are protected */ /* 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; return false;
} }
/* metadata directory is protected */ /* metadata directory is protected */
if (k_strncmp(new_rel, "metadata", 8) == 0) { if (strncmp(new_rel, "metadata", 8) == 0) {
return false; return false;
} }
extern bool vfs_rename(const char *old_path, const char *new_path); extern bool vfs_rename(const char *old_path, const char *new_path);
char new_partition_path[256]; char new_partition_path[256];
k_strcpy(new_partition_path, "/"); strcpy(new_partition_path, "/");
/* Manually append new_rel to new_partition_path */ /* Manually append new_rel to new_partition_path */
int path_len = 0; int path_len = 0;
@ -442,7 +442,7 @@ static bool bootfs_rename(void *fs_private, const char *old_path, const char *ne
return false; 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 */ /* Rename on partition filesystem */
bool result = vfs_rename("/limine.conf", new_partition_path); 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 (rel_path[0] == '\0') return true;
if (k_strcmp(rel_path, "limine.conf") == 0) return true; if (strcmp(rel_path, "limine.conf") == 0) return true;
if (k_strcmp(rel_path, "efi") == 0) return true; if (strcmp(rel_path, "efi") == 0) return true;
if (k_strcmp(rel_path, "kernel") == 0) return true; if (strcmp(rel_path, "kernel") == 0) return true;
if (k_strcmp(rel_path, "initrd") == 0) return true; if (strcmp(rel_path, "initrd") == 0) return true;
if (k_strcmp(rel_path, "initrd.tar") == 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 (is_metadata_file(rel_path)) return true;
if (bootfs_find_custom(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] == '/') rel_path++;
if (rel_path[0] == '\0') return true; if (rel_path[0] == '\0') return true;
if (k_strcmp(rel_path, "efi") == 0) return true; if (strcmp(rel_path, "efi") == 0) return true;
if (k_strcmp(rel_path, "metadata") == 0) return true; if (strcmp(rel_path, "metadata") == 0) return true;
return false; 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) rel_path = "";
if (rel_path[0] == '/') 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') { if (rel_path[0] == '\0') {
k_strcpy(info->name, "/"); strcpy(info->name, "/");
info->is_directory = 1; info->is_directory = 1;
return 0; return 0;
} }
if (k_strcmp(rel_path, "limine.conf") == 0) { if (strcmp(rel_path, "limine.conf") == 0) {
k_strcpy(info->name, "limine.conf"); strcpy(info->name, "limine.conf");
info->size = g_bootfs_state.limine_conf_len; info->size = g_bootfs_state.limine_conf_len;
info->is_directory = 0; info->is_directory = 0;
return 0; return 0;
} }
if (k_strcmp(rel_path, "kernel") == 0) { if (strcmp(rel_path, "kernel") == 0) {
k_strcpy(info->name, "kernel"); strcpy(info->name, "kernel");
info->size = g_bootfs_state.kernel_size; info->size = g_bootfs_state.kernel_size;
info->is_directory = 0; info->is_directory = 0;
return 0; return 0;
} else if (k_strcmp(rel_path, "initrd") == 0) { } else if (strcmp(rel_path, "initrd") == 0) {
k_strcpy(info->name, "initrd"); strcpy(info->name, "initrd");
info->size = g_bootfs_state.initrd_size; info->size = g_bootfs_state.initrd_size;
info->is_directory = 0; info->is_directory = 0;
return 0; return 0;
} else if (k_strcmp(rel_path, "initrd.tar") == 0) { } else if (strcmp(rel_path, "initrd.tar") == 0) {
k_strcpy(info->name, "initrd.tar"); strcpy(info->name, "initrd.tar");
info->size = g_bootfs_state.initrd_size; info->size = g_bootfs_state.initrd_size;
info->is_directory = 0; info->is_directory = 0;
return 0; return 0;
} else if (k_strcmp(rel_path, "metadata") == 0) { } else if (strcmp(rel_path, "metadata") == 0) {
k_strcpy(info->name, "metadata"); strcpy(info->name, "metadata");
info->is_directory = 1; info->is_directory = 1;
return 0; return 0;
} else if (k_strcmp(rel_path, "efi") == 0) { } else if (strcmp(rel_path, "efi") == 0) {
k_strcpy(info->name, "efi"); strcpy(info->name, "efi");
info->is_directory = 1; info->is_directory = 1;
return 0; 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)) { if (is_metadata_file(rel_path)) {
char temp_buf[4096]; char temp_buf[4096];
int len = generate_metadata_content(rel_path, 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->size = len;
info->is_directory = 0; info->is_directory = 0;
return 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); bootfs_custom_file_t *cf = bootfs_find_custom(rel_path);
if (cf) { if (cf) {
k_strcpy(info->name, cf->name); strcpy(info->name, cf->name);
info->size = cf->size; info->size = cf->size;
info->is_directory = 0; info->is_directory = 0;
return 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; bootfs_handle_t *h = (bootfs_handle_t*)file_handle;
if (!h) return 0; 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; 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; 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; 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; return g_bootfs_state.initrd_size;
} else if (is_metadata_file(h->path)) { } else if (is_metadata_file(h->path)) {
char temp_buf[4096]; char temp_buf[4096];
@ -589,10 +589,10 @@ vfs_fs_ops_t* bootfs_get_ops(void) {
} }
void bootfs_state_init(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"); strcpy(g_bootfs_state.bootloader_name, "Limine");
k_strcpy(g_bootfs_state.bootloader_version, "6.0.0"); strcpy(g_bootfs_state.bootloader_version, "6.0.0");
g_bootfs_state.limine_conf[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"); vfs_file_t *boot_conf = vfs_open("/boot/efi/limine.conf", "r");
if (boot_conf) { if (boot_conf) {
k_strcpy(g_limine_conf_path, "/boot/efi/limine.conf"); strcpy(g_limine_conf_path, "/boot/efi/limine.conf");
} else { } else {
boot_conf = vfs_open("/limine.conf", "r"); boot_conf = vfs_open("/limine.conf", "r");
if (boot_conf) { 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++; if (path[0] == '/') path++;
procfs_handle_t *h = (procfs_handle_t*)kmalloc(sizeof(procfs_handle_t)); 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; h->offset = 0;
if (path[0] == '\0') { if (path[0] == '\0') {
@ -33,10 +33,10 @@ void* procfs_open(void *fs_private, const char *path, const char *mode) {
i++; i++;
} }
pid_str[i] = 0; pid_str[i] = 0;
h->pid = k_atoi(pid_str); h->pid = atoi(pid_str);
if (path[i] == '/') { if (path[i] == '/') {
k_strcpy(h->type, path + i + 1); strcpy(h->type, path + i + 1);
} else { } else {
h->type[0] = 0; h->type[0] = 0;
} }
@ -44,7 +44,7 @@ void* procfs_open(void *fs_private, const char *path, const char *mode) {
} }
h->pid = 0xFFFFFFFF; h->pid = 0xFFFFFFFF;
k_strcpy(h->type, path); strcpy(h->type, path);
return h; return h;
} }
@ -61,33 +61,33 @@ int procfs_read(void *fs_private, void *handle, void *buf, int size) {
out[0] = 0; out[0] = 0;
if (h->pid == 0xFFFFFFFF) { 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); extern void get_os_info(os_info_t *info);
os_info_t info; os_info_t info;
get_os_info(&info); get_os_info(&info);
k_strcpy(out, info.os_name); strcpy(out, info.os_name);
k_strcpy(out + k_strlen(out), " ["); strcpy(out + strlen(out), " [");
k_strcpy(out + k_strlen(out), info.os_codename); strcpy(out + strlen(out), info.os_codename);
k_strcpy(out + k_strlen(out), "] Version "); strcpy(out + strlen(out), "] Version ");
k_strcpy(out + k_strlen(out), info.os_version); strcpy(out + strlen(out), info.os_version);
k_strcpy(out + k_strlen(out), "\nKernel: "); strcpy(out + strlen(out), "\nKernel: ");
k_strcpy(out + k_strlen(out), info.kernel_name); strcpy(out + strlen(out), info.kernel_name);
k_strcpy(out + k_strlen(out), " "); strcpy(out + strlen(out), " ");
k_strcpy(out + k_strlen(out), info.kernel_version); strcpy(out + strlen(out), info.kernel_version);
k_strcpy(out + k_strlen(out), "\nBuild: "); strcpy(out + strlen(out), "\nBuild: ");
k_strcpy(out + k_strlen(out), info.build_date); strcpy(out + strlen(out), info.build_date);
k_strcpy(out + k_strlen(out), " "); strcpy(out + strlen(out), " ");
k_strcpy(out + k_strlen(out), info.build_time); strcpy(out + strlen(out), info.build_time);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
} else if (k_strcmp(h->type, "uptime") == 0) { } else if (strcmp(h->type, "uptime") == 0) {
extern uint32_t wm_get_ticks(void); extern uint32_t wm_get_ticks(void);
uint32_t ticks = wm_get_ticks(); uint32_t ticks = wm_get_ticks();
k_itoa(ticks / 60, out); itoa(ticks / 60, out);
k_strcpy(out + k_strlen(out), " seconds\nRaw_Ticks:"); strcpy(out + strlen(out), " seconds\nRaw_Ticks:");
char t_s[16]; k_itoa(ticks, t_s); char t_s[16]; itoa(ticks, t_s);
k_strcpy(out + k_strlen(out), t_s); strcpy(out + strlen(out), t_s);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
} else if (k_strcmp(h->type, "cpuinfo") == 0) { } else if (strcmp(h->type, "cpuinfo") == 0) {
extern uint32_t smp_cpu_count(void); extern uint32_t smp_cpu_count(void);
extern void platform_get_cpu_model(char *model); extern void platform_get_cpu_model(char *model);
extern void platform_get_cpu_vendor(char *vendor); 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++) { for (uint32_t i = 0; i < cpu_count; i++) {
char buf[32]; char buf[32];
k_strcpy(out + k_strlen(out), "processor\t: "); strcpy(out + strlen(out), "processor\t: ");
k_itoa(i, buf); itoa(i, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "vendor_id\t: "); strcpy(out + strlen(out), "vendor_id\t: ");
k_strcpy(out + k_strlen(out), vendor); strcpy(out + strlen(out), vendor);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cpu family\t: "); strcpy(out + strlen(out), "cpu family\t: ");
k_itoa(info.family, buf); itoa(info.family, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "model\t\t: "); strcpy(out + strlen(out), "model\t\t: ");
k_itoa(info.model, buf); itoa(info.model, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "model name\t: "); strcpy(out + strlen(out), "model name\t: ");
k_strcpy(out + k_strlen(out), model); strcpy(out + strlen(out), model);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "stepping\t: "); strcpy(out + strlen(out), "stepping\t: ");
k_itoa(info.stepping, buf); itoa(info.stepping, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "microcode\t: 0x"); strcpy(out + strlen(out), "microcode\t: 0x");
char hex[16]; char hex[16];
int temp = info.microcode; int temp = info.microcode;
int hex_pos = 0; 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++] = digit < 10 ? '0' + digit : 'a' + (digit - 10);
} }
hex[hex_pos] = '\0'; hex[hex_pos] = '\0';
k_strcpy(out + k_strlen(out), hex); strcpy(out + strlen(out), hex);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cache size\t: "); strcpy(out + strlen(out), "cache size\t: ");
k_itoa(info.cache_size, buf); itoa(info.cache_size, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), " KB\n"); strcpy(out + strlen(out), " KB\n");
k_strcpy(out + k_strlen(out), "physical id\t: 0\n"); strcpy(out + strlen(out), "physical id\t: 0\n");
k_strcpy(out + k_strlen(out), "siblings\t: "); strcpy(out + strlen(out), "siblings\t: ");
k_itoa(cpu_count, buf); itoa(cpu_count, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "core id\t\t: "); strcpy(out + strlen(out), "core id\t\t: ");
k_itoa(i, buf); itoa(i, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "cpu cores\t: "); strcpy(out + strlen(out), "cpu cores\t: ");
k_itoa(cpu_count, buf); itoa(cpu_count, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "apicid\t\t: "); strcpy(out + strlen(out), "apicid\t\t: ");
k_itoa(i, buf); itoa(i, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "initial apicid\t: "); strcpy(out + strlen(out), "initial apicid\t: ");
k_itoa(i, buf); itoa(i, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "fpu\t\t: yes\n"); strcpy(out + strlen(out), "fpu\t\t: yes\n");
k_strcpy(out + k_strlen(out), "fpu_exception\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: "); strcpy(out + strlen(out), "flags\t\t: ");
k_strcpy(out + k_strlen(out), flags); strcpy(out + strlen(out), flags);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "bugs\t\t: \n"); strcpy(out + strlen(out), "bugs\t\t: \n");
k_strcpy(out + k_strlen(out), "bogomips\t: 4800.00\n"); strcpy(out + strlen(out), "bogomips\t: 4800.00\n");
if (i < cpu_count - 1) { 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); 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; int y, m, d, h_val, min, s;
rtc_get_datetime(&y, &m, &d, &h_val, &min, &s); rtc_get_datetime(&y, &m, &d, &h_val, &min, &s);
char buf[16]; char buf[16];
k_itoa(y, buf); itoa(y, buf);
k_strcpy(out, buf); strcpy(out, buf);
k_strcpy(out + k_strlen(out), "-"); strcpy(out + strlen(out), "-");
if (m < 10) k_strcpy(out + k_strlen(out), "0"); if (m < 10) strcpy(out + strlen(out), "0");
k_itoa(m, buf); itoa(m, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "-"); strcpy(out + strlen(out), "-");
if (d < 10) k_strcpy(out + k_strlen(out), "0"); if (d < 10) strcpy(out + strlen(out), "0");
k_itoa(d, buf); itoa(d, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), " "); strcpy(out + strlen(out), " ");
if (h_val < 10) k_strcpy(out + k_strlen(out), "0"); if (h_val < 10) strcpy(out + strlen(out), "0");
k_itoa(h_val, buf); itoa(h_val, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), ":"); strcpy(out + strlen(out), ":");
if (min < 10) k_strcpy(out + k_strlen(out), "0"); if (min < 10) strcpy(out + strlen(out), "0");
k_itoa(min, buf); itoa(min, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), ":"); strcpy(out + strlen(out), ":");
if (s < 10) k_strcpy(out + k_strlen(out), "0"); if (s < 10) strcpy(out + strlen(out), "0");
k_itoa(s, buf); itoa(s, buf);
k_strcpy(out + k_strlen(out), buf); strcpy(out + strlen(out), buf);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
} else if (k_strcmp(h->type, "meminfo") == 0) { } else if (strcmp(h->type, "meminfo") == 0) {
extern MemStats memory_get_stats(void); extern MemStats memory_get_stats(void);
MemStats stats = memory_get_stats(); MemStats stats = memory_get_stats();
char m_s[32]; char m_s[32];
k_strcpy(out, "MemTotal:\t"); strcpy(out, "MemTotal:\t");
k_itoa(stats.total_memory / 1024, m_s); itoa(stats.total_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n"); strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "MemFree:\t"); strcpy(out + strlen(out), "MemFree:\t");
k_itoa(stats.available_memory / 1024, m_s); itoa(stats.available_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n"); strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "MemAvailable:\t"); strcpy(out + strlen(out), "MemAvailable:\t");
k_itoa(stats.available_memory / 1024, m_s); itoa(stats.available_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n"); strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "Buffers:\t0 kB\n"); strcpy(out + strlen(out), "Buffers:\t0 kB\n");
k_strcpy(out + k_strlen(out), "Cached:\t\t0 kB\n"); strcpy(out + strlen(out), "Cached:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "MemUsed:\t"); strcpy(out + strlen(out), "MemUsed:\t");
k_itoa(stats.used_memory / 1024, m_s); itoa(stats.used_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n"); strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "MemPeak:\t"); strcpy(out + strlen(out), "MemPeak:\t");
k_itoa(stats.peak_memory_used / 1024, m_s); itoa(stats.peak_memory_used / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n"); strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "SwapTotal:\t0 kB\n"); strcpy(out + strlen(out), "SwapTotal:\t0 kB\n");
k_strcpy(out + k_strlen(out), "SwapFree:\t0 kB\n"); strcpy(out + strlen(out), "SwapFree:\t0 kB\n");
k_strcpy(out + k_strlen(out), "Dirty:\t\t0 kB\n"); strcpy(out + strlen(out), "Dirty:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "Writeback:\t0 kB\n"); strcpy(out + strlen(out), "Writeback:\t0 kB\n");
k_strcpy(out + k_strlen(out), "AnonPages:\t"); strcpy(out + strlen(out), "AnonPages:\t");
k_itoa(stats.used_memory / 1024, m_s); itoa(stats.used_memory / 1024, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), " kB\n"); strcpy(out + strlen(out), " kB\n");
k_strcpy(out + k_strlen(out), "Mapped:\t\t0 kB\n"); strcpy(out + strlen(out), "Mapped:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "Shmem:\t\t0 kB\n"); strcpy(out + strlen(out), "Shmem:\t\t0 kB\n");
k_strcpy(out + k_strlen(out), "Blocks:\t\t"); strcpy(out + strlen(out), "Blocks:\t\t");
k_itoa(stats.allocated_blocks, m_s); itoa(stats.allocated_blocks, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "FreeBlocks:\t"); strcpy(out + strlen(out), "FreeBlocks:\t");
k_itoa(stats.free_blocks, m_s); itoa(stats.free_blocks, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
k_strcpy(out + k_strlen(out), "Fragmentation:\t"); strcpy(out + strlen(out), "Fragmentation:\t");
k_itoa(stats.fragmentation_percent, m_s); itoa(stats.fragmentation_percent, m_s);
k_strcpy(out + k_strlen(out), m_s); strcpy(out + strlen(out), m_s);
k_strcpy(out + k_strlen(out), "%\n"); strcpy(out + strlen(out), "%\n");
} else if (k_strcmp(h->type, "devices") == 0) { } else if (strcmp(h->type, "devices") == 0) {
extern int disk_get_count(void); extern int disk_get_count(void);
extern Disk* disk_get_by_index(int index); extern Disk* disk_get_by_index(int index);
int dcount = disk_get_count(); int dcount = disk_get_count();
out[0] = '\0'; out[0] = '\0';
k_strcpy(out, "Character devices:\n"); strcpy(out, "Character devices:\n");
k_strcpy(out + k_strlen(out), " 1 mem\n"); strcpy(out + strlen(out), " 1 mem\n");
k_strcpy(out + k_strlen(out), " 4 tty\n"); strcpy(out + strlen(out), " 4 tty\n");
k_strcpy(out + k_strlen(out), " 5 cua\n"); strcpy(out + strlen(out), " 5 cua\n");
k_strcpy(out + k_strlen(out), " 7 vcs\n"); strcpy(out + strlen(out), " 7 vcs\n");
k_strcpy(out + k_strlen(out), " 8 stdin\n"); strcpy(out + strlen(out), " 8 stdin\n");
k_strcpy(out + k_strlen(out), " 13 input\n"); strcpy(out + strlen(out), " 13 input\n");
k_strcpy(out + k_strlen(out), " 14 sound\n"); strcpy(out + strlen(out), " 14 sound\n");
k_strcpy(out + k_strlen(out), " 29 fb\n"); strcpy(out + strlen(out), " 29 fb\n");
k_strcpy(out + k_strlen(out), "189 usb\n\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++) { for (int i = 0; i < dcount; i++) {
Disk *d = disk_get_by_index(i); Disk *d = disk_get_by_index(i);
if (d && !d->is_partition) { if (d && !d->is_partition) {
k_strcpy(out + k_strlen(out), " 8 "); strcpy(out + strlen(out), " 8 ");
k_strcpy(out + k_strlen(out), d->devname); strcpy(out + strlen(out), d->devname);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
} }
} }
k_strcpy(out + k_strlen(out), " 11 sr\n"); strcpy(out + strlen(out), " 11 sr\n");
k_strcpy(out + k_strlen(out), "253 virtblk\n"); strcpy(out + strlen(out), "253 virtblk\n");
} }
} }
else { else {
process_t *proc = process_get_by_pid(h->pid); process_t *proc = process_get_by_pid(h->pid);
if (!proc) { kfree(out); return -1; } if (!proc) { kfree(out); return -1; }
if (k_strcmp(h->type, "name") == 0 || k_strcmp(h->type, "cmdline") == 0) { if (strcmp(h->type, "name") == 0 || strcmp(h->type, "cmdline") == 0) {
k_strcpy(out, proc->name); strcpy(out, proc->name);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
} else if (k_strcmp(h->type, "cwd") == 0) { } else if (strcmp(h->type, "cwd") == 0) {
k_strcpy(out, proc->cwd); strcpy(out, proc->cwd);
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
} else if (k_strcmp(h->type, "status") == 0) { } else if (strcmp(h->type, "status") == 0) {
k_strcpy(out, "Name: "); strcpy(out, "Name: ");
k_strcpy(out + k_strlen(out), proc->name); strcpy(out + strlen(out), proc->name);
k_strcpy(out + k_strlen(out), "\nPID: "); strcpy(out + strlen(out), "\nPID: ");
char pid_s[16]; k_itoa(proc->pid, pid_s); char pid_s[16]; itoa(proc->pid, pid_s);
k_strcpy(out + k_strlen(out), pid_s); strcpy(out + strlen(out), pid_s);
k_strcpy(out + k_strlen(out), "\nState: RUNNING\nMemory: "); strcpy(out + strlen(out), "\nState: RUNNING\nMemory: ");
uint64_t mem_val = proc->used_memory; uint64_t mem_val = proc->used_memory;
if (h->pid == 0) { if (h->pid == 0) {
extern MemStats memory_get_stats(void); extern MemStats memory_get_stats(void);
mem_val = memory_get_stats().used_memory; mem_val = memory_get_stats().used_memory;
} }
char mem_s[32]; k_itoa(mem_val / 1024, mem_s); char mem_s[32]; itoa(mem_val / 1024, mem_s);
k_strcpy(out + k_strlen(out), mem_s); strcpy(out + strlen(out), mem_s);
k_strcpy(out + k_strlen(out), " KB\nTicks: "); strcpy(out + strlen(out), " KB\nTicks: ");
char tick_s[32]; k_itoa(proc->ticks, tick_s); char tick_s[32]; itoa(proc->ticks, tick_s);
k_strcpy(out + k_strlen(out), tick_s); strcpy(out + strlen(out), tick_s);
k_strcpy(out + k_strlen(out), "\nIdle: "); strcpy(out + strlen(out), "\nIdle: ");
k_strcpy(out + k_strlen(out), proc->is_idle ? "1" : "0"); strcpy(out + strlen(out), proc->is_idle ? "1" : "0");
k_strcpy(out + k_strlen(out), "\n"); strcpy(out + strlen(out), "\n");
} }
} }
int len = k_strlen(out); int len = strlen(out);
if (h->offset >= len) { kfree(out); return 0; } if (h->offset >= len) { kfree(out); return 0; }
int to_copy = len - h->offset; int to_copy = len - h->offset;
if (to_copy > size) to_copy = size; 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; h->offset += to_copy;
kfree(out); kfree(out);
return to_copy; 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; procfs_handle_t *h = (procfs_handle_t*)handle;
if (!h || h->pid == 0xFFFFFFFF) return -1; if (!h || h->pid == 0xFFFFFFFF) return -1;
if (k_strcmp(h->type, "signal") == 0) { if (strcmp(h->type, "signal") == 0) {
char cmd[16]; char cmd[16];
int to_copy = size < 15 ? size : 15; int to_copy = size < 15 ? size : 15;
k_memcpy(cmd, buf, to_copy); memcpy(cmd, buf, to_copy);
cmd[to_copy] = 0; 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); process_t *proc = process_get_by_pid(h->pid);
if (proc && proc->pid != 0) { if (proc && proc->pid != 0) {
process_terminate(proc); 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') { if (path[0] == '\0') {
int out = 0; int out = 0;
k_strcpy(entries[out++].name, "version"); strcpy(entries[out++].name, "version");
entries[out-1].is_directory = 0; entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "uptime"); strcpy(entries[out++].name, "uptime");
entries[out-1].is_directory = 0; entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "cpuinfo"); strcpy(entries[out++].name, "cpuinfo");
entries[out-1].is_directory = 0; entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "meminfo"); strcpy(entries[out++].name, "meminfo");
entries[out-1].is_directory = 0; entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "datetime"); strcpy(entries[out++].name, "datetime");
entries[out-1].is_directory = 0; entries[out-1].is_directory = 0;
k_strcpy(entries[out++].name, "devices"); strcpy(entries[out++].name, "devices");
entries[out-1].is_directory = 0; entries[out-1].is_directory = 0;
extern process_t processes[]; extern process_t processes[];
for (int i = 0; i < 16 && out < max; i++) { for (int i = 0; i < 16 && out < max; i++) {
if (processes[i].pid != 0xFFFFFFFF) { 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].is_directory = 1;
entries[out].size = 0; entries[out].size = 0;
out++; 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') { if (path[0] >= '0' && path[0] <= '9') {
int out = 0; int out = 0;
k_strcpy(entries[out++].name, "name"); strcpy(entries[out++].name, "name");
k_strcpy(entries[out++].name, "status"); strcpy(entries[out++].name, "status");
k_strcpy(entries[out++].name, "cmdline"); strcpy(entries[out++].name, "cmdline");
k_strcpy(entries[out++].name, "cwd"); strcpy(entries[out++].name, "cwd");
k_strcpy(entries[out++].name, "signal"); strcpy(entries[out++].name, "signal");
for(int i=0; i<out; i++) entries[i].is_directory = 0; for(int i=0; i<out; i++) entries[i].is_directory = 0;
return out; return out;
} }
@ -442,13 +442,13 @@ bool procfs_exists(void *fs_private, const char *path) {
i++; i++;
} }
pid_str[i] = 0; 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 (process_get_by_pid(pid)) return true;
} }
if (k_strcmp(path, "version") == 0 || k_strcmp(path, "uptime") == 0) return true; if (strcmp(path, "version") == 0 || strcmp(path, "uptime") == 0) return true;
if (k_strcmp(path, "cpuinfo") == 0 || k_strcmp(path, "meminfo") == 0) return true; if (strcmp(path, "cpuinfo") == 0 || strcmp(path, "meminfo") == 0) return true;
if (k_strcmp(path, "datetime") == 0 || k_strcmp(path, "devices") == 0) return true; if (strcmp(path, "datetime") == 0 || strcmp(path, "devices") == 0) return true;
return false; 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) { if (last_slash != -1) {
char prefix[64]; char prefix[64];
k_memcpy(prefix, path, last_slash); memcpy(prefix, path, last_slash);
prefix[last_slash] = 0; prefix[last_slash] = 0;
sub = subsystem_get_by_name(prefix); sub = subsystem_get_by_name(prefix);
if (sub) { if (sub) {
const char *filename = path + last_slash + 1; const char *filename = path + last_slash + 1;
for (int j = 0; j < sub->file_count; j++) { 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)); sysfs_handle_t *h = (sysfs_handle_t*)kmalloc(sizeof(sysfs_handle_t));
h->sub = sub; h->sub = sub;
h->file = &sub->files[j]; 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) { if (exact_sub) {
for (int i = 0; i < exact_sub->file_count && out < max; i++) { 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].is_directory = 0;
entries[out].size = 0; entries[out].size = 0;
out++; 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 count = subsystem_get_count();
int path_len = k_strlen(path); int path_len = strlen(path);
for (int i = 0; i < count && out < max; i++) { for (int i = 0; i < count && out < max; i++) {
kernel_subsystem_t *s = subsystem_get_by_index(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); const char *sub_path = s->name + (path_len ? path_len + 1 : 0);
char comp[64]; char comp[64];
int j = 0; int j = 0;
@ -96,13 +96,13 @@ static int sysfs_readdir(void *fs_private, const char *path, vfs_dirent_t *entri
bool found = false; bool found = false;
for (int k = 0; k < out; k++) { for (int k = 0; k < out; k++) {
if (k_strcmp(entries[k].name, comp) == 0) { if (strcmp(entries[k].name, comp) == 0) {
found = true; found = true;
break; break;
} }
} }
if (!found) { if (!found) {
k_strcpy(entries[out].name, comp); strcpy(entries[out].name, comp);
entries[out].is_directory = 1; entries[out].is_directory = 1;
entries[out].size = 0; entries[out].size = 0;
out++; 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; for (int j = 0; path[j]; j++) if (path[j] == '/') last_slash = j;
if (last_slash != -1) { if (last_slash != -1) {
char prefix[64]; char prefix[64];
k_memcpy(prefix, path, last_slash); memcpy(prefix, path, last_slash);
prefix[last_slash] = 0; prefix[last_slash] = 0;
kernel_subsystem_t *sub = subsystem_get_by_name(prefix); kernel_subsystem_t *sub = subsystem_get_by_name(prefix);
if (sub) { if (sub) {
const char *filename = path + last_slash + 1; const char *filename = path + last_slash + 1;
for (int j = 0; j < sub->file_count; j++) { 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 count = subsystem_get_count();
int path_len = k_strlen(path); int path_len = strlen(path);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
kernel_subsystem_t *s = subsystem_get_by_index(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; 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; for (int j = 0; path[j]; j++) if (path[j] == '/') last_slash = j;
if (last_slash != -1) { if (last_slash != -1) {
char prefix[64]; char prefix[64];
k_memcpy(prefix, path, last_slash); memcpy(prefix, path, last_slash);
prefix[last_slash] = 0; prefix[last_slash] = 0;
kernel_subsystem_t *sub = subsystem_get_by_name(prefix); kernel_subsystem_t *sub = subsystem_get_by_name(prefix);
if (sub) { if (sub) {
const char *filename = path + last_slash + 1; const char *filename = path + last_slash + 1;
for (int j = 0; j < sub->file_count; j++) { 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 // Freelist head must be a kernel higher-half address. Treat anything below the conservative
// threshold 0xFFFF000000000000 as corruption (canonical boundary is 0xFFFF800000000000). // threshold 0xFFFF000000000000 as corruption (canonical boundary is 0xFFFF800000000000).
if ((uintptr_t)obj < 0xFFFF000000000000ULL) { 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="); serial_write("[SLAB] corrupt freelist cls=");
k_itoa_hex((uint64_t)cls, b); serial_write(b); itoa_hex((uint64_t)cls, b); serial_write(b);
serial_write(" page="); k_itoa_hex((uint64_t)page, b); serial_write(b); serial_write(" page="); itoa_hex((uint64_t)page, b); serial_write(b);
serial_write(" fl="); k_itoa_hex((uint64_t)obj, b); serial_write(b); serial_write(" fl="); itoa_hex((uint64_t)obj, b); serial_write(b);
serial_write("\n"); serial_write("\n");
// Remove the corrupted page from the list to avoid hitting it again // 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) { static void vm_reset(void) {
sp = 0; sp = 0;
k_memset(memory, 0, VM_MEMORY_SIZE); memset(memory, 0, VM_MEMORY_SIZE);
vm_heap_ptr = 8192; vm_heap_ptr = 8192;
} }
@ -167,7 +167,7 @@ static void vm_syscall(int id) {
case VM_SYS_STRLEN: { case VM_SYS_STRLEN: {
int addr = pop(); int addr = pop();
if (addr >= 0 && addr < VM_MEMORY_SIZE) { if (addr >= 0 && addr < VM_MEMORY_SIZE) {
push(k_strlen((char*)&memory[addr])); push(strlen((char*)&memory[addr]));
} else push(0); } else push(0);
break; break;
} }
@ -175,7 +175,7 @@ static void vm_syscall(int id) {
int a2 = pop(); int a2 = pop();
int a1 = pop(); int a1 = pop();
if (a1 >= 0 && a1 < VM_MEMORY_SIZE && a2 >= 0 && a2 < VM_MEMORY_SIZE) { 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); } else push(0);
break; break;
} }
@ -183,7 +183,7 @@ static void vm_syscall(int id) {
int src = pop(); int src = pop();
int dest = pop(); int dest = pop();
if (dest >= 0 && dest < VM_MEMORY_SIZE && src >= 0 && src < VM_MEMORY_SIZE) { 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); push(dest);
} else push(0); } else push(0);
break; break;
@ -198,7 +198,7 @@ static void vm_syscall(int id) {
int val = pop(); int val = pop();
int ptr = pop(); int ptr = pop();
if (ptr >= 0 && ptr + n <= VM_MEMORY_SIZE) { if (ptr >= 0 && ptr + n <= VM_MEMORY_SIZE) {
k_memset(&memory[ptr], val, n); memset(&memory[ptr], val, n);
push(ptr); push(ptr);
} else push(0); } else push(0);
break; break;
@ -322,7 +322,7 @@ static void vm_syscall(int id) {
case VM_SYS_ATOI: { case VM_SYS_ATOI: {
int addr = pop(); int addr = pop();
if (addr >= 0 && addr < VM_MEMORY_SIZE) { if (addr >= 0 && addr < VM_MEMORY_SIZE) {
push(k_atoi((char*)&memory[addr])); push(atoi((char*)&memory[addr]));
} else push(0); } else push(0);
break; break;
} }
@ -330,7 +330,7 @@ static void vm_syscall(int id) {
int addr = pop(); int addr = pop();
int val = pop(); int val = pop();
if (addr >= 0 && addr < VM_MEMORY_SIZE) { if (addr >= 0 && addr < VM_MEMORY_SIZE) {
k_itoa(val, (char*)&memory[addr]); itoa(val, (char*)&memory[addr]);
} }
push(0); push(0);
break; break;
@ -503,7 +503,7 @@ int vm_exec(const uint8_t *code, int code_size) {
} }
// Load program into memory at address 0 // 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]; for(int i=0; i<code_size; i++) memory[i] = code[i];
int pc = 8; // Skip header int pc = 8; // Skip header

View file

@ -92,10 +92,10 @@ int network_init(void) {
extern void serial_write(const char *str); extern void serial_write(const char *str);
serial_write("[NET] IP Assigned: "); serial_write("[NET] IP Assigned: ");
char buf[32]; char buf[32];
k_itoa(ip.bytes[0], buf); serial_write(buf); serial_write("."); itoa(ip.bytes[0], buf); serial_write(buf); serial_write(".");
k_itoa(ip.bytes[1], buf); serial_write(buf); serial_write("."); itoa(ip.bytes[1], buf); serial_write(buf); serial_write(".");
k_itoa(ip.bytes[2], buf); serial_write(buf); serial_write("."); 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[3], buf); serial_write(buf); serial_write("\n");
} else { } else {
extern void serial_write(const char *str); extern void serial_write(const char *str);
serial_write("[NET] DHCP Failed during init\n"); 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); extern void serial_write(const char *str);
serial_write("[E1000] MMIO Base (virt): 0x"); serial_write("[E1000] MMIO Base (virt): 0x");
char hex_buf[32]; 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(hex_buf);
serial_write("\n"); serial_write("\n");
uint32_t status_reg = e1000_read_reg(mmio_base, E1000_REG_STATUS); uint32_t status_reg = e1000_read_reg(mmio_base, E1000_REG_STATUS);
serial_write("[E1000] Status: 0x"); serial_write("[E1000] Status: 0x");
k_itoa_hex(status_reg, hex_buf); itoa_hex(status_reg, hex_buf);
serial_write(hex_buf); serial_write(hex_buf);
serial_write("\n"); serial_write("\n");
@ -69,7 +69,7 @@ int e1000_init(pci_device_t* pci_dev) {
serial_write("[E1000] MAC: "); serial_write("[E1000] MAC: ");
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
char buf[4]; 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); serial_write(buf);
if(i<5) serial_write(":"); 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_descriptors = tx_descriptors;
e1000_dev.tx_head = 0; e1000_dev.tx_head = 0;
e1000_dev.tx_tail = 0; e1000_dev.tx_tail = 0;
k_memset(tx_descriptors, 0, sizeof(tx_descriptors)); memset(tx_descriptors, 0, sizeof(tx_descriptors));
k_memset(tx_buffers, 0, sizeof(tx_buffers)); memset(tx_buffers, 0, sizeof(tx_buffers));
for (int i = 0; i < E1000_TX_RING_SIZE; i++) { for (int i = 0; i < E1000_TX_RING_SIZE; i++) {
e1000_dev.tx_buffers[i] = tx_buffers[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_descriptors = rx_descriptors;
e1000_dev.rx_head = 0; e1000_dev.rx_head = 0;
e1000_dev.rx_tail = E1000_RX_RING_SIZE - 1; e1000_dev.rx_tail = E1000_RX_RING_SIZE - 1;
k_memset(rx_descriptors, 0, sizeof(rx_descriptors)); memset(rx_descriptors, 0, sizeof(rx_descriptors));
k_memset(rx_buffers, 0, sizeof(rx_buffers)); memset(rx_buffers, 0, sizeof(rx_buffers));
for (int i = 0; i < E1000_RX_RING_SIZE; i++) { for (int i = 0; i < E1000_RX_RING_SIZE; i++) {
e1000_dev.rx_buffers[i] = rx_buffers[i]; e1000_dev.rx_buffers[i] = rx_buffers[i];
e1000_dev.rx_descriptors[i].buffer_addr = v2p((uint64_t)(uintptr_t)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); extern void serial_write(const char *str);
serial_write("[RTL8111] MMIO Base: 0x"); 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); rtl8111_outb(RTL8111_CR, RTL8111_CR_RST);
for (int i = 0; i < 100000; i++) { for (int i = 0; i < 100000; i++) {
@ -103,14 +103,14 @@ int rtl8111_init(pci_device_t* pci_dev) {
serial_write("[RTL8111] MAC: "); serial_write("[RTL8111] MAC: ");
for(int i=0; i<6; i++) { 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(":"); if(i<5) serial_write(":");
} }
serial_write("\n"); serial_write("\n");
rtl8111_outb(0x50, 0xC0); 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++) { for (int i = 0; i < RTL8111_NUM_RX_DESC; i++) {
uint64_t buf_phys = v2p((uint64_t)(uintptr_t)rx_buffers[i]); uint64_t buf_phys = v2p((uint64_t)(uintptr_t)rx_buffers[i]);
rx_desc[i].buf_addr = buf_phys; 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, (uint32_t)rx_ring_phys);
rtl8111_outl(RTL8111_RDSAR + 4, (uint32_t)(rx_ring_phys >> 32)); 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); 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, (uint32_t)tx_ring_phys);
rtl8111_outl(RTL8111_TDSAR + 4, (uint32_t)(tx_ring_phys >> 32)); 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); extern void serial_write(const char *str);
serial_write("[RTL8139] MMIO Base: 0x"); 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) // Power on (CONFIG1)
rtl8139_outb(RTL8139_CONFIG_1, 0x00); rtl8139_outb(RTL8139_CONFIG_1, 0x00);
@ -89,7 +89,7 @@ int rtl8139_init(pci_device_t* pci_dev) {
serial_write("[RTL8139] MAC: "); serial_write("[RTL8139] MAC: ");
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
char buf[4]; char buf[4];
k_itoa_hex(mac_addr[i], buf); itoa_hex(mac_addr[i], buf);
serial_write(buf); serial_write(buf);
if(i<5) serial_write(":"); 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; uintptr_t used_start = (avail_end + 4095) & ~4095;
vq->used = (struct vq_used*)used_start; 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) { 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); extern void serial_write(const char *str);
serial_write("[VIRTIO-NET] I/O Base: 0x"); 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); 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: "); serial_write("[VIRTIO-NET] MAC: ");
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
char buf[4]; char buf[4];
k_itoa_hex(mac_addr[i], buf); itoa_hex(mac_addr[i], buf);
serial_write(buf); serial_write(buf);
if(i<5) serial_write(":"); 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 head = tx_vq.last_avail_idx % (tx_vq.q_size / 2);
uint16_t d_idx = head * 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].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].len = sizeof(struct virtio_net_hdr);
tx_vq.desc[d_idx].flags = VRING_DESC_F_NEXT; tx_vq.desc[d_idx].flags = VRING_DESC_F_NEXT;

View file

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

View file

@ -1,78 +1,15 @@
#ifndef LWIP_STRING_H #ifndef LWIP_STRING_H
#define 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" #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 #endif

View file

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

View file

@ -52,19 +52,19 @@ uint64_t exception_handler_c(registers_t *regs) {
// Serial Mirror // Serial Mirror
serial_write("\n*** EXCEPTION ***\nVector: "); serial_write("\n*** EXCEPTION ***\nVector: ");
k_itoa_hex(vector, buf); itoa_hex(vector, buf);
serial_write("0x"); serial_write("0x");
serial_write(buf); serial_write(buf);
if ((regs->cs & 0x3) != 0) { if ((regs->cs & 0x3) != 0) {
serial_write("\n*** USER MODE EXCEPTION ***\nVector: 0x"); serial_write("\n*** USER MODE EXCEPTION ***\nVector: 0x");
k_itoa_hex(vector, buf); itoa_hex(vector, buf);
serial_write(buf); serial_write(buf);
serial_write("\nRIP: 0x"); serial_write("\nRIP: 0x");
k_itoa_hex(regs->rip, buf); itoa_hex(regs->rip, buf);
serial_write(buf); serial_write(buf);
serial_write("\nError Code: 0x"); serial_write("\nError Code: 0x");
k_itoa_hex(regs->err_code, buf); itoa_hex(regs->err_code, buf);
serial_write(buf); serial_write(buf);
serial_write("\nTerminating process.\n"); serial_write("\nTerminating process.\n");
@ -77,12 +77,12 @@ uint64_t exception_handler_c(registers_t *regs) {
// Kernel mode exception // Kernel mode exception
const char *name = (vector < 32) ? exception_messages[vector] : "Unknown Kernel 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("\nRIP: 0x"); itoa_hex(regs->rip, buf); serial_write(buf);
serial_write("\nErr: 0x"); k_itoa_hex(regs->err_code, buf); serial_write(buf); serial_write("\nErr: 0x"); itoa_hex(regs->err_code, buf); serial_write(buf);
if (vector == 14) { if (vector == 14) {
uint64_t cr2; uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(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"); serial_write("\n");
kernel_panic(regs, name); 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); process_t *ap_idle = process_create(NULL, false);
ap_idle->cpu_affinity = my_id; ap_idle->cpu_affinity = my_id;
ap_idle->is_idle = true; ap_idle->is_idle = true;
k_strcpy(ap_idle->name, "idle:"); strcpy(ap_idle->name, "idle:");
char id_s[8]; k_itoa(my_id, id_s); char id_s[8]; itoa(my_id, id_s);
k_strcpy(ap_idle->name + 5, id_s); strcpy(ap_idle->name + 5, id_s);
process_set_current_for_cpu(my_id, ap_idle); process_set_current_for_cpu(my_id, ap_idle);
asm volatile("sti"); asm volatile("sti");

View file

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

View file

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

View file

@ -5,7 +5,7 @@ CC = x86_64-elf-gcc
AS = nasm AS = nasm
LD = x86_64-elf-ld 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 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 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); int got = sys_tty_read_in(&ch, 1);
if (got <= 0) { if (got <= 0) {
// Throttle idle input polling to avoid pegging the CPU at 100% // Throttle idle input polling to avoid pegging the CPU at 100%
sleep(1); sleep(50);
continue; continue;
} }

View file

@ -25,6 +25,8 @@ int main(int argc, char **argv) {
printf("date - Print current date and time\n"); printf("date - Print current date and time\n");
printf("uptime - Print system uptime\n"); printf("uptime - Print system uptime\n");
printf("meminfo - Print memory information\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("lsblk - List block devices and partitions\n");
printf("cowsay [msg] - Fun cow says something\n"); printf("cowsay [msg] - Fun cow says something\n");
printf("beep - Make a beep sound\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); ui_mark_dirty(win, 0, 0, WINDOW_W, WINDOW_H);
} }
} else { } 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); ui_mark_dirty(win, 0, 0, win_w, win_h);
needs_repaint = 0; needs_repaint = 0;
} else { } else {
sys_yield(); sys_system(SYSTEM_CMD_SLEEP, 16, 0, 0, 0);
} }
} }
return 0; return 0;

View file

@ -54,7 +54,7 @@ int main(void) {
draw(win); draw(win);
ui_mark_dirty(win, 0, 0, WINDOW_W, WINDOW_H); ui_mark_dirty(win, 0, 0, WINDOW_W, WINDOW_H);
} else { } 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) { if (num == 0) {
str[0] = '0'; str[0] = '0';
str[1] = '\0'; str[1] = '\0';
@ -731,7 +731,7 @@ static void control_panel_paint_network(ui_window_t win) {
char b[4]; char b[4];
mac_str[0] = 0; mac_str[0] = 0;
for (int i=0; i<6; i++) { 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 if (b[1] == 0) { b[1] = b[0]; b[0] = '0'; b[2] = 0; } // zero pad
strcat(mac_str, b); strcat(mac_str, b);
if (i < 5) strcat(mac_str, ":"); if (i < 5) strcat(mac_str, ":");

View file

@ -5,6 +5,7 @@
#include "syscall.h" #include "syscall.h"
#include "libui.h" #include "libui.h"
#include "stdlib.h" #include "stdlib.h"
#include "libwidget.h"
#define COLOR_DARK_BG 0xFF121212 #define COLOR_DARK_BG 0xFF121212
#define COLOR_DARK_PANEL 0xFF1E1E1E #define COLOR_DARK_PANEL 0xFF1E1E1E
@ -20,7 +21,7 @@
#define GRAPH_POINTS 60 #define GRAPH_POINTS 60
static ui_window_t win_taskman; static ui_window_t win_taskman;
static ProcessInfo proc_list[32]; static ProcessInfo proc_list[64];
static int proc_count = 0; static int proc_count = 0;
static int selected_proc = -1; 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 char cpu_model_name[64] = "Unknown CPU";
static int cpu_cores = 1; 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) { static int find_value(const char *buf, const char *key) {
char *p = (char*)buf; char *p = (char*)buf;
int key_len = strlen(key); int key_len = strlen(key);
while (*p) { while (*p) {
if (memcmp(p, key, key_len) == 0 && p[key_len] == ':') { if (memcmp(p, key, key_len) == 0) {
p += key_len + 1; char *tp = p + key_len;
while (*p == ' ') p++; while (*tp == ' ' || *tp == '\t') tp++;
return atoi(p); if (*tp == ':') {
tp++;
while (*tp == ' ' || *tp == '\t') tp++;
return atoi(tp);
}
} }
while (*p && *p != '\n') p++; while (*p && *p != '\n') p++;
if (*p == '\n') p++; if (*p == '\n') p++;
@ -55,16 +91,20 @@ static void find_string(const char *buf, const char *key, char *out, int max_len
char *p = (char*)buf; char *p = (char*)buf;
int key_len = strlen(key); int key_len = strlen(key);
while (*p) { while (*p) {
if (memcmp(p, key, key_len) == 0 && p[key_len] == ':') { if (memcmp(p, key, key_len) == 0) {
p += key_len + 1; char *tp = p + key_len;
while (*p == ' ') p++; while (*tp == ' ' || *tp == '\t') tp++;
if (*tp == ':') {
tp++;
while (*tp == ' ' || *tp == '\t') tp++;
int i = 0; int i = 0;
while (*p && *p != '\n' && i < max_len - 1) { while (*tp && *tp != '\n' && i < max_len - 1) {
out[i++] = *p++; out[i++] = *tp++;
} }
out[i] = 0; out[i] = 0;
return; return;
} }
}
while (*p && *p != '\n') p++; while (*p && *p != '\n') p++;
if (*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) { static void update_proc_list(void) {
FAT32_FileInfo entries[64]; FAT32_FileInfo entries[128];
int count = sys_list("/proc", entries, 64); int count = sys_list("/proc", entries, 128);
if (count < 0) return; if (count < 0) return;
proc_count = 0; proc_count = 0;
@ -105,18 +145,20 @@ static void update_proc_list(void) {
sys_close(fd); sys_close(fd);
if (bytes > 0) { if (bytes > 0) {
buf[bytes] = 0; buf[bytes] = 0;
uint64_t ticks = (uint64_t)find_value(buf, "Ticks");
bool is_idle = find_value(buf, "Idle") == 1;
total_ticks_now += ticks;
if (proc_count < 64 && !is_idle) {
proc_list[proc_count].pid = pid; proc_list[proc_count].pid = pid;
find_string(buf, "Name", proc_list[proc_count].name, 64); 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].used_memory = (size_t)find_value(buf, "Memory") * 1024;
uint64_t ticks = (uint64_t)find_value(buf, "Ticks");
proc_list[proc_count].ticks = ticks; proc_list[proc_count].ticks = ticks;
total_ticks_now += ticks; proc_list[proc_count].is_idle = is_idle;
user_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++; proc_count++;
if (proc_count >= 32) break; }
} }
} }
} }
@ -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, 60, 125, "NAME", COLOR_DIM_TEXT);
ui_draw_string(win_taskman, 250, 125, "MEMORY", COLOR_DIM_TEXT); ui_draw_string(win_taskman, 250, 125, "MEMORY", COLOR_DIM_TEXT);
// Process Rows
int row = 0; int list_x = 10;
for (int i = 0; i < proc_count && row < MAX_VISIBLE_PROCS; i++) { 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; if (proc_list[i].pid == 0xFFFFFFFF) continue;
int ry = 150 + row * 26; int ry = list_y + (i * row_h) - scroll_offset;
uint32_t bg = (selected_proc == row) ? 0xFF334455 : COLOR_DARK_PANEL;
ui_draw_rounded_rect_filled(win_taskman, 10, ry, 380, 24, 4, bg); 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]; char pid_str[16];
itoa(proc_list[i].pid, pid_str); 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]; char name_disp[28];
if (strlen(proc_list[i].name) > 22) { if (strlen(proc_list[i].name) > 22) {
@ -288,13 +351,11 @@ static void draw_taskman(void) {
} else { } else {
strcpy(name_disp, proc_list[i].name); 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]; char m_str[32];
format_mem_smart(proc_list[i].used_memory, m_str); format_mem_smart(proc_list[i].used_memory, m_str);
ui_draw_string(win_taskman, 255, ry + 6, m_str, COLOR_DARK_TEXT); ui_draw_string(win_taskman, list_x + 245, ry + 6, m_str, COLOR_DARK_TEXT);
row++;
} }
// Kill button (Positioned relative to window height) // Kill button (Positioned relative to window height)
@ -329,6 +390,18 @@ static void draw_taskman(void) {
int main(void) { int main(void) {
win_taskman = ui_window_create("Task Manager", 100, 100, 400, 480); 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"); int fd_c = sys_open("/proc/cpuinfo", "r");
if (fd_c >= 0) { if (fd_c >= 0) {
char buf[1024]; char buf[1024];
@ -336,8 +409,8 @@ int main(void) {
sys_close(fd_c); sys_close(fd_c);
if (bytes > 0) { if (bytes > 0) {
buf[bytes] = 0; buf[bytes] = 0;
find_string(buf, "Processor", cpu_model_name, 64); find_string(buf, "model name", cpu_model_name, 64);
int cores = find_value(buf, "Cores"); int cores = find_value(buf, "cpu cores");
if (cores > 0) cpu_cores = cores; if (cores > 0) cpu_cores = cores;
} }
} }
@ -346,60 +419,76 @@ int main(void) {
gui_event_t ev; gui_event_t ev;
uint64_t last_update = 30; // Force update on start
while (1) { while (1) {
bool needs_redraw = false;
// Drain events // Drain events
while (ui_get_event(win_taskman, &ev)) { while (ui_get_event(win_taskman, &ev)) {
if (ev.type == GUI_EVENT_CLOSE) { if (ev.type == GUI_EVENT_CLOSE) {
sys_exit(0); 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 mx = ev.arg1;
int my = ev.arg2; int my = ev.arg2;
bool clicked = (ev.type == GUI_EVENT_CLICK);
bool down = (ev.type == GUI_EVENT_MOUSE_DOWN);
if (mx >= 10 && mx < 390 && my >= 150 && my < 150 + MAX_VISIBLE_PROCS * 26) { // Handle scrollbar
int idx = (my - 150) / 26; if (widget_scrollbar_handle_mouse(&proc_sb, mx, my, down, NULL)) {
int valid_count = 0; needs_redraw = true;
int target_i = -1; } else if (clicked) {
for (int i = 0; i < proc_count; i++) { // Handle process selection
if (proc_list[i].pid != 0xFFFFFFFF) { int list_x = 10;
if (valid_count == idx) { target_i = i; break; } int list_y = 150;
valid_count++; int list_h = 480 - 150 - 80;
} int row_h = 26;
}
if (target_i != -1) selected_proc = idx;
else selected_proc = -1;
draw_taskman(); if (mx >= list_x && mx < list_x + 380 && my >= list_y && my < list_y + list_h) {
ui_mark_dirty(win_taskman, 0, 0, 400, 480); int idx = (my - list_y + scroll_offset) / row_h;
if (idx >= 0 && idx < proc_count) {
selected_proc = idx;
} else {
selected_proc = -1;
}
needs_redraw = true;
} else if (mx >= 290 && mx < 390 && my >= 410 && my < 440) { } else if (mx >= 290 && mx < 390 && my >= 410 && my < 440) {
// Kill button
if (selected_proc != -1) { if (selected_proc != -1) {
int valid_count = 0; if (proc_list[selected_proc].pid != 0) sys_kill(proc_list[selected_proc].pid);
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++;
}
}
selected_proc = -1; selected_proc = -1;
update_proc_list(); update_proc_list();
draw_taskman(); needs_redraw = true;
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) { } else if (ev.type == GUI_EVENT_PAINT) {
draw_taskman(); needs_redraw = true;
ui_mark_dirty(win_taskman, 0, 0, 400, 480);
} }
} }
if (last_update++ >= 30) {
update_proc_list(); update_proc_list();
needs_redraw = true;
last_update = 0;
}
if (needs_redraw) {
draw_taskman(); draw_taskman();
ui_mark_dirty(win_taskman, 0, 0, 400, 480); ui_mark_dirty(win_taskman, 0, 0, 400, 480);
}
// Proper blocking sleep (200ms) sys_system(SYSTEM_CMD_SLEEP, 16, 0, 0, 0);
sys_system(SYSTEM_CMD_SLEEP, 200, 0, 0, 0);
} }
return 0; return 0;

View file

@ -793,6 +793,11 @@ static void draw_session(TerminalSession *s) {
int input_end = input_start + cmd_char_len; int input_end = input_start + cmd_char_len;
if (input_end > g_cols) input_end = g_cols; 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++) { for (int col = 0; col < g_cols; col++) {
uint32_t ch = ' '; uint32_t ch = ' ';
uint32_t color = s->fg_color; uint32_t color = s->fg_color;
@ -809,13 +814,28 @@ static void draw_session(TerminalSession *s) {
} }
} }
char out[5]; if (start_col == -1) {
int len = text_encode_utf8(ch, out); start_col = col;
out[len] = 0; 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);
int x = col * g_char_w; start_col = col;
int y = base_y + row * g_line_h; current_color = color;
ui_draw_string(g_win, x, y, out, 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) { if (dirty) {
draw_tabs(); draw_tabs();
draw_session(&g_tabs[g_active_tab]); draw_session(&g_tabs[g_active_tab]);
dirty = false;
} else { } 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; break;
} }
sys_yield(); sleep(1);
continue; continue;
} }
@ -193,7 +193,7 @@ static int _b_pipe_write(fd_handle_t *h, const void *buf, size_t count) {
} }
break; break;
} }
sys_yield(); sleep(1);
continue; continue;
} }

View file

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

View file

@ -363,7 +363,7 @@ int main(int argc, char **argv) {
connected = 0; connected = 0;
break; break;
} }
sys_yield(); sys_system(SYSTEM_CMD_SLEEP, 10, 0, 0, 0);
continue; 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 <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.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"); serial_str("[WALLPAPER] Failed to save setting\n");
return; return;
} }
fat32_write(fh, path, (uint32_t)k_strlen(path)); fat32_write(fh, path, (uint32_t)strlen(path));
fat32_close(fh); fat32_close(fh);
serial_str("[WALLPAPER] Setting saved: "); serial_str("[WALLPAPER] Setting saved: ");
serial_str(path); 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(); int mc = vfs_get_mount_count();
for (int i = 0; i < mc; i++) { for (int i = 0; i < mc; i++) {
vfs_mount_t *m = vfs_get_mount(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; return m->fs_private;
} }
} }
@ -152,7 +152,7 @@ static void rootfs_write_marker(void) {
FAT32_FileHandle *fh = fat32_open(ROOT_MARKER_PATH, "w"); FAT32_FileHandle *fh = fat32_open(ROOT_MARKER_PATH, "w");
if (!fh || !fh->valid) return; if (!fh || !fh->valid) return;
const char *msg = "boredos root\n"; 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); 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; if (!entry || !entry->filename) return false;
char full_path[192]; char full_path[192];
k_strcpy(full_path, DOCK_ICON_BASE_PATH); strcpy(full_path, DOCK_ICON_BASE_PATH);
k_strcpy(full_path + k_strlen(full_path), entry->filename); strcpy(full_path + strlen(full_path), entry->filename);
FAT32_FileHandle *fh = fat32_open(full_path, "r"); FAT32_FileHandle *fh = fat32_open(full_path, "r");
if (!fh) return false; 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_x = img_w - 1;
int img_max_y = img_h - 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 ty = 0; ty < DOCK_ICON_SIZE; ty++) {
for (int tx = 0; tx < DOCK_ICON_SIZE; tx++) { for (int tx = 0; tx < DOCK_ICON_SIZE; tx++) {
int sx = (DOCK_ICON_SIZE > 1) ? (tx * img_max_x) / (DOCK_ICON_SIZE - 1) : 0; 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); 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")) { if (len > 4 && str_ends_with(out_label, ".elf")) {
out_label[len - 4] = 0; out_label[len - 4] = 0;
} else if (len > 9 && str_ends_with(out_label, ".shortcut")) { } else if (len > 9 && str_ends_with(out_label, ".shortcut")) {
@ -1280,14 +1280,14 @@ static void dock_save_config(void) {
if (!fh) return; if (!fh) return;
const char *header = "v1\n"; 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++) { for (int i = 0; i < dock_item_count; i++) {
dock_write_int(fh, dock_items[i].icon_slot); dock_write_int(fh, dock_items[i].icon_slot);
fat32_write(fh, "|", 1); 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, "|", 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); 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) { if (msg_box_visible) {
ttf_font_t *_ttf = graphics_get_current_ttf(); 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 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)(k_strlen(msg_box_text) * 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 content_w = (title_w > text_w) ? title_w : text_w;
int padding = 30; // horizontal padding on each side int padding = 30; // horizontal padding on each side
int mw = content_w + padding * 2; int mw = content_w + padding * 2;