1414#include "../lib/math.h"
1515
1616#define CMD_COMP (name ) (strcmp(strtok(chars, " "), name) == 0)
17+ #define MAX_CAT_SIZE 8192 // Max file size for cat (8KB for now)
1718
1819extern struct kfs_superblock superblock ;
1920
21+ static inline void outb (uint16_t port , uint8_t val ) {
22+ __asm__ volatile ("outb %0, %1" : : "a" (val ), "Nd" (port ));
23+ }
24+
2025void reboot (void ) {
2126 klog ("reboot triggered" );
2227 asm volatile (
@@ -26,12 +31,57 @@ void reboot(void) {
2631 );
2732}
2833
34+ // NOTE: This probably won't work for the current qemu run command for testing.
35+ // If not, try: qemu-system-i386 -fda floppy.img -hda rootfs/kfs.img -device isa-debug-exit,iobase=0x501,iosize=0x1
36+ void shutdown (void ) {
37+ klog ("shutdown triggered\n" );
38+
39+ // QEMU ISA debug exit
40+ outb (0x501 , 0x00 ); // Exit with code 0
41+
42+ // Try ACPI shutdown
43+ outb (0xB004 , 0x2000 ); // Bochs/QEMU
44+ outb (0x604 , 0x2000 ); // QEMU (but newer)
45+ outb (0x4004 , 0x3400 ); // VirtualBox
46+
47+ // Try writing to ACPI PM1a control register
48+ outb (0x600 , 0x34 );
49+ outb (0xb004 , 0x2000 );
50+
51+ // If ACPI didn't work, try APM
52+ asm volatile (
53+ "mov $0x5301, %%ax\n"
54+ "xor %%bx, %%bx\n"
55+ "int $0x15\n"
56+ "jc apm_fail\n"
57+
58+ "mov $0x5308, %%ax\n"
59+ "mov $1, %%bx\n"
60+ "mov $1, %%cx\n"
61+ "int $0x15\n"
62+
63+ "mov $0x5307, %%ax\n"
64+ "mov $1, %%bx\n"
65+ "mov $3, %%cx\n"
66+ "int $0x15\n"
67+
68+ "apm_fail:\n"
69+ ::: "ax" , "bx" , "cx"
70+ );
71+
72+ klog ("shutdown failed - halting\n" );
73+ asm volatile ("cli" );
74+ for (;;) {
75+ asm volatile ("hlt" );
76+ }
77+ }
2978
3079void sh (void ) {
3180 klog ("sh: scheduler and elfs are not properly implemented yet. dropping into temporary shell.\n" );
3281
3382 char chars [128 ];
3483 int i ;
84+ static uint8_t cat_buffer [MAX_CAT_SIZE ]; // Static buffer to avoid stack overflow
3585
3686 for (;;) {
3787 puts ("// " );
@@ -49,9 +99,13 @@ void sh(void) {
4999 putc ('\b' );
50100 }
51101 } else {
102+ if ((unsigned int )i >= sizeof (chars ) - 1 ) {
103+ chars [i ] = 0 ;
104+ break ;
105+ }
52106 putc (c );
53107 chars [i ++ ] = c ;
54- if (c == '\n' || ( unsigned int ) i >= sizeof ( chars ) - 1 ) {
108+ if (c == '\n' ) {
55109 chars [i - 1 ] = 0 ;
56110 break ;
57111 }
@@ -79,23 +133,39 @@ void sh(void) {
79133 struct kfs_file * f = kfs_find (chars + 4 );
80134 if (!f ) {
81135 printf ("cat: %s: not found\n" , chars + 4 );
136+ } else if (f -> size > MAX_CAT_SIZE ) {
137+ printf ("cat: file too large (max %d bytes)\n" , MAX_CAT_SIZE );
82138 } else {
83- uint8_t data [ (f -> size + 511 ) & ~511 ] ;
84- if (kfs_read (f -> name , data ) < 0 ) {
139+ uint32_t rounded_size = (f -> size + 511 ) & ~511 ;
140+ if (kfs_read (f -> name , cat_buffer ) < 0 ) {
85141 puts ("kfs: ioerr\n" );
86142 } else {
87143 for (uint32_t j = 0 ; j < f -> size ; j ++ )
88- putc (data [j ]);
144+ putc (cat_buffer [j ]);
89145 putc ('\n' );
90146 }
91147 }
92148 }
93149 else if (CMD_COMP ("reboot" )) {
94150 reboot ();
95151 }
152+ else if (CMD_COMP ("shutdown" )) {
153+ shutdown ();
154+ }
96155 else if (CMD_COMP ("exec" )) {
97156 exec (chars + 5 ) == ERR_FORMAT ? puts ("exec: format error\n" ) : 0 ;
98157 }
158+
159+ // Placeholder for now
160+ // Don't remove these comments until there is a proper implementation for elf.
161+ // AHEM *gingrspacecadet*
162+ // - Bryson
163+
164+ /*else if (CMD_COMP("elf")) {
165+ extern int elfExec(const char* name, void** entry, struct uexAlloc* out_alloc);
166+ elfExec(chars + 4, NULL, NULL);
167+ }
168+ */
99169 else if (CMD_COMP ("help" )) {
100170 puts ("Available commands:\n"
101171 " version - show kernel version\n"
@@ -104,7 +174,9 @@ void sh(void) {
104174 " exec <file> - execute UEX file\n"
105175 " clear - clear the screen\n"
106176 " help - show this help message\n"
107- " touch <file> - create an empty file\n" );
177+ " touch <file> - create an empty file\n"
178+ " reboot - reboot the system\n"
179+ " shutdown - power off the system\n" );
108180 } else if (chars [0 ] != 0 ) {
109181 printf ("%s: command not found\n" , chars );
110182 }
0 commit comments