-I include $(SRC_DIR)
# Sparse: kernel-oriented semantic checker (type safety, NULL, bitwise vs logical)
-SPARSE_FLAGS := -m32 -D__i386__ -D__linux__ -Iinclude
+SPARSE_FLAGS := -m32 -D__i386__ -D__linux__ -Iinclude -Iinclude/net -Ithird_party/lwip/src/include
SPARSE_SRCS := $(filter-out $(wildcard $(SRC_DIR)/arch/arm/*.c) \
$(wildcard $(SRC_DIR)/arch/riscv/*.c) \
$(wildcard $(SRC_DIR)/arch/mips/*.c) \
void register_interrupt_handler(uint8_t n, isr_handler_t handler);
void unregister_interrupt_handler(uint8_t n, isr_handler_t handler);
+// Main ISR dispatch — called from assembly (interrupts.S)
+void isr_handler(struct registers* regs);
+
#endif
__asm__ volatile("mov %0, %%gs:12" : : "r"(proc) : "memory");
}
+/* GS selector lookup table indexed by LAPIC ID (used by interrupts.S). */
+extern uint16_t _percpu_gs_lut[256];
+
+/* Get percpu_data pointer for a specific CPU by index. */
+struct percpu_data* percpu_get_ptr(uint32_t cpu_index);
+
#endif
/* Get the current CPU's index (based on LAPIC ID). */
uint32_t smp_current_cpu(void);
+/* Flag set by BSP to signal APs that scheduling is ready. */
+extern volatile uint32_t ap_sched_go;
+
+/* AP C entry point (called from SMP trampoline assembly). */
+void ap_entry(void);
+
#endif
*/
void arch_syscall_init(void);
+#if defined(__i386__)
+/* x86 SYSENTER helpers */
+void x86_sysenter_set_kernel_stack(uintptr_t esp0);
+void sysenter_init_ap(uint32_t cpu_index);
+#endif
+
#endif /* ARCH_SYSCALL_H */
/* Map drive ID to device name. Returns NULL if invalid. */
const char* ata_drive_to_name(int drive);
+/* Register detected ATA drives in devfs (/dev/hdX). */
+void ata_register_devfs(void);
+
#endif
void hal_cpu_set_tls(uintptr_t base);
+/* SMAP (Supervisor Mode Access Prevention) status — set by cpu_features init */
+extern int g_smap_enabled;
+
#endif
void hal_usermode_enter_regs(const void* regs);
+#if defined(__i386__)
+void x86_usermode_test_start(void);
+#endif
+
#endif
uint8_t fb_type; /* 0=indexed, 1=direct RGB (linear), 2=EGA text */
};
+/* Kernel entry point (called from arch-specific boot code). */
+void kernel_main(const struct boot_info* bi);
+
#endif
/* Get the active network interface (or NULL). */
struct netif* net_get_netif(void);
+/* Start DHCP client on the active network interface. */
+void net_dhcp_start(void);
+
/* Run ICMP ping test (sends echo requests to QEMU gateway 10.0.2.2). */
void net_ping_test(void);
#include "arch_fpu.h"
#include "fs.h"
#include "signal.h"
+#include "spinlock.h"
/* clone() flags (Linux-compatible subset) */
#define CLONE_VM 0x00000100 /* Share address space */
// Periodic load balancing: migrate one process from busiest to idlest CPU.
void sched_load_balance(void);
+// Scheduler globals (used by procfs)
+extern struct process* ready_queue_head;
+extern spinlock_t sched_lock;
+
+// Scheduler init helpers (called from arch platform code)
+void sched_set_init_pid(uint32_t pid);
+void sched_assign_pid1(struct process* p);
+void sched_ap_init(uint32_t cpu);
+
#endif
#include <stdint.h>
+struct registers;
void syscall_init(void);
+void syscall_handler(struct registers* regs);
enum {
SYSCALL_WRITE = 1,
#define IDT_ENTRIES 256
#define IRQ_CHAIN_POOL_SIZE 32
-struct idt_entry idt[IDT_ENTRIES];
-struct idt_ptr idtp;
+static struct idt_entry idt[IDT_ENTRIES];
+static struct idt_ptr idtp;
struct irq_chain_node {
isr_handler_t handler;
/* Legacy single-handler array kept for backward compatibility.
* New registrations via register_interrupt_handler go through the chain. */
-isr_handler_t interrupt_handlers[IDT_ENTRIES];
+static isr_handler_t interrupt_handlers[IDT_ENTRIES];
static spinlock_t idt_handlers_lock = {0};
static struct irq_chain_node* irq_chain_alloc(void) {
for (int i = 0; i < IRQ_CHAIN_POOL_SIZE; i++) {
- if (irq_chain_pool[i].handler == 0) {
+ if (irq_chain_pool[i].handler == NULL) {
return &irq_chain_pool[i];
}
}
- return 0;
+ return NULL;
}
// Extern prototypes for Assembly stubs
extern void isr128();
extern void isr255();
-void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
+static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
idt[num].base_lo = base & 0xFFFF;
idt[num].base_hi = (base >> 16) & 0xFFFF;
idt[num].sel = sel;
}
/* Reconfigure the PIC to remap IRQs from 0-15 to 32-47 */
-void pic_remap(void) {
+static void pic_remap(void) {
uint8_t a1, a2;
a1 = inb(0x21); // Save masks
struct irq_chain_node* first = irq_chain_alloc();
if (first) {
first->handler = interrupt_handlers[n];
- first->next = 0;
+ first->next = NULL;
irq_chain_heads[n] = first;
}
- interrupt_handlers[n] = 0;
+ interrupt_handlers[n] = NULL;
}
/* Add new handler to chain */
/* Check legacy slot */
if (interrupt_handlers[n] == handler) {
- interrupt_handlers[n] = 0;
+ interrupt_handlers[n] = NULL;
spin_unlock_irqrestore(&idt_handlers_lock, flags);
return;
}
if ((*pp)->handler == handler) {
struct irq_chain_node* victim = *pp;
*pp = victim->next;
- victim->handler = 0;
- victim->next = 0;
+ victim->handler = NULL;
+ victim->next = NULL;
break;
}
pp = &(*pp)->next;
/* If only one handler left in chain, migrate back to legacy slot */
if (irq_chain_heads[n] && !irq_chain_heads[n]->next) {
interrupt_handlers[n] = irq_chain_heads[n]->handler;
- irq_chain_heads[n]->handler = 0;
- irq_chain_heads[n] = 0;
+ irq_chain_heads[n]->handler = NULL;
+ irq_chain_heads[n] = NULL;
}
spin_unlock_irqrestore(&idt_handlers_lock, flags);
// ... imports ...
-void print_reg(const char* name, uint32_t val) {
+static void print_reg(const char* name, uint32_t val) {
kprintf("%s: %x ", name, val);
}
if (node->handler) node->handler(regs);
node = node->next;
}
- } else if (interrupt_handlers[regs->int_no] != 0) {
+ } else if (interrupt_handlers[regs->int_no] != NULL) {
isr_handler_t handler = interrupt_handlers[regs->int_no];
handler(regs);
} else {
#include <stdint.h>
-static volatile uint32_t* ioapic_base = 0;
+static volatile uint32_t* ioapic_base = NULL;
static int ioapic_active = 0;
static uint8_t ioapic_max_irqs = 0;
}
void ioapic_mask_irq(uint8_t irq) {
- if (!ioapic_active && ioapic_base == 0) return;
+ if (!ioapic_active && ioapic_base == NULL) return;
if (irq >= IOAPIC_MAX_IRQS) return;
uint32_t reg_lo = IOAPIC_REG_REDTBL + (uint32_t)irq * 2;
#define IA32_APIC_BASE_ENABLE (1U << 11)
#define IA32_APIC_BASE_ADDR 0xFFFFF000U
-static volatile uint32_t* lapic_base = 0;
+static volatile uint32_t* lapic_base = NULL;
static int lapic_active = 0;
static uint32_t lapic_timer_ticks_saved = 0; /* BSP-calibrated ticks for AP reuse */
#include "interrupts.h"
#include "console.h"
#include "arch/x86/smp.h"
+#include "arch_syscall.h"
#include <stdint.h>
#include "process.h"
#include "utils.h"
#include "arch/x86/usermode.h"
+#include "hal/usermode.h"
#include "arch/x86/idt.h"
#if defined(__i386__)
int ata_name_to_drive(const char* name) { (void)name; return -1; }
__attribute__((weak))
-const char* ata_drive_to_name(int drive) { (void)drive; return 0; }
+const char* ata_drive_to_name(int drive) { (void)drive; return NULL; }
__attribute__((weak))
void ata_register_devfs(void) { }
#define E1000_TX_BUF_VA KVA_E1000_TX_BUF
#define E1000_RX_BUF_VA KVA_E1000_RX_BUF
-static volatile uint32_t* e1000_mmio = 0;
+static volatile uint32_t* e1000_mmio = NULL;
static uint8_t e1000_mac[6];
static int e1000_ready = 0;
}
static struct fs_node* initrd_finddir(struct fs_node* node, const char* name) {
- if (!node || !name) return 0;
+ if (!node || !name) return NULL;
int parent = (int)node->inode;
- if (parent < 0 || parent >= entry_count) return 0;
+ if (parent < 0 || parent >= entry_count) return NULL;
int c = entries[parent].first_child;
while (c != -1) {
}
c = entries[c].next_sibling;
}
- return 0;
+ return NULL;
}
static const struct file_operations initrd_file_ops = {
decomp_buf = (uint8_t*)kmalloc(orig_sz);
if (!decomp_buf) {
kprintf("[INITRD] OOM decompressing LZ4 (%u bytes)\n", orig_sz);
- return 0;
+ return NULL;
}
int ret = lz4_decompress_frame(raw, size, decomp_buf, orig_sz);
if (ret < 0) {
kprintf("[INITRD] LZ4 Frame decompress failed (ret=%d)\n", ret);
kfree(decomp_buf);
- return 0;
+ return NULL;
}
kprintf("[INITRD] LZ4: %u -> %d bytes\n", size, ret);
decomp_buf = (uint8_t*)kmalloc(orig_sz);
if (!decomp_buf) {
kprintf("[INITRD] OOM decompressing LZ4 (%u bytes)\n", orig_sz);
- return 0;
+ return NULL;
}
int ret = lz4_decompress_block(raw + LZ4B_HDR_SIZE, comp_sz,
kprintf("[INITRD] LZ4 decompress failed (ret=%d, expected=%u)\n",
ret, orig_sz);
kfree(decomp_buf);
- return 0;
+ return NULL;
}
kprintf("[INITRD] LZ4: %u -> %u bytes\n", comp_sz, orig_sz);
entry_count = 0;
int root = entry_alloc();
- if (root < 0) { kfree(decomp_buf); return 0; }
+ if (root < 0) { kfree(decomp_buf); return NULL; }
strcpy(entries[root].name, "");
entries[root].flags = FS_DIRECTORY;
entries[root].data_offset = 0;
int pci_get_device_count(void) { return 0; }
__attribute__((weak))
-const struct pci_device* pci_get_device(int index) { (void)index; return 0; }
+const struct pci_device* pci_get_device(int index) { (void)index; return NULL; }
__attribute__((weak))
-const struct pci_device* pci_find_device(uint16_t vendor, uint16_t device) { (void)vendor; (void)device; return 0; }
+const struct pci_device* pci_find_device(uint16_t vendor, uint16_t device) { (void)vendor; (void)device; return NULL; }
__attribute__((weak))
-const struct pci_device* pci_find_class(uint8_t class_code, uint8_t subclass) { (void)class_code; (void)subclass; return 0; }
+const struct pci_device* pci_find_class(uint8_t class_code, uint8_t subclass) { (void)class_code; (void)subclass; return NULL; }
#include "spinlock.h"
-static volatile uint16_t* VGA_BUFFER = 0;
+static volatile uint16_t* VGA_BUFFER = NULL;
#define VGA_WIDTH 80
#define VGA_HEIGHT 25
#define VGA_CELLS (VGA_WIDTH * VGA_HEIGHT)
}
const char* ata_drive_to_name(int drive) {
- if (drive < 0 || drive >= ATA_MAX_DRIVES) return 0;
+ if (drive < 0 || drive >= ATA_MAX_DRIVES) return NULL;
return drive_names[drive];
}
*/
#include "hal/cpu_features.h"
+#include "hal/cpu.h"
#include "arch/x86/cpuid.h"
#include "console.h"
#include "arch/x86/idt.h"
#include "io.h"
#include "vga_console.h"
+#include <stddef.h>
-static hal_keyboard_char_cb_t g_cb = 0;
-static hal_keyboard_scan_cb_t g_scan_cb = 0;
+static hal_keyboard_char_cb_t g_cb = NULL;
+static hal_keyboard_scan_cb_t g_scan_cb = NULL;
/* Modifier state */
static volatile int shift_held = 0;
}
const struct pci_device* pci_get_device(int index) {
- if (index < 0 || index >= pci_device_count) return 0;
+ if (index < 0 || index >= pci_device_count) return NULL;
return &pci_devices[index];
}
if (pci_devices[i].vendor_id == vendor && pci_devices[i].device_id == device)
return &pci_devices[i];
}
- return 0;
+ return NULL;
}
const struct pci_device* pci_find_class(uint8_t class_code, uint8_t subclass) {
if (pci_devices[i].class_code == class_code && pci_devices[i].subclass == subclass)
return &pci_devices[i];
}
- return 0;
+ return NULL;
}
/* HAL driver registration */
#include "io.h"
#include "console.h"
-static hal_timer_tick_cb_t g_tick_cb = 0;
+static hal_timer_tick_cb_t g_tick_cb = NULL;
static void timer_irq(struct registers* regs) {
(void)regs;
#include "arch/x86/idt.h"
#include <stdint.h>
+#include <stddef.h>
#define UART_BASE 0x3F8
static int uart_present = 0;
-static void (*uart_rx_cb)(char) = 0;
+static void (*uart_rx_cb)(char) = NULL;
static void uart_irq_handler(struct registers* regs) {
(void)regs;
static struct fs_node* devfs_finddir_impl(struct fs_node* node, const char* name) {
(void)node;
- if (!name || name[0] == 0) return 0;
+ if (!name || name[0] == 0) return NULL;
if (strcmp(name, "null") == 0) return &g_dev_null;
if (strcmp(name, "zero") == 0) return &g_dev_zero;
if (strcmp(g_registered[i]->name, name) == 0)
return g_registered[i];
}
- return 0;
+ return NULL;
}
static int devfs_readdir_impl(struct fs_node* node, uint32_t* inout_index, void* buf, uint32_t buf_len) {
static struct fs_node* diskfs_root_finddir(struct fs_node* node, const char* name) {
struct diskfs_node* parent = (struct diskfs_node*)node;
- if (!g_ready) return 0;
- if (!name || name[0] == 0) return 0;
- if (!diskfs_segment_valid(name)) return 0;
+ if (!g_ready) return NULL;
+ if (!name || name[0] == 0) return NULL;
+ if (!diskfs_segment_valid(name)) return NULL;
uint16_t parent_ino = parent ? parent->ino : 0;
struct diskfs_super sb;
- if (diskfs_super_load(&sb) < 0) return 0;
- if (parent_ino >= DISKFS_MAX_INODES) return 0;
- if (sb.inodes[parent_ino].type != DISKFS_INODE_DIR) return 0;
+ if (diskfs_super_load(&sb) < 0) return NULL;
+ if (parent_ino >= DISKFS_MAX_INODES) return NULL;
+ if (sb.inodes[parent_ino].type != DISKFS_INODE_DIR) return NULL;
int child = diskfs_find_child(&sb, parent_ino, name);
- if (child < 0) return 0;
+ if (child < 0) return NULL;
uint16_t cino = (uint16_t)child;
struct diskfs_node* dn = (struct diskfs_node*)kmalloc(sizeof(*dn));
- if (!dn) return 0;
+ if (!dn) return NULL;
memset(dn, 0, sizeof(*dn));
strcpy(dn->vfs.name, name);
int diskfs_open_file(const char* rel_path, uint32_t flags, fs_node_t** out_node) {
if (!out_node) return -EINVAL;
- *out_node = 0;
+ *out_node = NULL;
if (!g_ready) return -ENODEV;
if (!rel_path || rel_path[0] == 0) return -EINVAL;
if (diskfs_super_load(&sb) < 0) return -EIO;
uint16_t ino = 0;
- int rc = diskfs_lookup_path(&sb, rel_path, &ino, 0, 0, 0);
+ int rc = diskfs_lookup_path(&sb, rel_path, &ino, NULL, NULL, 0);
if (rc < 0) return rc;
if (ino == 0) return -EPERM;
if (ino >= DISKFS_MAX_INODES) return -EIO;
if (diskfs_super_load(&sb) < 0) return -EIO;
uint16_t old_ino = 0;
- int rc = diskfs_lookup_path(&sb, old_rel, &old_ino, 0, 0, 0);
+ int rc = diskfs_lookup_path(&sb, old_rel, &old_ino, NULL, NULL, 0);
if (rc < 0) return rc;
if (old_ino >= DISKFS_MAX_INODES) return -EIO;
if (sb.inodes[old_ino].type != DISKFS_INODE_FILE) return -EPERM;
/* Check new name doesn't already exist */
uint16_t dummy = 0;
- if (diskfs_lookup_path(&sb, new_rel, &dummy, 0, 0, 0) == 0) return -EEXIST;
+ if (diskfs_lookup_path(&sb, new_rel, &dummy, NULL, NULL, 0) == 0) return -EEXIST;
/* Find a free inode slot */
uint16_t new_ino = 0;
if (diskfs_super_load(&sb) < 0) return -EIO;
uint16_t ino = 0;
- int rc = diskfs_lookup_path(&sb, rel_path, &ino, 0, 0, 0);
+ int rc = diskfs_lookup_path(&sb, rel_path, &ino, NULL, NULL, 0);
if (rc < 0) return rc;
if (ino == 0) return -EPERM;
if (ino >= DISKFS_MAX_INODES) return -EIO;
if (diskfs_super_load(&sb) < 0) return -EIO;
uint16_t src_ino = 0;
- int rc = diskfs_lookup_path(&sb, old_rel, &src_ino, 0, 0, 0);
+ int rc = diskfs_lookup_path(&sb, old_rel, &src_ino, NULL, NULL, 0);
if (rc < 0) return rc;
if (src_ino == 0) return -EPERM;
if (src_ino >= DISKFS_MAX_INODES) return -EIO;
static int diskfs_vfs_create(struct fs_node* dir, const char* name, uint32_t flags, struct fs_node** out) {
if (!dir || !name || !out) return -EINVAL;
- *out = 0;
+ *out = NULL;
if (!g_ready) return -ENODEV;
struct diskfs_node* parent = (struct diskfs_node*)dir;
}
}
- return g_ready ? &g_root.vfs : 0;
+ return g_ready ? &g_root.vfs : NULL;
}
static const char* hist_get(int idx) {
/* idx 0 = most recent, 1 = second most recent, etc. */
- if (idx < 0 || idx >= hist_count) return 0;
+ if (idx < 0 || idx >= hist_count) return NULL;
int slot = (hist_head - 1 - idx + HIST_MAX) % HIST_MAX;
return hist_buf[slot];
}
/* ---- Main entry ---- */
void kconsole_enter(void) {
- keyboard_set_callback(0);
+ keyboard_set_callback(NULL);
kc_puts("\n[PANIC] Userspace init failed -- dropping to kconsole.\n");
kc_puts(" Type 'help' for commands, 'reboot' to restart.\n\n");
}
static struct fs_node* overlay_finddir_impl(struct fs_node* node, const char* name) {
- if (!node || !name) return 0;
- if (node->flags != FS_DIRECTORY) return 0;
+ if (!node || !name) return NULL;
+ if (node->flags != FS_DIRECTORY) return NULL;
struct overlay_node* dir = (struct overlay_node*)node;
if (dir->lower && dir->lower->i_ops && dir->lower->i_ops->lookup)
lower_child = dir->lower->i_ops->lookup(dir->lower, name);
- if (!upper_child && !lower_child) return 0;
+ if (!upper_child && !lower_child) return NULL;
return overlay_wrap_child(dir, name, lower_child, upper_child);
}
static uint32_t g_ready = 0;
static fs_node_t* persistfs_backing_open(uint32_t flags) {
- fs_node_t* n = 0;
- if (diskfs_open_file(PERSISTFS_BACKING_NAME, flags, &n) < 0) return 0;
+ fs_node_t* n = NULL;
+ if (diskfs_open_file(PERSISTFS_BACKING_NAME, flags, &n) < 0) return NULL;
return n;
}
static struct fs_node* persist_root_finddir(struct fs_node* node, const char* name) {
(void)node;
- if (!name || name[0] == 0) return 0;
+ if (!name || name[0] == 0) return NULL;
if (strcmp(name, "counter") == 0) return &g_counter;
- return 0;
+ return NULL;
}
static const struct file_operations persistfs_root_fops = {0};
g_counter.f_ops = &persistfs_counter_fops;
}
- return g_ready ? &g_root : 0;
+ return g_ready ? &g_root : NULL;
}
static struct fs_node* pty_pts_finddir(struct fs_node* node, const char* name) {
(void)node;
- if (!name || name[0] == 0) return 0;
+ if (!name || name[0] == 0) return NULL;
int count = pty_pair_count();
for (int i = 0; i < count; i++) {
char num[4];
return pty_get_slave_node(i);
}
}
- return 0;
+ return NULL;
}
static int pty_pts_readdir(struct fs_node* node, uint32_t* inout_index, void* buf, uint32_t buf_len) {
struct process* current_process = NULL;
#endif
struct process* ready_queue_head = NULL;
-struct process* ready_queue_tail = NULL;
+static struct process* ready_queue_tail = NULL;
static uint32_t next_pid = 2; /* PID 1 reserved for init */
static uint32_t init_pid = 0; /* PID of the first userspace process ("init") */
s->count = initial_count;
s->nwaiters = 0;
for (uint32_t i = 0; i < KSEM_MAX_WAITERS; i++)
- s->waiters[i] = 0;
+ s->waiters[i] = NULL;
}
void ksem_wait(ksem_t* s) {
/* We timed out — remove from list */
for (uint32_t j = i; j + 1 < s->nwaiters; j++)
s->waiters[j] = s->waiters[j + 1];
- s->waiters[--s->nwaiters] = 0;
+ s->waiters[--s->nwaiters] = NULL;
found = 1;
break;
}
/* Remove from waiters list */
for (uint32_t j = i; j + 1 < s->nwaiters; j++)
s->waiters[j] = s->waiters[j + 1];
- s->waiters[--s->nwaiters] = 0;
+ s->waiters[--s->nwaiters] = NULL;
p->state = PROCESS_READY;
p->wake_at_tick = 0;
mb->count = 0;
mb->capacity = size;
for (uint32_t i = 0; i < KMBOX_MAX_MSGS; i++)
- mb->msgs[i] = 0;
+ mb->msgs[i] = NULL;
ksem_init(&mb->not_empty, 0);
ksem_init(&mb->not_full, (int32_t)size);
spinlock_init(&cv->lock);
cv->nwaiters = 0;
for (uint32_t i = 0; i < KCOND_MAX_WAITERS; i++)
- cv->waiters[i] = 0;
+ cv->waiters[i] = NULL;
}
int kcond_wait(kcond_t* cv, kmutex_t* mtx, uint32_t timeout_ms) {
if (cv->waiters[i] == current_process) {
for (uint32_t j = i; j + 1 < cv->nwaiters; j++)
cv->waiters[j] = cv->waiters[j + 1];
- cv->waiters[--cv->nwaiters] = 0;
+ cv->waiters[--cv->nwaiters] = NULL;
found = 1;
break;
}
if (p && (p->state == PROCESS_BLOCKED || p->state == PROCESS_SLEEPING)) {
for (uint32_t j = i; j + 1 < cv->nwaiters; j++)
cv->waiters[j] = cv->waiters[j + 1];
- cv->waiters[--cv->nwaiters] = 0;
+ cv->waiters[--cv->nwaiters] = NULL;
p->state = PROCESS_READY;
p->wake_at_tick = 0;
p->state = PROCESS_READY;
p->wake_at_tick = 0;
wake_list[wake_count++] = p;
- cv->waiters[i] = 0;
+ cv->waiters[i] = NULL;
}
}
cv->nwaiters = 0;
current_process->state = PROCESS_SLEEPING;
current_process->wake_at_tick = get_tick_count() + 5000; /* 100s timeout */
schedule();
- futex_waiters[slot].proc = 0;
+ futex_waiters[slot].proc = NULL;
futex_waiters[slot].addr = 0;
sc_ret(regs) = 0;
return;
for (int i = 0; i < FUTEX_MAX_WAITERS && woken < max_wake; i++) {
if (futex_waiters[i].proc && futex_waiters[i].addr == (uintptr_t)uaddr) {
futex_waiters[i].proc->state = PROCESS_READY;
- futex_waiters[i].proc = 0;
+ futex_waiters[i].proc = NULL;
futex_waiters[i].addr = 0;
woken++;
}
}
static struct fs_node* tmpfs_finddir_impl(struct fs_node* node, const char* name) {
- if (!node || !name) return 0;
- if (node->flags != FS_DIRECTORY) return 0;
+ if (!node || !name) return NULL;
+ if (node->flags != FS_DIRECTORY) return NULL;
struct tmpfs_node* dir = (struct tmpfs_node*)node;
struct tmpfs_node* child = tmpfs_child_find(dir, name);
- if (!child) return 0;
+ if (!child) return NULL;
return &child->vfs;
}
#include "utils.h"
+/* Forward declarations for compiler ABI symbols (not in any header) */
+void* __memcpy_chk(void* dst, const void* src, size_t n, size_t dst_len);
+const unsigned short** __ctype_b_loc(void);
+
size_t strlen(const char* str) {
size_t len = 0;
while (str[len])
#include "console.h"
static uintptr_t vdso_phys = 0;
-static volatile struct vdso_data* vdso_kptr = 0;
+static volatile struct vdso_data* vdso_kptr = NULL;
void vdso_init(void) {
void* page = pmm_alloc_page();
dns_done = 0;
dns_result_ip = 0;
- err_t err = dns_gethostbyname(hostname, &resolved, dns_found_cb, 0);
+ err_t err = dns_gethostbyname(hostname, &resolved, dns_found_cb, NULL);
if (err == ERR_OK) {
/* Already cached */
*out_ip = ip4_addr_get_u32(ip_2_ip4(&resolved));
* RX path: interrupt → e1000_rx_sem → rx_thread → e1000_recv → tcpip_input
* TX path: lwIP core → e1000_netif_output → e1000_send (non-blocking)
*/
+#include "net.h"
#include "lwip/opt.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"