Skip to content

Commit 27b0d12

Browse files
committed
upd: crash splashes
1 parent ac4084d commit 27b0d12

21 files changed

Lines changed: 274 additions & 93 deletions

File tree

ZenOS.vhd

-26 MB
Binary file not shown.

docs/TODO.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
## What I have planned next for Zen:
22

3-
> Getting more BusyBox applets.
3+
> Getting more BusyBox applets.
4+
5+
> Self-hosting, perhaps implies GCC porting

src/cpu/isr.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "../libk/ports.h"
2020
#include "../libk/string.h"
2121
#include "../libk/debug/log.h"
22+
#include "../drv/vga.h"
2223
#include "../kernel/sched.h"
2324
#include <stdint.h>
2425

@@ -30,8 +31,138 @@ void register_interrupt_handler(uint8_t interrupt, isr_handler_t handler, const
3031
interrupt_handlers[interrupt] = handler;
3132
}
3233

34+
static const char *exception_title(uint64_t int_no)
35+
{
36+
switch (int_no) {
37+
case DIVISION_BY_ZERO: return "Division by zero";
38+
case DEBUG_EXCEPTION: return "Debug exception";
39+
case NON_MASKABLE_INTERRUPT: return "Non-maskable interrupt";
40+
case BREAKPOINT_EXCEPTION: return "Breakpoint";
41+
case OVERFLOW_EXCEPTION: return "Overflow";
42+
case BOUND_RANGE_EXCEEDED: return "Bound range exceeded";
43+
case INVALID_OPCODE_EXCEPTION: return "Invalid opcode";
44+
case DEVICE_NOT_AVAILABLE: return "Device not available";
45+
case DOUBLE_FAULT: return "Double fault";
46+
case INVALID_TSS: return "Invalid TSS";
47+
case SEGMENT_NOT_PRESENT: return "Segment not present";
48+
case STACK_SEGMENT_FAULT: return "Stack segment fault";
49+
case GENERAL_PROTECTION_FAULT: return "General protection fault";
50+
case PAGE_FAULT: return "Page fault";
51+
case X87_FLOATING_POINT: return "x87 floating point exception";
52+
case ALIGNMENT_CHECK: return "Alignment check";
53+
case MACHINE_CHECK: return "Machine check";
54+
case SIMD_FLOATING_POINT: return "SIMD floating point exception";
55+
case VIRTUALIZATION_EXCEPTION: return "Virtualization exception";
56+
case SECURITY_EXCEPTION: return "Security exception";
57+
default: return "CPU exception";
58+
}
59+
}
60+
61+
static const char *exception_splash(uint64_t int_no)
62+
{
63+
switch (int_no) {
64+
case DIVISION_BY_ZERO: return "DIV0";
65+
case INVALID_OPCODE_EXCEPTION: return "UD";
66+
case DOUBLE_FAULT: return "DF";
67+
case INVALID_TSS: return "TSS";
68+
case SEGMENT_NOT_PRESENT: return "SNP";
69+
case STACK_SEGMENT_FAULT: return "SS";
70+
case GENERAL_PROTECTION_FAULT: return "GPF";
71+
case PAGE_FAULT: return "PF";
72+
case ALIGNMENT_CHECK: return "AC";
73+
case MACHINE_CHECK: return "MC";
74+
case SIMD_FLOATING_POINT: return "SIMD";
75+
default: return "EXCEPTION";
76+
}
77+
}
78+
79+
static void halt_forever(void)
80+
{
81+
for (;;)
82+
asm volatile("cli; hlt");
83+
}
84+
85+
static void kernel_exception_screen(registers_t *regs)
86+
{
87+
uint64_t cr2 = 0;
88+
if (regs->int_no == PAGE_FAULT)
89+
asm volatile("mov %%cr2, %0" : "=r"(cr2));
90+
task_t *task = sched_current_task();
91+
const char *task_name = task ? task->name : "kernel";
92+
int pid = task ? task->pid : -1;
93+
uint16_t selector = (uint16_t)((regs->err_code >> 3) & 0x1fff);
94+
char info[1536];
95+
96+
if (regs->int_no == PAGE_FAULT) {
97+
snprintf(info, sizeof(info),
98+
"Task: %s (PID %d)\n"
99+
"Fault address: 0x%016lx\n"
100+
"Error: 0x%016lx %s %s %s\n"
101+
"RIP=0x%016lx RSP=0x%016lx RFLAGS=0x%016lx\n"
102+
"RAX=0x%016lx RBX=0x%016lx RCX=0x%016lx\n"
103+
"RDX=0x%016lx RSI=0x%016lx RDI=0x%016lx\n"
104+
"RBP=0x%016lx R8 =0x%016lx R9 =0x%016lx\n"
105+
"R10=0x%016lx R11=0x%016lx R12=0x%016lx\n"
106+
"R13=0x%016lx R14=0x%016lx R15=0x%016lx\n"
107+
"CS=0x%04lx SS=0x%04lx",
108+
task_name, pid, cr2, regs->err_code,
109+
(regs->err_code & 1) ? "protection" : "not-present",
110+
(regs->err_code & 2) ? "write" : "read",
111+
(regs->err_code & 4) ? "user" : "supervisor",
112+
regs->rip, regs->userrsp, regs->rflags,
113+
regs->rax, regs->rbx, regs->rcx, regs->rdx,
114+
regs->rsi, regs->rdi, regs->rbp,
115+
regs->r8, regs->r9, regs->r10, regs->r11,
116+
regs->r12, regs->r13, regs->r14, regs->r15,
117+
regs->cs, regs->ss);
118+
} else if (regs->int_no == GENERAL_PROTECTION_FAULT) {
119+
snprintf(info, sizeof(info),
120+
"Task: %s (PID %d)\n"
121+
"Error: 0x%016lx selector=0x%04x %s\n"
122+
"RIP=0x%016lx RSP=0x%016lx RFLAGS=0x%016lx\n"
123+
"RAX=0x%016lx RBX=0x%016lx RCX=0x%016lx\n"
124+
"RDX=0x%016lx RSI=0x%016lx RDI=0x%016lx\n"
125+
"RBP=0x%016lx R8 =0x%016lx R9 =0x%016lx\n"
126+
"R10=0x%016lx R11=0x%016lx R12=0x%016lx\n"
127+
"R13=0x%016lx R14=0x%016lx R15=0x%016lx\n"
128+
"CS=0x%04lx SS=0x%04lx",
129+
task_name, pid, regs->err_code, selector,
130+
(regs->err_code & 1) ? "external" : "internal",
131+
regs->rip, regs->userrsp, regs->rflags,
132+
regs->rax, regs->rbx, regs->rcx, regs->rdx,
133+
regs->rsi, regs->rdi, regs->rbp,
134+
regs->r8, regs->r9, regs->r10, regs->r11,
135+
regs->r12, regs->r13, regs->r14, regs->r15,
136+
regs->cs, regs->ss);
137+
} else {
138+
snprintf(info, sizeof(info),
139+
"Task: %s (PID %d)\n"
140+
"Interrupt: %lu Error: 0x%016lx\n"
141+
"RIP=0x%016lx RSP=0x%016lx RFLAGS=0x%016lx\n"
142+
"RAX=0x%016lx RBX=0x%016lx RCX=0x%016lx\n"
143+
"RDX=0x%016lx RSI=0x%016lx RDI=0x%016lx\n"
144+
"RBP=0x%016lx R8 =0x%016lx R9 =0x%016lx\n"
145+
"R10=0x%016lx R11=0x%016lx R12=0x%016lx\n"
146+
"R13=0x%016lx R14=0x%016lx R15=0x%016lx\n"
147+
"CS=0x%04lx SS=0x%04lx",
148+
task_name, pid, regs->int_no, regs->err_code,
149+
regs->rip, regs->userrsp, regs->rflags,
150+
regs->rax, regs->rbx, regs->rcx, regs->rdx,
151+
regs->rsi, regs->rdi, regs->rbp,
152+
regs->r8, regs->r9, regs->r10, regs->r11,
153+
regs->r12, regs->r13, regs->r14, regs->r15,
154+
regs->cs, regs->ss);
155+
}
156+
157+
vga_crash_screen(exception_splash(regs->int_no), exception_title(regs->int_no), info);
158+
halt_forever();
159+
}
160+
33161
void isr_handler(registers_t* regs)
34162
{
163+
if (regs->int_no < 32 && !(regs->cs & 3))
164+
kernel_exception_screen(regs);
165+
35166
switch(regs->int_no) {
36167
case DIVISION_BY_ZERO:
37168
if (regs->cs & 3) {

src/drv/disk/fat.c

Lines changed: 24 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020
#include "../../libk/core/mem.h"
2121
#include "../../libk/spinlock.h"
2222
#include "../../drv/rtc.h"
23-
#include "../../kernel/sched.h"
24-
25-
#define FAT_IO_CHUNK 4096U
2623

2724
DWORD get_fattime(void) {
2825
rtc_time_t t = rtc_get_time();
@@ -158,49 +155,23 @@ int fat_open(const char *path, int write) { return fat_open_vol(path, write, 0);
158155

159156
int fat_read(int fd, void *buf, uint32_t size, uint32_t *bytes_read) {
160157
if (!initialized || fd < 0 || fd >= FAT_MAX_FDS || !fd_table[fd].used) return -1;
161-
uint8_t *out = (uint8_t *)buf;
162-
uint32_t total = 0;
163-
while (total < size) {
164-
UINT br = 0;
165-
UINT chunk = (UINT)(size - total);
166-
if (chunk > FAT_IO_CHUNK)
167-
chunk = FAT_IO_CHUNK;
168-
fat_lock();
169-
FRESULT fr = f_read(&fd_table[fd].fil, out + total, chunk, &br);
170-
fat_unlock();
171-
total += br;
172-
if (fr != FR_OK) {
173-
if (bytes_read) *bytes_read = total;
174-
return total ? 0 : -1;
175-
}
176-
if (br == 0 || br < chunk)
177-
break;
178-
if (total < size)
179-
sched_yield();
180-
}
181-
if (bytes_read) *bytes_read = total;
182-
return 0;
158+
UINT br = 0;
159+
fat_lock();
160+
FRESULT fr = f_read(&fd_table[fd].fil, buf, size, &br);
161+
fat_unlock();
162+
if (bytes_read) *bytes_read = br;
163+
return fr == FR_OK ? 0 : -1;
183164
}
184165

185166
int fat_write(int fd, const void *buf, uint32_t size) {
186167
if (!initialized || fd < 0 || fd >= FAT_MAX_FDS || !fd_table[fd].used) return -1;
187168
if (!fd_table[fd].writable) return -1;
188-
const uint8_t *in = (const uint8_t *)buf;
189-
uint32_t total = 0;
190-
while (total < size) {
191-
UINT bw = 0;
192-
UINT chunk = (UINT)(size - total);
193-
if (chunk > FAT_IO_CHUNK)
194-
chunk = FAT_IO_CHUNK;
195-
fat_lock();
196-
FRESULT fr = f_write(&fd_table[fd].fil, in + total, chunk, &bw);
197-
fat_unlock();
198-
fd_table[fd].total_written += bw;
199-
total += bw;
200-
if (fr != FR_OK || bw != chunk) { log("Write fd=%d failed.", 2, 0, fd); return -1; }
201-
if (total < size)
202-
sched_yield();
203-
}
169+
UINT bw = 0;
170+
fat_lock();
171+
FRESULT fr = f_write(&fd_table[fd].fil, buf, size, &bw);
172+
fat_unlock();
173+
fd_table[fd].total_written += bw;
174+
if (fr != FR_OK || bw != size) { log("Write fd=%d failed.", 2, 0, fd); return -1; }
204175
return 0;
205176
}
206177

@@ -475,51 +446,23 @@ int fat_open_entry(const char *path, int write, fd_entry_t *out) { return fat_op
475446

476447
int fat_read_entry(fd_entry_t *e, void *buf, uint32_t size, uint32_t *bytes_read) {
477448
if (!e || !e->used || e->type != FD_FILE || !e->file) return -1;
478-
uint8_t *out = (uint8_t *)buf;
479-
uint32_t total = 0;
480-
while (total < size) {
481-
UINT br = 0;
482-
UINT chunk = (UINT)(size - total);
483-
if (chunk > FAT_IO_CHUNK)
484-
chunk = FAT_IO_CHUNK;
485-
fat_lock();
486-
FRESULT fr = f_read(&e->file->fil, out + total, chunk, &br);
487-
fat_unlock();
488-
total += br;
489-
if (fr != FR_OK) {
490-
if (bytes_read) *bytes_read = total;
491-
return total ? 0 : -1;
492-
}
493-
if (br == 0 || br < chunk)
494-
break;
495-
if (total < size)
496-
sched_yield();
497-
}
498-
if (bytes_read) *bytes_read = total;
499-
return 0;
449+
UINT br = 0;
450+
fat_lock();
451+
FRESULT fr = f_read(&e->file->fil, buf, size, &br);
452+
fat_unlock();
453+
if (bytes_read) *bytes_read = br;
454+
return fr == FR_OK ? 0 : -1;
500455
}
501456

502457
int fat_write_entry(fd_entry_t *e, const void *buf, uint32_t size) {
503458
if (!e || !e->used || e->type != FD_FILE || !e->file) return -1;
504459
if (!e->file->writable) return -1;
505-
const uint8_t *in = (const uint8_t *)buf;
506-
uint32_t total = 0;
507-
while (total < size) {
508-
UINT bw = 0;
509-
UINT chunk = (UINT)(size - total);
510-
if (chunk > FAT_IO_CHUNK)
511-
chunk = FAT_IO_CHUNK;
512-
fat_lock();
513-
FRESULT fr = f_write(&e->file->fil, in + total, chunk, &bw);
514-
fat_unlock();
515-
e->file->total_written += bw;
516-
total += bw;
517-
if (fr != FR_OK || bw != chunk)
518-
return -1;
519-
if (total < size)
520-
sched_yield();
521-
}
522-
return 0;
460+
UINT bw = 0;
461+
fat_lock();
462+
FRESULT fr = f_write(&e->file->fil, buf, size, &bw);
463+
fat_unlock();
464+
e->file->total_written += bw;
465+
return (fr == FR_OK && bw == size) ? 0 : -1;
523466
}
524467

525468
int fat_close_entry(fd_entry_t *e) {

0 commit comments

Comments
 (0)