bugfixes, init program, hello world
This commit is contained in:
		
							parent
							
								
									cbc85f6e89
								
							
						
					
					
						commit
						73bb0e4864
					
				
					 17 changed files with 99 additions and 59 deletions
				
			
		|  | @ -1 +1 @@ | |||
| /bin/shell.ple | ||||
| BIN/HELLO.ELF | ||||
							
								
								
									
										16
									
								
								makefile
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								makefile
									
										
									
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
| disk: kernel boot skel init #psch
 | ||||
| disk: kernel boot skel init hello | ||||
| 	mkdir -p obj out | ||||
| 	/sbin/mkfs.fat -C -f 1 -F 16 -n "PORTLAND OS" -R 65 -s 1 -S 512 obj/shadow.img 8192 | ||||
| 	echo -n -e '\xeb\x3c' > obj/jmp.bin | ||||
|  | @ -32,16 +32,15 @@ init: knob | |||
| 	gcc ${ugccargs} -c src/user/init/main.c -o obj/init/main.o | ||||
| 
 | ||||
| 	ld -T src/user/elf.ld obj/init/main.o obj/knob.o -o obj/init.elf | ||||
| 	cp obj/init.elf out/fs/bin/init.elf | ||||
| 	objcopy -S obj/init.elf out/fs/bin/init.elf | ||||
| 
 | ||||
| psch: knob | ||||
| 	mkdir -p obj/psch out/fs/bin | ||||
| hello: knob | ||||
| 	mkdir -p obj/hello out/fs/bin | ||||
| 
 | ||||
| 	gcc ${ugccargs} -c src/user/psch/main.c -o obj/psch/main.o | ||||
| 	gcc ${ugccargs} -c src/user/psch/data.c -o obj/psch/data.o | ||||
| 	gcc ${ugccargs} -c src/user/hello/hello.c -o obj/hello/hello.o | ||||
| 
 | ||||
| 	ld -T src/user/elf.ld obj/psch/*.o obj/knob.o -o obj/psch.elf | ||||
| 	cp obj/psch.elf out/fs/bin/psch.elf | ||||
| 	ld -T src/user/elf.ld obj/hello/hello.o obj/knob.o -o obj/hello.elf | ||||
| 	objcopy -S obj/hello.elf out/fs/bin/hello.elf | ||||
| 
 | ||||
| knob: | ||||
| 	mkdir -p obj/knob | ||||
|  | @ -52,6 +51,7 @@ knob: | |||
| 	gcc ${ugccargs} -c src/user/knob/heap.c    -o obj/knob/heap.o | ||||
| 	gcc ${ugccargs} -c src/user/knob/quit.c    -o obj/knob/quit.o | ||||
| 	gcc ${ugccargs} -c src/user/knob/user.c    -o obj/knob/user.o | ||||
| 	gcc ${ugccargs} -c src/user/knob/task.c    -o obj/knob/task.o | ||||
| 	nasm ${nasmargs}   src/user/knob/entry.asm -o obj/knob/entry.o | ||||
| 
 | ||||
| 	ld ${partlink} obj/knob/*.o -o obj/knob.o | ||||
|  |  | |||
|  | @ -107,6 +107,7 @@ bool try_elf_run(const struct drive *d, const char *path) { | |||
|   } | ||||
| 
 | ||||
|   free_pages(phtable, phtable_pages); | ||||
|   d->free_file(d, h); | ||||
| 
 | ||||
|   struct task_state tstate; | ||||
|   tstate.page_directory = pd; | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ syscall_isr: | |||
| quit_isr: | ||||
|   push dword [active_task] | ||||
|   call delete_task | ||||
|   push yield_isr.return_to_task | ||||
|   mov dword [esp], yield_isr.return_to_task | ||||
|   jmp advance_active_task | ||||
| 
 | ||||
| yield_isr: | ||||
|  |  | |||
|  | @ -1,20 +1,26 @@ | |||
| #include "vga.h" | ||||
| #include "serial.h" | ||||
| #include "log.h" | ||||
| 
 | ||||
| #define INFO_COM COM1 | ||||
| #define LOG_COM COM1 | ||||
| 
 | ||||
| void init_log() { | ||||
|   vga_set_color(0x30); | ||||
|   vga_blank(); | ||||
| static const uint8_t log_mode_colors[] = { | ||||
|   0x30, | ||||
|   0x07, | ||||
|   0x4f | ||||
| }; | ||||
| 
 | ||||
| void set_log_mode(enum log_mode mode) { | ||||
|   vga_set_color(log_mode_colors[mode]); | ||||
| } | ||||
| 
 | ||||
| void logch(char ch) { | ||||
|   if (ch == '\n') { | ||||
|     sout(INFO_COM, (uint8_t)'\r'); | ||||
|     sout(INFO_COM, (uint8_t)'\n'); | ||||
|     sout(LOG_COM, (uint8_t)'\r'); | ||||
|     sout(LOG_COM, (uint8_t)'\n'); | ||||
|   } | ||||
|   else | ||||
|     sout(INFO_COM, (uint8_t)ch); | ||||
|     sout(LOG_COM, (uint8_t)ch); | ||||
| 
 | ||||
|   vga_printch(ch); | ||||
| } | ||||
|  |  | |||
|  | @ -1,7 +1,14 @@ | |||
| #ifndef LOG_H | ||||
| #define LOG_H | ||||
| 
 | ||||
| enum log_mode { | ||||
|   LOG_SYSTEM, | ||||
|   LOG_USER, | ||||
|   LOG_PANIC | ||||
| }; | ||||
| 
 | ||||
| void init_log(); | ||||
| void set_log_mode(enum log_mode mode); | ||||
| 
 | ||||
| void logch(char ch); | ||||
| void logsz(const char *sz); | ||||
|  |  | |||
|  | @ -10,8 +10,8 @@ | |||
| #include "pmap.h" | ||||
| #include "task.h" | ||||
| #include "pci.h" | ||||
| #include "log.h" | ||||
| #include "elf.h" | ||||
| #include "log.h" | ||||
| #include "vga.h" | ||||
| 
 | ||||
| void reset_tree(); | ||||
|  | @ -27,7 +27,8 @@ void main() { | |||
|   init_paging(); | ||||
|   init_tasks(); | ||||
|   init_serial(); | ||||
|   init_log(); | ||||
|   set_log_mode(LOG_SYSTEM); | ||||
|   vga_blank(); | ||||
| 
 | ||||
|   logsz("Portland v0.0.11\n\n"); | ||||
| 
 | ||||
|  | @ -146,6 +147,7 @@ void main() { | |||
| 
 | ||||
|   init_idt(); | ||||
| 
 | ||||
|   vga_set_color(0x07); | ||||
|   set_log_mode(LOG_USER); | ||||
|   logch('\n'); | ||||
|   _start_user_mode(); | ||||
| } | ||||
|  | @ -3,7 +3,7 @@ | |||
| #include "vga.h" | ||||
| 
 | ||||
| void panic(const char *message) { | ||||
|   vga_set_color(0x4f); | ||||
|   set_log_mode(LOG_PANIC); | ||||
|   vga_blank(); | ||||
|   logsz("Kernel panic: "); | ||||
|   logsz(message); | ||||
|  |  | |||
|  | @ -79,7 +79,9 @@ void advance_active_task() { | |||
|     if (++active_task == tasks + MAX_TASKS) | ||||
|       active_task = tasks; | ||||
|     if (active_task == prev_task) { | ||||
|       logsz("No active tasks.\nHalting."); | ||||
|       logch('\n'); | ||||
|       set_log_mode(LOG_SYSTEM); | ||||
|       logsz("\nNo active tasks, halting."); | ||||
|       while (1) | ||||
|         asm ("hlt"); | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										5
									
								
								src/user/hello/hello.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/user/hello/hello.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| #include <knob/user.h> | ||||
| 
 | ||||
| void main() { | ||||
|   tell_user_sz("\nHello, world!\nThis is a userspace program that has been started by init."); | ||||
| } | ||||
|  | @ -1,8 +0,0 @@ | |||
| #ifndef KNOB_BLOCK_H | ||||
| #define KNOB_BLOCK_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| void blockcpy(void *to, const void *from, uint32_t count); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -5,6 +5,8 @@ | |||
| 
 | ||||
| struct file; | ||||
| 
 | ||||
| const char *remove_prefix(const char *path, uint8_t *dn_out); | ||||
| 
 | ||||
| struct file *open_file(const char *path); | ||||
| void close_file(struct file *f); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										9
									
								
								src/user/include/knob/task.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/user/include/knob/task.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| #ifndef KNOB_TASK_H | ||||
| #define KNOB_TASK_H | ||||
| 
 | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| bool try_run_command(const char *path); | ||||
| void yield_task(); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -2,6 +2,7 @@ | |||
| #define PLAND_SYSCALL_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| typedef uint32_t _file_handle_t; | ||||
| typedef uint32_t _task_handle_t; | ||||
|  | @ -120,8 +121,8 @@ static inline uint32_t _file_size(_file_handle_t handle) { | |||
|   return _sc1(_SCN_FILE_SIZE, handle); | ||||
| } | ||||
| 
 | ||||
| static inline void _start_task(_drive_number_t drive_number, char *path) { | ||||
|   _sc2(_SCN_START_TASK, drive_number, (uint32_t)path); | ||||
| static inline bool _start_task(_drive_number_t drive_number, const char *path) { | ||||
|   return (bool)_sc2(_SCN_START_TASK, drive_number, (uint32_t)path); | ||||
| } | ||||
| 
 | ||||
| static inline void _log_string(const char *sz) { | ||||
|  |  | |||
|  | @ -1,29 +1,31 @@ | |||
| #include <knob/user.h> | ||||
| #include <knob/file.h> | ||||
| #include <knob/heap.h> | ||||
| #include <knob/task.h> | ||||
| 
 | ||||
| void main() { | ||||
|   tell_user_sz("\n\nThis is a userland program.\n"); | ||||
| 
 | ||||
|   tell_user_sz("Opening sd0:TEST.TXT.\n"); | ||||
|   struct file *f = open_file("sd0:TEST.TXT"); | ||||
|   struct file *f = open_file("SYS/STARTUP.RC"); | ||||
|   if (!f) { | ||||
|     tell_user_sz("Failed to open.\n"); | ||||
|     tell_user_sz("\nCould not open SYS/STARTUP.RC"); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   tell_user_sz("Length: "); | ||||
|   uint32_t size = file_size(f); | ||||
|   tell_user_n(size); | ||||
|   tell_user_sz(" bytes\n\nContents:\n"); | ||||
| 
 | ||||
|   char *buf = get_block(size + 1); | ||||
|   read_from_file(f, size, buf); | ||||
|   buf[size] = '\0'; | ||||
|   char buf[1024]; | ||||
|   char *bufp = buf; | ||||
|   while (read_from_file(f, 1, bufp)) { | ||||
|     if (*bufp == '\n') { | ||||
|       if (bufp == buf) | ||||
|         continue; | ||||
|       *bufp = '\0'; | ||||
|       try_run_command(buf); | ||||
|       bufp = buf; | ||||
|     } | ||||
|     else | ||||
|       ++bufp; | ||||
|   } | ||||
|   if (bufp != buf) { | ||||
|     *bufp = '\0'; | ||||
|     try_run_command(buf); | ||||
|   } | ||||
| 
 | ||||
|   close_file(f); | ||||
| 
 | ||||
|   tell_user_sz(buf); | ||||
| 
 | ||||
|   tell_user_sz("\n\nGoodbye!\n"); | ||||
| } | ||||
|  |  | |||
|  | @ -9,9 +9,9 @@ struct file { | |||
|   uint32_t length; | ||||
| }; | ||||
| 
 | ||||
| static const char *try_remove_prefix(const char *path, uint8_t *dn_out) { | ||||
| const char *remove_prefix(const char *path, uint8_t *dn_out) { | ||||
|   if ((path[0] != 's') || (path[1] != 'd')) | ||||
|     return 0; | ||||
|     goto no_prefix; | ||||
| 
 | ||||
|   const char *num_part = path + 2; | ||||
|   for (uint32_t i = 0; num_part[i]; ++i) | ||||
|  | @ -19,22 +19,20 @@ static const char *try_remove_prefix(const char *path, uint8_t *dn_out) { | |||
| 
 | ||||
|       uint32_t dn_large; | ||||
|       if (!try_sntoi(num_part, i, &dn_large) || dn_large > 255) | ||||
|         return 0; | ||||
|         goto no_prefix; | ||||
| 
 | ||||
|       *dn_out = (uint8_t)dn_large; | ||||
|       return num_part + i + 1; | ||||
|     } | ||||
| 
 | ||||
|   return 0; | ||||
| no_prefix: | ||||
|   *dn_out = current_drive; | ||||
|   return path; | ||||
| } | ||||
| 
 | ||||
| struct file *open_file(const char *path) { | ||||
|   uint8_t dn; | ||||
|   const char *path_part = try_remove_prefix(path, &dn); | ||||
|   if (path_part) | ||||
|     path = path_part; | ||||
|   else | ||||
|     dn = current_drive; | ||||
|   path = remove_prefix(path, &dn); | ||||
| 
 | ||||
|   _file_handle_t h = _open_file(dn, path); | ||||
|   if (!h) | ||||
|  |  | |||
							
								
								
									
										13
									
								
								src/user/knob/task.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/user/knob/task.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| #include <stdbool.h> | ||||
| #include <pland/syscall.h> | ||||
| #include <knob/file.h> | ||||
| 
 | ||||
| bool try_run_command(const char *path) { | ||||
|   uint8_t dn; | ||||
|   path = remove_prefix(path, &dn); | ||||
|   return _start_task(dn, path); | ||||
| } | ||||
| 
 | ||||
| void yield_task() { | ||||
|   _yield_task(); | ||||
| } | ||||
		Reference in a new issue