├── .gitignore ├── Makefile ├── README.md ├── apps ├── 0shell │ ├── 0shell.c │ └── Makefile ├── Makefile ├── app.ld ├── include │ ├── app.h │ ├── common.h │ ├── console.h │ ├── kernel.h │ └── string.h ├── libcommon │ ├── Makefile │ └── libcommon.c ├── libconsole │ ├── Makefile │ └── libconsole.c ├── libkernel │ ├── Makefile │ └── libkernel.c ├── libstring │ ├── Makefile │ └── libstring.c ├── uptime │ ├── Makefile │ └── uptime.c └── whoareyou │ ├── Makefile │ └── whoareyou.c ├── boot ├── legacy_bios │ ├── Makefile │ ├── boot.ld │ └── boot.s └── uefi │ ├── Makefile │ ├── boot.c │ ├── include │ ├── common.h │ ├── efi.h │ ├── fb.h │ ├── file.h │ ├── graphics.h │ ├── gui.h │ ├── mem.h │ └── shell.h │ └── libuefi │ ├── Makefile │ ├── common.c │ ├── efi.c │ ├── fb.c │ ├── file.c │ ├── graphics.c │ ├── gui.c │ ├── mem.c │ └── shell.c ├── doc ├── Makefile └── memory_map.org ├── kernel ├── Makefile ├── common.c ├── console_io.c ├── cpu.c ├── debug.c ├── excp.c ├── fb.c ├── fbcon.c ├── font.c ├── fs.c ├── include │ ├── asm │ │ └── cpu.h │ ├── common.h │ ├── console_io.h │ ├── cpu.h │ ├── debug.h │ ├── efi.h │ ├── excp.h │ ├── fb.h │ ├── fbcon.h │ ├── font.h │ ├── fs.h │ ├── intr.h │ ├── io_port.h │ ├── kbc.h │ ├── kern_task.h │ ├── kernel.h │ ├── list.h │ ├── lock.h │ ├── memory.h │ ├── queue.h │ ├── sched.h │ ├── stddef.h │ ├── syscall.h │ ├── task.h │ └── timer.h ├── init.c ├── init_64.c ├── intr.c ├── kbc.c ├── kern_task_init.c ├── lock.c ├── memory.c ├── queue.c ├── sched.c ├── sys.S ├── sys.ld ├── sys_64.S ├── sys_64.ld ├── syscall.c ├── task.c └── timer.c └── tools ├── cap.sh └── make_os5_fs.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | *.a 4 | *.bin 5 | *.dat 6 | *.img 7 | *.efi 8 | *.map 9 | *.txt 10 | *# 11 | bin 12 | fs 13 | GPATH 14 | GRTAGS 15 | GTAGS 16 | GSYMS 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: fd.img 2 | 3 | fs: boot/uefi/boot.efi kernel/kernel_64.bin apps/apps.img 4 | mkdir -p $@/EFI/BOOT 5 | cp boot/uefi/boot.efi $@/EFI/BOOT/BOOTX64.EFI 6 | cp kernel/kernel_64.bin $@/kernel.bin 7 | cp apps/apps.img $@/apps.img 8 | 9 | fd.img: boot/legacy_bios/boot.bin kernel/kernel.bin apps/apps.img 10 | cat $+ > $@ 11 | 12 | boot/uefi/boot.efi: 13 | make -C boot/uefi 14 | 15 | boot/legacy_bios/boot.bin: 16 | make -C boot/legacy_bios 17 | 18 | kernel/kernel_64.bin: 19 | make -C kernel kernel_64.bin x86_64=true 20 | 21 | kernel/kernel.bin: 22 | make -C kernel kernel.bin 23 | 24 | apps/apps.img: 25 | make -C apps 26 | 27 | doc: 28 | make -C doc 29 | 30 | clean: 31 | make -C boot/uefi clean 32 | make -C boot/legacy_bios clean 33 | make -C kernel clean 34 | make -C apps clean 35 | make -C doc clean 36 | rm -rf *~ *.o *.bin *.dat *.img *.map fs 37 | 38 | run: run32 39 | 40 | run64: fs/EFI/BOOT/BOOTX64.EFI 41 | qemu-system-x86_64 -bios OVMF.fd -hda fat:fs 42 | 43 | run32: fd.img 44 | qemu-system-i386 -fda $< 45 | 46 | .PHONY: boot/legacy_bios/boot.bin boot/uefi/boot.efi kernel/kernel.bin \ 47 | apps/apps.img doc clean run run64 run32 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OS5 2 | 3 | ## 概要 4 | 5 | * フルスクラッチの自作OS 6 | * x86のQEMU(qemu-system-i386)で動作 7 | * 最新リリース等、詳しくは「[自作OS(OS5)のまとめ](http://funlinux.org/os5/)」 8 | 9 | ## 使い方 10 | 11 | * gcc 12 | * make 13 | * qemu 14 | 15 | しか使っていないので、 16 | 17 | 以下のDebianパッケージがインストールされていればビルドと動作確認を行えます。 18 | 19 | * build-essential 20 | * qemu 21 | 22 | 以下でビルドからqemuでの実行まで行います。 23 | 24 | `make run` 25 | 26 | ## ドキュメントについて 27 | 28 | docディレクトリ以下のドキュメントはemacsのorg-modeで記述しています。 29 | 30 | テキストファイルなのでそのままでも読めますが、`make doc`で整形されたテキストファイルへエクスポートできます。 31 | -------------------------------------------------------------------------------- /apps/0shell/0shell.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAX_LINE_SIZE 512 8 | 9 | enum { 10 | ECHO, 11 | READB, 12 | READW, 13 | READL, 14 | IOREADB, 15 | WRITEB, 16 | WRITEW, 17 | WRITEL, 18 | IOWRITEB, 19 | BG, 20 | #ifdef DEBUG 21 | TEST, 22 | #endif /* DEBUG */ 23 | COMMAND_NUM 24 | } _COMMAND_SET; 25 | 26 | static int command_echo(char *args) 27 | { 28 | put_str(args); 29 | put_str("\r\n"); 30 | 31 | return 0; 32 | } 33 | 34 | static int command_readb(char *args) 35 | { 36 | char first[128], other[128]; 37 | unsigned char *addr; 38 | 39 | str_get_first_entry(args, first, other); 40 | addr = (unsigned char *)str_conv_ahex_int(first); 41 | dump_hex(*addr, 2); 42 | put_str("\r\n"); 43 | 44 | return 0; 45 | } 46 | 47 | static int command_readw(char *args) 48 | { 49 | char first[128], other[128]; 50 | unsigned short *addr; 51 | 52 | str_get_first_entry(args, first, other); 53 | addr = (unsigned short *)str_conv_ahex_int(first); 54 | dump_hex(*addr, 4); 55 | put_str("\r\n"); 56 | 57 | return 0; 58 | } 59 | 60 | static int command_readl(char *args) 61 | { 62 | char first[128], other[128]; 63 | unsigned int *addr; 64 | 65 | str_get_first_entry(args, first, other); 66 | addr = (unsigned int *)str_conv_ahex_int(first); 67 | dump_hex(*addr, 8); 68 | put_str("\r\n"); 69 | 70 | return 0; 71 | } 72 | 73 | static int command_ioreadb(char *args) 74 | { 75 | char first[128], other[128]; 76 | unsigned short addr; 77 | 78 | str_get_first_entry(args, first, other); 79 | addr = (unsigned short)str_conv_ahex_int(first); 80 | dump_hex(inb_p(addr), 2); 81 | put_str("\r\n"); 82 | 83 | return 0; 84 | } 85 | 86 | static int command_writeb(char *args) 87 | { 88 | char first[16], second[32], other[128], _other[128]; 89 | unsigned char data, *addr; 90 | 91 | str_get_first_entry(args, first, other); 92 | str_get_first_entry(other, second, _other); 93 | data = (unsigned char)str_conv_ahex_int(first); 94 | addr = (unsigned char *)str_conv_ahex_int(second); 95 | *addr = data; 96 | 97 | return 0; 98 | } 99 | 100 | static int command_writew(char *args) 101 | { 102 | char first[16], second[32], other[128], _other[128]; 103 | unsigned short data, *addr; 104 | 105 | str_get_first_entry(args, first, other); 106 | str_get_first_entry(other, second, _other); 107 | data = (unsigned short)str_conv_ahex_int(first); 108 | addr = (unsigned short *)str_conv_ahex_int(second); 109 | *addr = data; 110 | 111 | return 0; 112 | } 113 | 114 | static int command_writel(char *args) 115 | { 116 | char first[16], second[32], other[128], _other[128]; 117 | unsigned int data, *addr; 118 | 119 | str_get_first_entry(args, first, other); 120 | str_get_first_entry(other, second, _other); 121 | data = (unsigned int)str_conv_ahex_int(first); 122 | addr = (unsigned int *)str_conv_ahex_int(second); 123 | *addr = data; 124 | 125 | return 0; 126 | } 127 | 128 | static int command_iowriteb(char *args) 129 | { 130 | char first[16], second[32], other[128], _other[128]; 131 | unsigned char data; 132 | unsigned short addr; 133 | 134 | str_get_first_entry(args, first, other); 135 | str_get_first_entry(other, second, _other); 136 | data = (unsigned char)str_conv_ahex_int(first); 137 | addr = (unsigned short)str_conv_ahex_int(second); 138 | outb_p(data, addr); 139 | 140 | return 0; 141 | } 142 | 143 | #ifdef DEBUG 144 | static int command_test(char *args) 145 | { 146 | put_str("test\r\n"); 147 | 148 | return 0; 149 | } 150 | #endif /* DEBUG */ 151 | 152 | static unsigned char get_command_id(const char *command) 153 | { 154 | if (!str_compare(command, "echo")) { 155 | return ECHO; 156 | } 157 | 158 | if (!str_compare(command, "readb")) { 159 | return READB; 160 | } 161 | 162 | if (!str_compare(command, "readw")) { 163 | return READW; 164 | } 165 | 166 | if (!str_compare(command, "readl")) { 167 | return READL; 168 | } 169 | 170 | if (!str_compare(command, "ioreadb")) { 171 | return IOREADB; 172 | } 173 | 174 | if (!str_compare(command, "writeb")) { 175 | return WRITEB; 176 | } 177 | 178 | if (!str_compare(command, "writew")) { 179 | return WRITEW; 180 | } 181 | 182 | if (!str_compare(command, "writel")) { 183 | return WRITEL; 184 | } 185 | 186 | if (!str_compare(command, "iowriteb")) { 187 | return IOWRITEB; 188 | } 189 | 190 | if (!str_compare(command, "bg")) { 191 | return BG; 192 | } 193 | 194 | #ifdef DEBUG 195 | if (!str_compare(command, "test")) { 196 | return TEST; 197 | } 198 | #endif /* DEBUG */ 199 | 200 | return COMMAND_NUM; 201 | } 202 | 203 | int main(int argc __attribute__ ((unused)), 204 | char *argv[] __attribute__ ((unused))) 205 | { 206 | while (1) { 207 | char buf[MAX_LINE_SIZE]; 208 | char command[256], args[256]; 209 | unsigned char command_id, is_background = 0; 210 | unsigned int fp; 211 | 212 | put_str("OS5> "); 213 | if (get_line(buf, MAX_LINE_SIZE) <= 0) { 214 | continue; 215 | } 216 | 217 | while (1) { 218 | str_get_first_entry(buf, command, args); 219 | command_id = get_command_id(command); 220 | if (command_id != BG) 221 | break; 222 | else { 223 | is_background = 1; 224 | copy_mem(args, buf, 225 | (unsigned int)str_get_len(args)); 226 | } 227 | } 228 | 229 | switch (command_id) { 230 | case ECHO: 231 | command_echo(args); 232 | break; 233 | case READB: 234 | command_readb(args); 235 | break; 236 | case READW: 237 | command_readw(args); 238 | break; 239 | case READL: 240 | command_readl(args); 241 | break; 242 | case IOREADB: 243 | command_ioreadb(args); 244 | break; 245 | case WRITEB: 246 | command_writeb(args); 247 | break; 248 | case WRITEW: 249 | command_writew(args); 250 | break; 251 | case WRITEL: 252 | command_writel(args); 253 | break; 254 | case IOWRITEB: 255 | command_iowriteb(args); 256 | break; 257 | #ifdef DEBUG 258 | case TEST: 259 | command_test(args); 260 | break; 261 | #endif /* DEBUG */ 262 | default: 263 | fp = syscall(SYSCALL_OPEN, (unsigned int)command, 0, 0); 264 | if (fp) { 265 | unsigned int argc = 0, i; 266 | char *argv[256]; 267 | char *start; 268 | 269 | argv[argc++] = command; 270 | 271 | start = &args[0]; 272 | for (i = 0; ; i++) { 273 | if ((i == 0) && (args[i] == '\0')) { 274 | break; 275 | } else if ((args[i] == ' ') || 276 | (args[i] == '\0')) { 277 | argv[argc++] = start; 278 | start = &args[i + 1]; 279 | if (args[i] == ' ') 280 | args[i] = '\0'; 281 | else 282 | break; 283 | } 284 | } 285 | 286 | syscall(SYSCALL_EXEC, fp, argc, 287 | (unsigned int)argv); 288 | 289 | if (!is_background) 290 | syscall(SYSCALL_SCHED_WAKEUP_EVENT, 291 | EVENT_TYPE_EXIT, 0, 0); 292 | } else 293 | put_str("Command not found.\r\n"); 294 | break; 295 | } 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /apps/0shell/Makefile: -------------------------------------------------------------------------------- 1 | NAME=0shell 2 | 3 | $(BIN_DIR)/$(NAME): $(NAME).o 4 | ld -m elf_i386 -o $@ $< -Map $(NAME).map -s -T $(APP_LD) -x \ 5 | $(LDFLAGS) $(LIBS) 6 | 7 | %.o: %.c 8 | gcc $(CFLAGS) -o $@ $< 9 | 10 | clean: 11 | rm -rf *~ *.o *.map 12 | 13 | .PHONY: clean 14 | -------------------------------------------------------------------------------- /apps/Makefile: -------------------------------------------------------------------------------- 1 | LIB_DIR = .lib 2 | BIN_DIR = .bin 3 | APP_LD = ../app.ld 4 | LIB_DIRS = libkernel libcommon libconsole libstring 5 | APP_DIRS = $(shell find . -maxdepth 1 -type d '!' -iname '.*' '!' \ 6 | -iname 'include' '!' -iname 'lib*') 7 | CFLAGS = -Wall -Wextra 8 | CFLAGS += -nostdinc -nostdlib -fno-builtin -c 9 | CFLAGS += -I../include 10 | CFLAGS += -m32 11 | CFLAGS += -DCOMPILE_APP 12 | LDFLAGS = -L../$(LIB_DIR) 13 | LIBS = -lstring -lconsole -lcommon -lkernel 14 | 15 | apps.img: lib app 16 | ../tools/make_os5_fs.sh $(BIN_DIR)/* > $@ 17 | 18 | lib: $(LIB_DIRS) 19 | [ -d $(LIB_DIR) ] || mkdir $(LIB_DIR) 20 | for libdir in $^; do \ 21 | make -C $$libdir LIB_DIR=../$(LIB_DIR) \ 22 | APP_LD=$(APP_LD) CFLAGS="$(CFLAGS)" \ 23 | LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)"; \ 24 | done 25 | 26 | app: $(APP_DIRS) 27 | [ -d $(BIN_DIR) ] || mkdir $(BIN_DIR) 28 | for appdir in $^; do \ 29 | make -C $$appdir BIN_DIR=../$(BIN_DIR) \ 30 | APP_LD=$(APP_LD) CFLAGS="$(CFLAGS)" \ 31 | LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)"; \ 32 | done 33 | 34 | clean: 35 | rm -rf *~ *.o *.a *.bin *.dat *.img *.map $(LIB_DIR) $(BIN_DIR) 36 | for dir in $(LIB_DIRS) $(APP_DIRS); do \ 37 | make -C $$dir clean; \ 38 | done 39 | 40 | .PHONY: lib app clean 41 | -------------------------------------------------------------------------------- /apps/app.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("binary"); 2 | 3 | SECTIONS 4 | { 5 | . = 0x20000030; 6 | .text : { 7 | *(.entry) 8 | *(.text) 9 | } 10 | .rodata : { 11 | *(.strings) 12 | *(.rodata) 13 | *(.rodata.*) 14 | } 15 | .data : {*(.data)} 16 | .bss : {*(.bss)} 17 | } 18 | -------------------------------------------------------------------------------- /apps/include/app.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_H_ 2 | #define _APP_H_ 3 | 4 | int main(int argc, char *argv[]) __attribute__((section(".entry"))); 5 | 6 | #endif /* _APP_H_ */ 7 | -------------------------------------------------------------------------------- /apps/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_H_ 2 | #define _COMMON_H_ 3 | 4 | int pow(int num, int multer); 5 | void copy_mem(const void *src, void *dst, unsigned int size); 6 | 7 | #endif /* _COMMON_H_ */ 8 | -------------------------------------------------------------------------------- /apps/include/console.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONSOLE_H_ 2 | #define _CONSOLE_H_ 3 | 4 | unsigned int get_cursor_pos_y(void); 5 | void put_str(char *str); 6 | void put_str_pos(char *str, unsigned char x, unsigned char y); 7 | void dump_hex(unsigned int val, unsigned int num_digits); 8 | void dump_hex_pos(unsigned int val, unsigned int num_digits, 9 | unsigned char x, unsigned char y); 10 | unsigned int get_line(char *buf, unsigned int buf_size); 11 | 12 | #endif /* _CONSOLE_H_ */ 13 | -------------------------------------------------------------------------------- /apps/include/kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _APP_KERNEL_H_ 2 | #define _APP_KERNEL_H_ 3 | 4 | #include "../../kernel/include/kernel.h" 5 | #include "../../kernel/include/io_port.h" 6 | #include "../../kernel/include/console_io.h" 7 | 8 | unsigned int syscall(unsigned int syscall_id, unsigned int arg1, 9 | unsigned int arg2, unsigned int arg3); 10 | unsigned int get_global_counter(void); 11 | void exit(void); 12 | 13 | #endif /* _APP_KERNEL_H_ */ 14 | -------------------------------------------------------------------------------- /apps/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_ 2 | #define _STRING_H_ 3 | 4 | int str_get_len(const char *src); 5 | int str_find_char(const char *src, char key); 6 | void str_get_first_entry(const char *line, char *first, char *other); 7 | int str_conv_ahex_int(const char *hex_str); 8 | int str_compare(const char *src, const char *dst); 9 | 10 | #endif /* _STRING_H_ */ 11 | -------------------------------------------------------------------------------- /apps/libcommon/Makefile: -------------------------------------------------------------------------------- 1 | NAME=libcommon 2 | 3 | $(LIB_DIR)/$(NAME).a: $(NAME).o 4 | ar rcs $@ $< 5 | 6 | %.o: %.c 7 | gcc $(CFLAGS) -o $@ $< 8 | 9 | clean: 10 | rm -rf *~ *.o *.a *.map 11 | 12 | .PHONY: clean 13 | -------------------------------------------------------------------------------- /apps/libcommon/libcommon.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int pow(int num, int multer) 4 | { 5 | if (multer == 0) return 1; 6 | return pow(num, multer - 1) * num; 7 | } 8 | 9 | void copy_mem(const void *src, void *dst, unsigned int size) 10 | { 11 | unsigned char *d = (unsigned char *)dst; 12 | unsigned char *s = (unsigned char *)src; 13 | 14 | for (; size > 0; size--) { 15 | *d = *s; 16 | d++; 17 | s++; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/libconsole/Makefile: -------------------------------------------------------------------------------- 1 | NAME=libconsole 2 | 3 | $(LIB_DIR)/$(NAME).a: $(NAME).o 4 | ar rcs $@ $< 5 | 6 | %.o: %.c 7 | gcc $(CFLAGS) -o $@ $< 8 | 9 | clean: 10 | rm -rf *~ *.o *.a *.map 11 | 12 | .PHONY: clean 13 | -------------------------------------------------------------------------------- /apps/libconsole/libconsole.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unsigned int get_cursor_pos_y(void) 5 | { 6 | return syscall(SYSCALL_CON_GET_CURSOR_POS_Y, 0, 0, 0); 7 | } 8 | 9 | void put_str(char *str) 10 | { 11 | syscall(SYSCALL_CON_PUT_STR, (unsigned int)str, 0, 0); 12 | } 13 | 14 | void put_str_pos(char *str, unsigned char x, unsigned char y) 15 | { 16 | syscall(SYSCALL_CON_PUT_STR_POS, (unsigned int)str, 17 | (unsigned int)x, (unsigned int)y); 18 | } 19 | 20 | void dump_hex(unsigned int val, unsigned int num_digits) 21 | { 22 | syscall(SYSCALL_CON_DUMP_HEX, val, num_digits, 0); 23 | } 24 | 25 | void dump_hex_pos(unsigned int val, unsigned int num_digits, 26 | unsigned char x, unsigned char y) 27 | { 28 | syscall(SYSCALL_CON_DUMP_HEX_POS, val, num_digits, 29 | (unsigned int)((x << 16) | y)); 30 | } 31 | 32 | unsigned int get_line(char *buf, unsigned int buf_size) 33 | { 34 | return syscall(SYSCALL_CON_GET_LINE, (unsigned int)buf, buf_size, 0); 35 | } 36 | -------------------------------------------------------------------------------- /apps/libkernel/Makefile: -------------------------------------------------------------------------------- 1 | NAME=libkernel 2 | 3 | $(LIB_DIR)/$(NAME).a: $(NAME).o 4 | ar rcs $@ $< 5 | 6 | %.o: %.c 7 | gcc $(CFLAGS) -o $@ $< 8 | 9 | clean: 10 | rm -rf *~ *.o *.a *.map 11 | 12 | .PHONY: clean 13 | -------------------------------------------------------------------------------- /apps/libkernel/libkernel.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned int syscall(unsigned int syscall_id, unsigned int arg1, 4 | unsigned int arg2, unsigned int arg3) 5 | { 6 | unsigned int result; 7 | 8 | __asm__ ( 9 | "\tint $0x80\n" 10 | :"=a"(result) 11 | :"a"(syscall_id), "b"(arg1), "c"(arg2), "d"(arg3)); 12 | 13 | return result; 14 | } 15 | 16 | unsigned int get_global_counter(void) 17 | { 18 | return syscall(SYSCALL_TIMER_GET_GLOBAL_COUNTER, 0, 0, 0); 19 | } 20 | 21 | void exit(void) 22 | { 23 | syscall(SYSCALL_EXIT, 0, 0, 0); 24 | } 25 | -------------------------------------------------------------------------------- /apps/libstring/Makefile: -------------------------------------------------------------------------------- 1 | NAME=libstring 2 | 3 | $(LIB_DIR)/$(NAME).a: $(NAME).o 4 | ar rcs $@ $< 5 | 6 | %.o: %.c 7 | gcc $(CFLAGS) -o $@ $< 8 | 9 | clean: 10 | rm -rf *~ *.o *.a *.map 11 | 12 | .PHONY: clean 13 | -------------------------------------------------------------------------------- /apps/libstring/libstring.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int str_get_len(const char *src) 5 | { 6 | int len; 7 | for (len = 0; src[len] != '\0'; len++); 8 | return len + 1; 9 | } 10 | 11 | int str_find_char(const char *src, char key) 12 | { 13 | int i; 14 | 15 | for (i = 0; src[i] != key; i++) { 16 | if (src[i] == '\0') { 17 | i = -1; 18 | break; 19 | } 20 | } 21 | 22 | return i; 23 | } 24 | 25 | void str_get_first_entry(const char *line, char *first, char *other) 26 | { 27 | int line_len, first_len, other_len; 28 | 29 | line_len = str_get_len(line); 30 | first_len = str_find_char(line, ' '); 31 | if (first_len < 0) { 32 | copy_mem((void *)line, (void *)first, line_len); 33 | first_len = line_len; 34 | other_len = 0; 35 | other[other_len] = '\0'; 36 | } else { 37 | copy_mem((void *)line, (void *)first, first_len); 38 | first[first_len] = '\0'; 39 | first_len++; 40 | other_len = line_len - first_len; 41 | copy_mem((void *)(line + first_len), (void *)other, other_len); 42 | } 43 | 44 | #ifdef DEBUG 45 | shell_put_str(line); 46 | shell_put_str("|"); 47 | shell_put_str(first); 48 | shell_put_str(":"); 49 | shell_put_str(other); 50 | shell_put_str("\r\n"); 51 | #endif /* DEBUG */ 52 | } 53 | 54 | int str_conv_ahex_int(const char *hex_str) 55 | { 56 | int len = str_get_len(hex_str); 57 | int val = 0, i; 58 | 59 | for (i = 0; hex_str[i] != '\0'; i++) { 60 | if (('0' <= hex_str[i]) && (hex_str[i] <= '9')) { 61 | val += (hex_str[i] - '0') * pow(16, len - 2 - i); 62 | } else { 63 | val += (hex_str[i] - 'a' + 10) * pow(16, len - 2 - i); 64 | } 65 | } 66 | 67 | return val; 68 | } 69 | 70 | int str_compare(const char *src, const char *dst) 71 | { 72 | char is_equal = 1; 73 | 74 | for (; (*src != '\0') && (*dst != '\0'); src++, dst++) { 75 | if (*src != *dst) { 76 | is_equal = 0; 77 | break; 78 | } 79 | } 80 | 81 | if (is_equal) { 82 | if (*src != '\0') { 83 | return 1; 84 | } else if (*dst != '\0') { 85 | return -1; 86 | } else { 87 | return 0; 88 | } 89 | } else { 90 | return (int)(*src - *dst); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /apps/uptime/Makefile: -------------------------------------------------------------------------------- 1 | NAME=uptime 2 | 3 | $(BIN_DIR)/$(NAME): $(NAME).o 4 | ld -m elf_i386 -o $@ $< -Map $(NAME).map -s -T $(APP_LD) -x \ 5 | $(LDFLAGS) $(LIBS) 6 | 7 | %.o: %.c 8 | gcc $(CFLAGS) -o $@ $< 9 | 10 | clean: 11 | rm -rf *~ *.o *.map 12 | 13 | .PHONY: clean 14 | -------------------------------------------------------------------------------- /apps/uptime/uptime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc __attribute__ ((unused)), 6 | char *argv[] __attribute__ ((unused))) 7 | { 8 | static unsigned int uptime; 9 | unsigned int cursor_pos_y; 10 | 11 | while (1) { 12 | uptime = get_global_counter() / 1000; 13 | cursor_pos_y = get_cursor_pos_y(); 14 | if (cursor_pos_y < ROWS) { 15 | put_str_pos("uptime:", COLUMNS - (7 + 4), 0); 16 | dump_hex_pos(uptime, 4, COLUMNS - 4, 0); 17 | } else { 18 | put_str_pos("uptime:", COLUMNS - (7 + 4), 19 | cursor_pos_y - ROWS + 1); 20 | dump_hex_pos(uptime, 4, COLUMNS - 4, 21 | cursor_pos_y - ROWS + 1); 22 | } 23 | syscall(SYSCALL_SCHED_WAKEUP_MSEC, 33, 0, 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /apps/whoareyou/Makefile: -------------------------------------------------------------------------------- 1 | NAME=whoareyou 2 | 3 | $(BIN_DIR)/$(NAME): $(NAME).o 4 | ld -m elf_i386 -o $@ $< -Map $(NAME).map -s -T $(APP_LD) -x \ 5 | $(LDFLAGS) $(LIBS) 6 | 7 | %.o: %.c 8 | gcc $(CFLAGS) -o $@ $< 9 | 10 | clean: 11 | rm -rf *~ *.o *.map 12 | 13 | .PHONY: clean 14 | -------------------------------------------------------------------------------- /apps/whoareyou/whoareyou.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | if ((argc >= 2) && !str_compare(argv[1], "-v")) 9 | put_str("Operating System 5\r\n"); 10 | else 11 | put_str("OS5\r\n"); 12 | exit(); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /boot/legacy_bios/Makefile: -------------------------------------------------------------------------------- 1 | .s.o: 2 | as --32 -o $@ $< 3 | 4 | boot.bin: boot.o 5 | ld -m elf_i386 -o $@ $< -T boot.ld -Map boot.map 6 | 7 | boot.o: boot.s 8 | 9 | clean: 10 | rm -f *~ *.o *.bin *.dat *.img *.map 11 | 12 | .PHONY: clean 13 | -------------------------------------------------------------------------------- /boot/legacy_bios/boot.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("binary"); 2 | 3 | SECTIONS 4 | { 5 | .text : {*(.text)} 6 | .rodata : { 7 | *(.strings) 8 | *(.rodata) 9 | *(.rodata.*) 10 | } 11 | .data : {*(.data)} 12 | .bss : {*(.bss)} 13 | 14 | . = 510; 15 | .sign : {SHORT(0xaa55)} 16 | } 17 | -------------------------------------------------------------------------------- /boot/legacy_bios/boot.s: -------------------------------------------------------------------------------- 1 | .code16 2 | 3 | .text 4 | cli 5 | 6 | movw $0x07c0, %ax 7 | movw %ax, %ds 8 | movw $0x0000, %ax 9 | movw %ax, %ss 10 | movw $0x1000, %sp 11 | 12 | /* ビデオモード設定(画面クリア) */ 13 | movw $0x0003, %ax 14 | int $0x10 15 | 16 | movw $msg_welcome, %si 17 | call print_msg 18 | 19 | movw $msg_now_loading, %si 20 | call print_msg 21 | 22 | /* ディスクサービス セクタ読み込み 23 | * int 0x13, AH=0x02 24 | * 入力 25 | * - AL: 読み込むセクタ数 26 | * - CH: トラックの下位8ビット 27 | * - CL(上位2ビット): トラックの上位2ビット 28 | * - CL(下位6ビット): セクタを指定 29 | * - DH: ヘッド番号を指定 30 | * - DL: セクタを読み込むドライブ番号を指定 31 | * - ES: 読み込み先のセグメント指定 32 | * - BX: 読み込み先のオフセットアドレス指定 33 | * 出力 34 | * - EFLAGSのCFビット: 0=成功, 1=失敗 35 | * - AH: エラーコード(0x00=成功) 36 | * - AL: 読み込んだセクタ数 37 | * 備考 38 | * - トラック番号: 0始まり 39 | * - ヘッド番号: 0始まり 40 | * - セクタ番号: 1始まり 41 | * - セクタ数/トラック: 2HDは18 42 | * - セクタ18の次は、別トラック(裏面)へ 43 | * - 64KB境界を超えて読みだすことはできない 44 | * (その際は、2回に分ける) 45 | */ 46 | 47 | /* トラック0, ヘッド0, セクタ2以降 48 | * src: トラック0, ヘッド0のセクタ2以降 49 | * (17セクタ = 8704バイト = 0x2200バイト) 50 | * dst: 0x0000 7e00 〜 0x0000 bfff 51 | */ 52 | load_track0_head0: 53 | movw $0x0000, %ax 54 | movw %ax, %es 55 | movw $0x7e00, %bx 56 | movw $0x0000, %dx 57 | movw $0x0002, %cx 58 | movw $0x0211, %ax 59 | int $0x13 60 | jc load_track0_head0 61 | 62 | /* トラック0, ヘッド1, 全セクタ 63 | * src: トラック0, ヘッド1の全セクタ 64 | * (18セクタ = 9216バイト = 0x2400バイト) 65 | * dst: 0x0000 a000 〜 0x0000 c3ff 66 | */ 67 | load_track0_head1: 68 | movw $0x0000, %ax 69 | movw %ax, %es 70 | movw $0xa000, %bx 71 | movw $0x0100, %dx 72 | movw $0x0001, %cx 73 | movw $0x0212, %ax 74 | int $0x13 75 | jc load_track0_head1 76 | 77 | /* トラック1, ヘッド0, 全セクタ 78 | * src: トラック1, ヘッド0の全セクタ 79 | * (18セクタ = 9216バイト = 0x2400バイト) 80 | * dst: 0x0000 c400 〜 0x0000 e7ff 81 | */ 82 | load_track1_head0: 83 | movw $0x0000, %ax 84 | movw %ax, %es 85 | movw $0xc400, %bx 86 | movw $0x0000, %dx 87 | movw $0x0101, %cx 88 | movw $0x0212, %ax 89 | int $0x13 90 | jc load_track1_head0 91 | 92 | /* トラック1, ヘッド1, セクタ1 - 12 93 | * src: トラック1, ヘッド1の12セクタ 94 | * (12セクタ = 6144バイト = 0x1800バイト) 95 | * dst: 0x0000 e800 〜 0x0000 ffff 96 | */ 97 | load_track1_head1_1: 98 | movw $0x0000, %ax 99 | movw %ax, %es 100 | movw $0xe800, %bx 101 | movw $0x0100, %dx 102 | movw $0x0101, %cx 103 | movw $0x020c, %ax 104 | int $0x13 105 | jc load_track1_head1_1 106 | 107 | /* トラック1, ヘッド1, セクタ13 - 18 108 | * src: トラック1, ヘッド1の6セクタ 109 | * (6セクタ = 3072バイト = 0xc00バイト) 110 | * dst: 0x0001 0000 〜 0x0001 0bff 111 | */ 112 | load_track1_head1_2: 113 | movw $0x1000, %ax 114 | movw %ax, %es 115 | movw $0x0000, %bx 116 | movw $0x0100, %dx 117 | movw $0x010d, %cx 118 | movw $0x0206, %ax 119 | int $0x13 120 | jc load_track1_head1_2 121 | 122 | /* トラック2, ヘッド0, 全セクタ 123 | * src: トラック2, ヘッド0の全セクタ 124 | * (18セクタ = 9216バイト = 0x2400バイト) 125 | * dst: 0x0001 0c00 〜 0x0001 2fff 126 | */ 127 | load_track2_head0: 128 | movw $0x1000, %ax 129 | movw %ax, %es 130 | movw $0x0c00, %bx 131 | movw $0x0000, %dx 132 | movw $0x0201, %cx 133 | movw $0x0212, %ax 134 | int $0x13 135 | jc load_track2_head0 136 | 137 | /* トラック2, ヘッド1, 全セクタ 138 | * src: トラック2, ヘッド1の全セクタ 139 | * (18セクタ = 9216バイト = 0x2400バイト) 140 | * dst: 0x0001 3000 〜 0x0001 53ff 141 | */ 142 | load_track2_head1: 143 | movw $0x1000, %ax 144 | movw %ax, %es 145 | movw $0x3000, %bx 146 | movw $0x0100, %dx 147 | movw $0x0201, %cx 148 | movw $0x0212, %ax 149 | int $0x13 150 | jc load_track2_head1 151 | 152 | /* トラック3, ヘッド0, 全セクタ 153 | * src: トラック3, ヘッド0の全セクタ 154 | * (18セクタ = 9216バイト = 0x2400バイト) 155 | * dst: 0x0001 5400 〜 0x0001 77ff 156 | */ 157 | load_track3_head0: 158 | movw $0x1000, %ax 159 | movw %ax, %es 160 | movw $0x5400, %bx 161 | movw $0x0000, %dx 162 | movw $0x0301, %cx 163 | movw $0x0212, %ax 164 | int $0x13 165 | jc load_track3_head0 166 | 167 | /* トラック3, ヘッド1, 全セクタ 168 | * src: トラック3, ヘッド1の全セクタ 169 | * (18セクタ = 9216バイト = 0x2400バイト) 170 | * dst: 0x0001 7800 〜 0x0001 9bff 171 | */ 172 | load_track3_head1: 173 | movw $0x1000, %ax 174 | movw %ax, %es 175 | movw $0x7800, %bx 176 | movw $0x0100, %dx 177 | movw $0x0301, %cx 178 | movw $0x0212, %ax 179 | int $0x13 180 | jc load_track3_head1 181 | 182 | /* トラック4, ヘッド0, 全セクタ 183 | * src: トラック4, ヘッド0の全セクタ 184 | * (18セクタ = 9216バイト = 0x2400バイト) 185 | * dst: 0x0001 9c00 〜 0x0001 bfff 186 | */ 187 | load_track4_head0: 188 | movw $0x1000, %ax 189 | movw %ax, %es 190 | movw $0x9c00, %bx 191 | movw $0x0000, %dx 192 | movw $0x0401, %cx 193 | movw $0x0212, %ax 194 | int $0x13 195 | jc load_track4_head0 196 | 197 | /* トラック4, ヘッド1, 全セクタ 198 | * src: トラック4, ヘッド1の全セクタ 199 | * (18セクタ = 9216バイト = 0x2400バイト) 200 | * dst: 0x0001 c000 〜 0x0001 e3ff 201 | */ 202 | load_track4_head1: 203 | movw $0x1000, %ax 204 | movw %ax, %es 205 | movw $0xc000, %bx 206 | movw $0x0100, %dx 207 | movw $0x0401, %cx 208 | movw $0x0212, %ax 209 | int $0x13 210 | jc load_track4_head1 211 | 212 | /* トラック5, ヘッド0, セクタ1 - 14 213 | * src: トラック5, ヘッド0のセクタ1〜14 214 | * (14セクタ = 7168バイト = 0x1c00バイト) 215 | * dst: 0x0001 e400 〜 0x0001 ffff 216 | */ 217 | load_track5_head0_1: 218 | movw $0x1000, %ax 219 | movw %ax, %es 220 | movw $0xe400, %bx 221 | movw $0x0000, %dx 222 | movw $0x0501, %cx 223 | movw $0x020e, %ax 224 | int $0x13 225 | jc load_track5_head0_1 226 | 227 | movw $msg_completed, %si 228 | call print_msg 229 | 230 | /* マスタPICの初期化 */ 231 | movb $0x10, %al 232 | outb %al, $0x20 /* ICW1 */ 233 | movb $0x00, %al 234 | outb %al, $0x21 /* ICW2 */ 235 | movb $0x04, %al 236 | outb %al, $0x21 /* ICW3 */ 237 | movb $0x01, %al 238 | outb %al, $0x21 /* ICW4 */ 239 | movb $0xff, %al 240 | outb %al, $0x21 /* OCW1 */ 241 | 242 | /* スレーブPICの初期化 */ 243 | movb $0x10, %al 244 | outb %al, $0xa0 /* ICW1 */ 245 | movb $0x00, %al 246 | outb %al, $0xa1 /* ICW2 */ 247 | movb $0x02, %al 248 | outb %al, $0xa1 /* ICW3 */ 249 | movb $0x01, %al 250 | outb %al, $0xa1 /* ICW4 */ 251 | movb $0xff, %al 252 | outb %al, $0xa1 /* OCW1 */ 253 | 254 | call waitkbdout 255 | movb $0xd1, %al 256 | outb %al, $0x64 257 | call waitkbdout 258 | movb $0xdf, %al 259 | outb %al, $0x60 260 | call waitkbdout 261 | 262 | /* GDTを0x0009 0000から配置 */ 263 | movw $0x07c0, %ax /* src */ 264 | movw %ax, %ds 265 | movw $gdt, %si 266 | movw $0x9000, %ax /* dst */ 267 | movw %ax, %es 268 | subw %di, %di 269 | movw $12, %cx /* words */ 270 | rep movsw 271 | 272 | movw $0x07c0, %ax 273 | movw %ax, %ds 274 | lgdtw gdt_descr 275 | 276 | movw $0x0001, %ax 277 | lmsw %ax 278 | 279 | movw $2*8, %ax 280 | movw %ax, %ds 281 | movw %ax, %es 282 | movw %ax, %fs 283 | movw %ax, %gs 284 | movw %ax, %ss 285 | 286 | ljmp $8, $0x7e00 287 | 288 | print_msg: 289 | lodsb 290 | andb %al, %al 291 | jz print_msg_ret 292 | movb $0xe, %ah 293 | movw $7, %bx 294 | int $0x10 295 | jmp print_msg 296 | print_msg_ret: 297 | ret 298 | waitkbdout: 299 | inb $0x60, %al 300 | inb $0x64, %al 301 | andb $0x02, %al 302 | jnz waitkbdout 303 | ret 304 | 305 | .data 306 | gdt_descr: 307 | .word 3*8-1 308 | .word 0x0000, 0x09 309 | /* .word gdt,0x07c0 310 | * と設定しても、 311 | * GDTRには、ベースアドレスが 312 | * 0x00c0 [gdtの場所] 313 | * と読み込まれてしまう 314 | */ 315 | gdt: 316 | .quad 0x0000000000000000 /* NULL descriptor */ 317 | .quad 0x00cf9a000000ffff /* 4GB(r-x:Code) */ 318 | .quad 0x00cf92000000ffff /* 4GB(rw-:Data) */ 319 | 320 | msg_welcome: 321 | .ascii "Welcome to OS5!\r\n" 322 | .byte 0 323 | msg_now_loading: 324 | .ascii "Now Loading ... " 325 | .byte 0 326 | msg_completed: 327 | .ascii "Completed!\r\n" 328 | .byte 0 329 | -------------------------------------------------------------------------------- /boot/uefi/Makefile: -------------------------------------------------------------------------------- 1 | CC = x86_64-w64-mingw32-gcc 2 | OBJCOPY = x86_64-w64-mingw32-objcopy 3 | CFLAGS = -Wall -Wextra 4 | CFLAGS += -nostdinc -nostdlib -fno-builtin 5 | CFLAGS += -Wl,--subsystem,10 6 | 7 | boot.efi: boot.o libuefi/libuefi.a 8 | $(CC) $(CFLAGS) -e efi_main -o $@ $+ 9 | 10 | boot.o: boot.c 11 | $(CC) $(CFLAGS) -Iinclude -c -o $@ $< 12 | 13 | libuefi/libuefi.a: 14 | make -C libuefi CC=$(CC) CFLAGS="$(CFLAGS)" 15 | 16 | clean: 17 | rm -f *~ *.o 18 | make -C libuefi clean 19 | 20 | .PHONY: clean 21 | -------------------------------------------------------------------------------- /boot/uefi/boot.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define KERNEL_FILE_NAME L"kernel.bin" 8 | #define APPS_FILE_NAME L"apps.img" 9 | #define STACK_HEAP_SIZE 1048576 /* 1MB */ 10 | 11 | #define KERNEL_START 0x0000000000110000 12 | #define APPS_START 0x0000000000200000 13 | #define STACK_BASE 0x0000000000400000 14 | 15 | void efi_main(void *ImageHandle, struct EFI_SYSTEM_TABLE *SystemTable) 16 | { 17 | unsigned long long status; 18 | struct EFI_FILE_PROTOCOL *root; 19 | struct EFI_FILE_PROTOCOL *file_kernel; 20 | struct EFI_FILE_PROTOCOL *file_apps; 21 | unsigned long long kernel_size; 22 | unsigned long long apps_size; 23 | unsigned char *p; 24 | unsigned int i; 25 | unsigned long long kernel_arg1; 26 | unsigned long long kernel_arg2; 27 | unsigned char has_apps = TRUE; 28 | 29 | efi_init(SystemTable); 30 | 31 | puts(L"Starting OS5 UEFI bootloader ...\r\n"); 32 | 33 | status = SFSP->OpenVolume(SFSP, &root); 34 | assert(status, L"SFSP->OpenVolume"); 35 | 36 | 37 | /* load the kernel */ 38 | status = root->Open( 39 | root, &file_kernel, KERNEL_FILE_NAME, EFI_FILE_MODE_READ, 0); 40 | assert(status, L"root->Open(kernel)"); 41 | 42 | kernel_size = get_file_size(file_kernel); 43 | 44 | struct header { 45 | void *bss_start; 46 | unsigned long long bss_size; 47 | } head; 48 | unsigned long long head_size = sizeof(head); 49 | status = file_kernel->Read(file_kernel, &head_size, (void *)&head); 50 | assert(status, L"file_kernel->Read(head)"); 51 | 52 | kernel_size -= sizeof(head); 53 | status = file_kernel->Read(file_kernel, &kernel_size, 54 | (void *)KERNEL_START); 55 | assert(status, L"file_kernel->Read(body)"); 56 | 57 | ST->BootServices->SetMem(head.bss_start, head.bss_size, 0); 58 | 59 | puts(L"loaded kernel(first 8 bytes): "); 60 | p = (unsigned char *)KERNEL_START; 61 | for (i = 0; i < 8; i++) { 62 | puth(*p++, 2); 63 | putc(L' '); 64 | } 65 | puts(L"\r\n"); 66 | 67 | file_kernel->Close(file_kernel); 68 | 69 | 70 | /* load the applications */ 71 | status = root->Open( 72 | root, &file_apps, APPS_FILE_NAME, EFI_FILE_MODE_READ, 0); 73 | if (!check_warn_error(status, L"root->Open(apps)")) { 74 | puts(L"apps load failure. skip.\r\n"); 75 | has_apps = FALSE; 76 | } 77 | 78 | if (has_apps) { 79 | apps_size = get_file_size(file_apps); 80 | 81 | status = file_apps->Read(file_apps, &apps_size, (void *)APPS_START); 82 | assert(status, L"file_apps->Read"); 83 | 84 | puts(L"loaded apps(first 8 bytes): "); 85 | p = (unsigned char *)APPS_START; 86 | for (i = 0; i < 8; i++) { 87 | puth(*p++, 2); 88 | putc(L' '); 89 | } 90 | puts(L"\r\n"); 91 | 92 | file_apps->Close(file_apps); 93 | } 94 | 95 | 96 | kernel_arg1 = (unsigned long long)ST; 97 | init_fb(); 98 | kernel_arg2 = (unsigned long long)&fb; 99 | 100 | puts(L"kernel_arg1 = 0x"); 101 | puth(kernel_arg1, 16); 102 | puts(L"\r\n"); 103 | puts(L"kernel_arg2 = 0x"); 104 | puth(kernel_arg2, 16); 105 | puts(L"\r\n"); 106 | puts(L"stack_base = 0x"); 107 | puth(STACK_BASE, 16); 108 | puts(L"\r\n"); 109 | 110 | exit_boot_services(ImageHandle); 111 | 112 | unsigned long long _sb = STACK_BASE, _ks = KERNEL_START; 113 | __asm__ (" mov %0, %%rsi\n" 114 | " mov %1, %%rdi\n" 115 | " mov %2, %%rsp\n" 116 | " jmp *%3\n" 117 | ::"r"(kernel_arg2), "r"(kernel_arg1), "r"(_sb), "r"(_ks)); 118 | 119 | while (TRUE); 120 | } 121 | -------------------------------------------------------------------------------- /boot/uefi/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_H_ 2 | #define _COMMON_H_ 3 | 4 | #define NULL (void *)0 5 | #define TRUE 1 6 | #define FALSE 0 7 | #define SC_OFS 0x1680 8 | #define SC_ESC (SC_OFS + 0x0017) 9 | 10 | void putc(unsigned short c); 11 | void puts(unsigned short *s); 12 | void puth(unsigned long long val, unsigned char num_digits); 13 | unsigned short getc(void); 14 | unsigned int gets(unsigned short *buf, unsigned int buf_size); 15 | int strcmp(const unsigned short *s1, const unsigned short *s2); 16 | void strncpy(unsigned short *dst, unsigned short *src, unsigned long long n); 17 | unsigned long long strlen(unsigned short *str); 18 | unsigned char check_warn_error(unsigned long long status, unsigned short *name); 19 | void assert(unsigned long long status, unsigned short *message); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /boot/uefi/include/efi.h: -------------------------------------------------------------------------------- 1 | #ifndef _EFI_H_ 2 | #define _EFI_H_ 3 | 4 | #define EFI_FILE_MODE_READ 0x0000000000000001 5 | #define EFI_FILE_MODE_WRITE 0x0000000000000002 6 | #define EFI_FILE_MODE_CREATE 0x8000000000000000 7 | 8 | #define EFI_FILE_READ_ONLY 0x0000000000000001 9 | 10 | //******************************************************* 11 | // Attributes 12 | //******************************************************* 13 | #define EFI_BLACK 0x00 14 | #define EFI_BLUE 0x01 15 | #define EFI_GREEN 0x02 16 | #define EFI_CYAN 0x03 17 | #define EFI_RED 0x04 18 | #define EFI_MAGENTA 0x05 19 | #define EFI_BROWN 0x06 20 | #define EFI_LIGHTGRAY 0x07 21 | #define EFI_BRIGHT 0x08 22 | #define EFI_DARKGRAY 0x08 23 | #define EFI_LIGHTBLUE 0x09 24 | #define EFI_LIGHTGREEN 0x0A 25 | #define EFI_LIGHTCYAN 0x0B 26 | #define EFI_LIGHTRED 0x0C 27 | #define EFI_LIGHTMAGENTA 0x0D 28 | #define EFI_YELLOW 0x0E 29 | #define EFI_WHITE 0x0F 30 | 31 | #define EFI_BACKGROUND_BLACK 0x00 32 | #define EFI_BACKGROUND_BLUE 0x10 33 | #define EFI_BACKGROUND_GREEN 0x20 34 | #define EFI_BACKGROUND_CYAN 0x30 35 | #define EFI_BACKGROUND_RED 0x40 36 | #define EFI_BACKGROUND_MAGENTA 0x50 37 | #define EFI_BACKGROUND_BROWN 0x60 38 | #define EFI_BACKGROUND_LIGHTGRAY 0x70 39 | 40 | #define EFI_SUCCESS 0 41 | #define EFI_ERROR 0x8000000000000000 42 | #define EFI_UNSUPPORTED (EFI_ERROR | 3) 43 | 44 | #define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 45 | #define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 46 | #define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 47 | #define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 48 | #define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 49 | #define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 50 | 51 | #define EVT_TIMER 0x80000000 52 | #define EVT_RUNTIME 0x40000000 53 | #define EVT_NOTIFY_WAIT 0x00000100 54 | #define EVT_NOTIFY_SIGNAL 0x00000200 55 | #define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 56 | #define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 57 | 58 | #define TPL_APPLICATION 4 59 | #define TPL_CALLBACK 8 60 | #define TPL_NOTIFY 16 61 | #define TPL_HIGH_LEVEL 31 62 | 63 | struct EFI_INPUT_KEY { 64 | unsigned short ScanCode; 65 | unsigned short UnicodeChar; 66 | }; 67 | 68 | struct EFI_GUID { 69 | unsigned int Data1; 70 | unsigned short Data2; 71 | unsigned short Data3; 72 | unsigned char Data4[8]; 73 | }; 74 | 75 | enum EFI_MEMORY_TYPE { 76 | EfiReservedMemoryType, 77 | EfiLoaderCode, 78 | EfiLoaderData, 79 | EfiBootServicesCode, 80 | EfiBootServicesData, 81 | EfiRuntimeServicesCode, 82 | EfiRuntimeServicesData, 83 | EfiConventionalMemory, 84 | EfiUnusableMemory, 85 | EfiACPIReclaimMemory, 86 | EfiACPIMemoryNVS, 87 | EfiMemoryMappedIO, 88 | EfiMemoryMappedIOPortSpace, 89 | EfiPalCode, 90 | EfiMaxMemoryType 91 | }; 92 | 93 | enum EFI_TIMER_DELAY { 94 | TimerCancel, 95 | TimerPeriodic, 96 | TimerRelative 97 | }; 98 | 99 | enum EFI_RESET_TYPE { 100 | EfiResetCold, 101 | EfiResetWarm, 102 | EfiResetShutdown, 103 | EfiResetPlatformSpecific 104 | }; 105 | 106 | struct EFI_DEVICE_PATH_PROTOCOL { 107 | unsigned char Type; 108 | unsigned char SubType; 109 | unsigned char Length[2]; 110 | }; 111 | 112 | struct EFI_MEMORY_DESCRIPTOR { 113 | unsigned int Type; 114 | unsigned long long PhysicalStart; 115 | unsigned long long VirtualStart; 116 | unsigned long long NumberOfPages; 117 | unsigned long long Attribute; 118 | }; 119 | 120 | struct EFI_SYSTEM_TABLE { 121 | char _buf1[44]; 122 | struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL { 123 | unsigned long long _buf; 124 | unsigned long long (*ReadKeyStroke)( 125 | struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, 126 | struct EFI_INPUT_KEY *Key); 127 | void *WaitForKey; 128 | } *ConIn; 129 | unsigned long long _buf2; 130 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { 131 | unsigned long long _buf; 132 | unsigned long long (*OutputString)( 133 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 134 | unsigned short *String); 135 | unsigned long long (*TestString)( 136 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 137 | unsigned short *String); 138 | unsigned long long (*QueryMode)( 139 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 140 | unsigned long long ModeNumber, 141 | unsigned long long *Columns, 142 | unsigned long long *Rows); 143 | unsigned long long (*SetMode)( 144 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 145 | unsigned long long ModeNumber); 146 | unsigned long long (*SetAttribute)( 147 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 148 | unsigned long long Attribute); 149 | unsigned long long (*ClearScreen)( 150 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This); 151 | unsigned long long _buf4[2]; 152 | struct SIMPLE_TEXT_OUTPUT_MODE { 153 | int MaxMode; 154 | int Mode; 155 | int Attribute; 156 | int CursorColumn; 157 | int CursorRow; 158 | unsigned char CursorVisible; 159 | } *Mode; 160 | } *ConOut; 161 | unsigned long long _buf3[2]; 162 | struct EFI_RUNTIME_SERVICES { 163 | char _buf_rs1[24]; 164 | 165 | // 166 | // Time Services 167 | // 168 | unsigned long long _buf_rs2[4]; 169 | 170 | // 171 | // Virtual Memory Services 172 | // 173 | unsigned long long _buf_rs3[2]; 174 | 175 | // 176 | // Variable Services 177 | // 178 | unsigned long long _buf_rs4[3]; 179 | 180 | // 181 | // Miscellaneous Services 182 | // 183 | unsigned long long _buf_rs5; 184 | void (*ResetSystem)(enum EFI_RESET_TYPE ResetType, 185 | unsigned long long ResetStatus, 186 | unsigned long long DataSize, 187 | void *ResetData); 188 | } *RuntimeServices; 189 | struct EFI_BOOT_SERVICES { 190 | char _buf1[24]; 191 | 192 | // 193 | // Task Priority Services 194 | // 195 | unsigned long long _buf2[2]; 196 | 197 | // 198 | // Memory Services 199 | // 200 | unsigned long long _buf3[2]; 201 | unsigned long long (*GetMemoryMap)( 202 | unsigned long long *MemoryMapSize, 203 | struct EFI_MEMORY_DESCRIPTOR *MemoryMap, 204 | unsigned long long *MapKey, 205 | unsigned long long *DescriptorSize, 206 | unsigned int *DescriptorVersion); 207 | unsigned long long (*AllocatePool)( 208 | enum EFI_MEMORY_TYPE PoolType, 209 | unsigned long long Size, 210 | void **Buffer); 211 | unsigned long long (*FreePool)( 212 | void *Buffer); 213 | 214 | // 215 | // Event & Timer Services 216 | // 217 | unsigned long long (*CreateEvent)( 218 | unsigned int Type, 219 | unsigned long long NotifyTpl, 220 | void (*NotifyFunction)(void *Event, void *Context), 221 | void *NotifyContext, 222 | void *Event); 223 | unsigned long long (*SetTimer)(void *Event, 224 | enum EFI_TIMER_DELAY Type, 225 | unsigned long long TriggerTime); 226 | unsigned long long (*WaitForEvent)( 227 | unsigned long long NumberOfEvents, 228 | void **Event, 229 | unsigned long long *Index); 230 | unsigned long long _buf4_2[3]; 231 | 232 | // 233 | // Protocol Handler Services 234 | // 235 | unsigned long long _buf5[9]; 236 | 237 | // 238 | // Image Services 239 | // 240 | unsigned long long (*LoadImage)( 241 | unsigned char BootPolicy, 242 | void *ParentImageHandle, 243 | struct EFI_DEVICE_PATH_PROTOCOL *DevicePath, 244 | void *SourceBuffer, 245 | unsigned long long SourceSize, 246 | void **ImageHandle); 247 | unsigned long long (*StartImage)( 248 | void *ImageHandle, 249 | unsigned long long *ExitDataSize, 250 | unsigned short **ExitData); 251 | unsigned long long _buf6[2]; 252 | unsigned long long (*ExitBootServices)( 253 | void *ImageHandle, 254 | unsigned long long MapKey); 255 | 256 | // 257 | // Miscellaneous Services 258 | // 259 | unsigned long long _buf7[2]; 260 | unsigned long long (*SetWatchdogTimer)( 261 | unsigned long long Timeout, 262 | unsigned long long WatchdogCode, 263 | unsigned long long DataSize, 264 | unsigned short *WatchdogData); 265 | 266 | // 267 | // DriverSupport Services 268 | // 269 | unsigned long long _buf8[2]; 270 | 271 | // 272 | // Open and Close Protocol Services 273 | // 274 | unsigned long long (*OpenProtocol)( 275 | void *Handle, 276 | struct EFI_GUID *Protocol, 277 | void **Interface, 278 | void *AgentHandle, 279 | void *ControllerHandle, 280 | unsigned int Attributes); 281 | unsigned long long _buf9[2]; 282 | 283 | // 284 | // Library Services 285 | // 286 | unsigned long long _buf10[2]; 287 | unsigned long long (*LocateProtocol)( 288 | struct EFI_GUID *Protocol, 289 | void *Registration, 290 | void **Interface); 291 | unsigned long long _buf10_2[2]; 292 | 293 | // 294 | // 32-bit CRC Services 295 | // 296 | unsigned long long _buf11; 297 | 298 | // 299 | // Miscellaneous Services 300 | // 301 | void (*CopyMem)( 302 | void *Destination, 303 | void *Source, 304 | unsigned long long Length); 305 | void (*SetMem)( 306 | void *Buffer, 307 | unsigned long long Size, 308 | unsigned char Value); 309 | unsigned long long _buf12; 310 | } *BootServices; 311 | }; 312 | 313 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL { 314 | unsigned char Blue; 315 | unsigned char Green; 316 | unsigned char Red; 317 | unsigned char Reserved; 318 | }; 319 | 320 | struct EFI_GRAPHICS_OUTPUT_PROTOCOL { 321 | unsigned long long _buf[3]; 322 | struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE { 323 | unsigned int MaxMode; 324 | unsigned int Mode; 325 | struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION { 326 | unsigned int Version; 327 | unsigned int HorizontalResolution; 328 | unsigned int VerticalResolution; 329 | enum EFI_GRAPHICS_PIXEL_FORMAT { 330 | PixelRedGreenBlueReserved8BitPerColor, 331 | PixelBlueGreenRedReserved8BitPerColor, 332 | PixelBitMask, 333 | PixelBltOnly, 334 | PixelFormatMax 335 | } PixelFormat; 336 | } *Info; 337 | unsigned long long SizeOfInfo; 338 | unsigned long long FrameBufferBase; 339 | unsigned long long FrameBufferSize; 340 | } *Mode; 341 | }; 342 | 343 | struct EFI_SIMPLE_POINTER_STATE { 344 | int RelativeMovementX; 345 | int RelativeMovementY; 346 | int RelativeMovementZ; 347 | unsigned char LeftButton; 348 | unsigned char RightButton; 349 | }; 350 | 351 | struct EFI_SIMPLE_POINTER_PROTOCOL { 352 | unsigned long long (*Reset)( 353 | struct EFI_SIMPLE_POINTER_PROTOCOL *This, 354 | unsigned char ExtendedVerification); 355 | unsigned long long (*GetState)( 356 | struct EFI_SIMPLE_POINTER_PROTOCOL *This, 357 | struct EFI_SIMPLE_POINTER_STATE *State); 358 | void *WaitForInput; 359 | }; 360 | 361 | struct EFI_TIME { 362 | unsigned short Year; // 1900 – 9999 363 | unsigned char Month; // 1 – 12 364 | unsigned char Day; // 1 – 31 365 | unsigned char Hour; // 0 – 23 366 | unsigned char Minute; // 0 – 59 367 | unsigned char Second; // 0 – 59 368 | unsigned char Pad1; 369 | unsigned int Nanosecond; // 0 – 999,999,999 370 | unsigned short TimeZone; // -1440 to 1440 or 2047 371 | unsigned char Daylight; 372 | unsigned char Pad2; 373 | }; 374 | 375 | struct EFI_FILE_INFO { 376 | unsigned long long Size; 377 | unsigned long long FileSize; 378 | unsigned long long PhysicalSize; 379 | struct EFI_TIME CreateTime; 380 | struct EFI_TIME LastAccessTime; 381 | struct EFI_TIME ModificationTime; 382 | unsigned long long Attribute; 383 | unsigned short FileName[]; 384 | }; 385 | 386 | struct EFI_FILE_PROTOCOL { 387 | unsigned long long _buf; 388 | unsigned long long (*Open)(struct EFI_FILE_PROTOCOL *This, 389 | struct EFI_FILE_PROTOCOL **NewHandle, 390 | unsigned short *FileName, 391 | unsigned long long OpenMode, 392 | unsigned long long Attributes); 393 | unsigned long long (*Close)(struct EFI_FILE_PROTOCOL *This); 394 | unsigned long long _buf2; 395 | unsigned long long (*Read)(struct EFI_FILE_PROTOCOL *This, 396 | unsigned long long *BufferSize, 397 | void *Buffer); 398 | unsigned long long (*Write)(struct EFI_FILE_PROTOCOL *This, 399 | unsigned long long *BufferSize, 400 | void *Buffer); 401 | unsigned long long _buf3[2]; 402 | unsigned long long (*GetInfo)(struct EFI_FILE_PROTOCOL *This, 403 | struct EFI_GUID *InformationType, 404 | unsigned long long *BufferSize, 405 | void *Buffer); 406 | unsigned long long _buf4; 407 | unsigned long long (*Flush)(struct EFI_FILE_PROTOCOL *This); 408 | }; 409 | 410 | struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL { 411 | unsigned long long Revision; 412 | unsigned long long (*OpenVolume)( 413 | struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, 414 | struct EFI_FILE_PROTOCOL **Root); 415 | }; 416 | 417 | struct EFI_KEY_STATE { 418 | unsigned int KeyShiftState; 419 | unsigned char KeyToggleState; 420 | }; 421 | 422 | struct EFI_KEY_DATA { 423 | struct EFI_INPUT_KEY Key; 424 | struct EFI_KEY_STATE KeyState; 425 | }; 426 | 427 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { 428 | unsigned long long (*Reset)( 429 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 430 | unsigned char ExtendedVerification); 431 | unsigned long long (*ReadKeyStrokeEx)( 432 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 433 | struct EFI_KEY_DATA *KeyData); 434 | void *WaitForKeyEx; 435 | unsigned long long (*SetState)( 436 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 437 | unsigned char *KeyToggleState); 438 | unsigned long long (*RegisterKeyNotify)( 439 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 440 | struct EFI_KEY_DATA *KeyData, 441 | unsigned long long (*KeyNotificationFunction)( 442 | struct EFI_KEY_DATA *KeyData), 443 | void **NotifyHandle); 444 | unsigned long long (*UnregisterKeyNotify)( 445 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 446 | void *NotificationHandle); 447 | }; 448 | 449 | struct EFI_LOADED_IMAGE_PROTOCOL { 450 | unsigned int Revision; 451 | void *ParentHandle; 452 | struct EFI_SYSTEM_TABLE *SystemTable; 453 | // Source location of the image 454 | void *DeviceHandle; 455 | struct EFI_DEVICE_PATH_PROTOCOL *FilePath; 456 | void *Reserved; 457 | // Image’s load options 458 | unsigned int LoadOptionsSize; 459 | void *LoadOptions; 460 | // Location where image was loaded 461 | void *ImageBase; 462 | unsigned long long ImageSize; 463 | enum EFI_MEMORY_TYPE ImageCodeType; 464 | enum EFI_MEMORY_TYPE ImageDataType; 465 | unsigned long long (*Unload)(void *ImageHandle); 466 | }; 467 | 468 | struct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL { 469 | unsigned long long _buf; 470 | unsigned short *(*ConvertDevicePathToText)( 471 | const struct EFI_DEVICE_PATH_PROTOCOL* DeviceNode, 472 | unsigned char DisplayOnly, 473 | unsigned char AllowShortcuts); 474 | }; 475 | 476 | struct EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL { 477 | struct EFI_DEVICE_PATH_PROTOCOL *(*ConvertTextToDeviceNode) ( 478 | const unsigned short *TextDeviceNode); 479 | struct EFI_DEVICE_PATH_PROTOCOL *(*ConvertTextToDevicePath) ( 480 | const unsigned short *TextDevicePath); 481 | }; 482 | 483 | struct EFI_DEVICE_PATH_UTILITIES_PROTOCOL { 484 | unsigned long long _buf[3]; 485 | struct EFI_DEVICE_PATH_PROTOCOL *(*AppendDeviceNode)( 486 | const struct EFI_DEVICE_PATH_PROTOCOL *DevicePath, 487 | const struct EFI_DEVICE_PATH_PROTOCOL *DeviceNode); 488 | }; 489 | 490 | extern struct EFI_SYSTEM_TABLE *ST; 491 | extern struct EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP; 492 | extern struct EFI_SIMPLE_POINTER_PROTOCOL *SPP; 493 | extern struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SFSP; 494 | extern struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *STIEP; 495 | extern struct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DPTTP; 496 | extern struct EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DPFTP; 497 | extern struct EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DPUP; 498 | extern struct EFI_GUID lip_guid; 499 | extern struct EFI_GUID dpp_guid; 500 | extern struct EFI_GUID fi_guid; 501 | 502 | void efi_init(struct EFI_SYSTEM_TABLE *SystemTable); 503 | 504 | #endif 505 | -------------------------------------------------------------------------------- /boot/uefi/include/fb.h: -------------------------------------------------------------------------------- 1 | #ifndef _FB_H_ 2 | #define _FB_H_ 3 | 4 | struct fb { 5 | unsigned long long base; 6 | unsigned long long size; 7 | unsigned int hr; 8 | unsigned int vr; 9 | }; 10 | 11 | extern struct fb fb; 12 | 13 | void init_fb(void); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /boot/uefi/include/file.h: -------------------------------------------------------------------------------- 1 | #ifndef _FILE_H_ 2 | #define _FILE_H_ 3 | 4 | #include "graphics.h" 5 | 6 | #define MAX_FILE_NAME_LEN 4 7 | #define MAX_FILE_NUM 10 8 | #define MAX_FILE_BUF 1024 9 | #define FILE_INFO_BUF_SIZE 180 10 | 11 | struct FILE { 12 | struct RECT rect; 13 | unsigned char is_highlight; 14 | unsigned short name[MAX_FILE_NAME_LEN]; 15 | }; 16 | 17 | extern struct FILE file_list[MAX_FILE_NUM]; 18 | 19 | unsigned long long get_file_size(struct EFI_FILE_PROTOCOL *file); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /boot/uefi/include/graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef _GRAPHICS_H_ 2 | #define _GRAPHICS_H_ 3 | 4 | #include "efi.h" 5 | 6 | struct RECT { 7 | unsigned int x, y; 8 | unsigned int w, h; 9 | }; 10 | 11 | extern const struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL white; 12 | extern const struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL yellow; 13 | 14 | void draw_pixel(unsigned int x, unsigned int y, 15 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); 16 | void draw_rect(struct RECT r, struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL c); 17 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL get_pixel(unsigned int x, unsigned int y); 18 | unsigned char is_in_rect(unsigned int x, unsigned int y, struct RECT r); 19 | void blt(unsigned char img[], unsigned int img_width, unsigned int img_height); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /boot/uefi/include/gui.h: -------------------------------------------------------------------------------- 1 | #ifndef _GUI_H_ 2 | #define _GUI_H_ 3 | 4 | void gui(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /boot/uefi/include/mem.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEM_H_ 2 | #define _MEM_H_ 3 | 4 | #define PAGE_SIZE 4096 5 | 6 | void dump_memmap(void); 7 | void init_memmap(void); 8 | struct EFI_MEMORY_DESCRIPTOR *get_allocatable_area(unsigned long long size); 9 | void exit_boot_services(void *IH); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /boot/uefi/include/shell.h: -------------------------------------------------------------------------------- 1 | #ifndef _SHELL_H_ 2 | #define _SHELL_H_ 3 | 4 | void dialogue_get_filename(int idx); 5 | void pstat(void); 6 | int ls(void); 7 | void cat(unsigned short *file_name); 8 | void edit(unsigned short *file_name); 9 | void view(unsigned short *img_name); 10 | void shell(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/Makefile: -------------------------------------------------------------------------------- 1 | AR = x86_64-w64-mingw32-ar 2 | OBJS = common.o efi.o file.o fb.o graphics.o gui.o mem.o shell.o 3 | 4 | libuefi.a: $(OBJS) 5 | $(AR) rcs $@ $^ 6 | 7 | %.o: %.c 8 | $(CC) $(CFLAGS) -I../include -c -o $@ $< 9 | 10 | clean: 11 | rm -f *~ *.o *.a 12 | 13 | .PHONY: clean 14 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MAX_STR_BUF 100 5 | 6 | void putc(unsigned short c) 7 | { 8 | unsigned short str[2] = L" "; 9 | str[0] = c; 10 | ST->ConOut->OutputString(ST->ConOut, str); 11 | } 12 | 13 | void puts(unsigned short *s) 14 | { 15 | ST->ConOut->OutputString(ST->ConOut, s); 16 | } 17 | 18 | void puth(unsigned long long val, unsigned char num_digits) 19 | { 20 | int i; 21 | unsigned short unicode_val; 22 | unsigned short str[MAX_STR_BUF]; 23 | 24 | for (i = num_digits - 1; i >= 0; i--) { 25 | unicode_val = (unsigned short)(val & 0x0f); 26 | if (unicode_val < 0xa) 27 | str[i] = L'0' + unicode_val; 28 | else 29 | str[i] = L'A' + (unicode_val - 0xa); 30 | val >>= 4; 31 | } 32 | str[num_digits] = L'\0'; 33 | 34 | puts(str); 35 | } 36 | 37 | unsigned short getc(void) 38 | { 39 | struct EFI_INPUT_KEY key; 40 | unsigned long long waitidx; 41 | 42 | ST->BootServices->WaitForEvent(1, &(ST->ConIn->WaitForKey), 43 | &waitidx); 44 | while (ST->ConIn->ReadKeyStroke(ST->ConIn, &key)); 45 | 46 | return (key.UnicodeChar) ? key.UnicodeChar 47 | : (key.ScanCode + SC_OFS); 48 | } 49 | 50 | unsigned int gets(unsigned short *buf, unsigned int buf_size) 51 | { 52 | unsigned int i; 53 | 54 | for (i = 0; i < buf_size - 1;) { 55 | buf[i] = getc(); 56 | putc(buf[i]); 57 | if (buf[i] == L'\r') { 58 | putc(L'\n'); 59 | break; 60 | } 61 | i++; 62 | } 63 | buf[i] = L'\0'; 64 | 65 | return i; 66 | } 67 | 68 | int strcmp(const unsigned short *s1, const unsigned short *s2) 69 | { 70 | char is_equal = 1; 71 | 72 | for (; (*s1 != L'\0') && (*s2 != L'\0'); s1++, s2++) { 73 | if (*s1 != *s2) { 74 | is_equal = 0; 75 | break; 76 | } 77 | } 78 | 79 | if (is_equal) { 80 | if (*s1 != L'\0') { 81 | return 1; 82 | } else if (*s2 != L'\0') { 83 | return -1; 84 | } else { 85 | return 0; 86 | } 87 | } else { 88 | return (int)(*s1 - *s2); 89 | } 90 | } 91 | 92 | void strncpy(unsigned short *dst, unsigned short *src, unsigned long long n) 93 | { 94 | while (n--) 95 | *dst++ = *src++; 96 | } 97 | 98 | unsigned long long strlen(unsigned short *str) 99 | { 100 | unsigned long long len = 0; 101 | 102 | while (*str++ != L'\0') 103 | len++; 104 | 105 | return len; 106 | } 107 | 108 | unsigned char check_warn_error(unsigned long long status, unsigned short *message) 109 | { 110 | if (status) { 111 | puts(message); 112 | puts(L":"); 113 | puth(status, 16); 114 | puts(L"\r\n"); 115 | } 116 | 117 | return !status; 118 | } 119 | 120 | void assert(unsigned long long status, unsigned short *message) 121 | { 122 | if (!check_warn_error(status, message)) 123 | while (1); 124 | } 125 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/efi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct EFI_SYSTEM_TABLE *ST; 5 | struct EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP; 6 | struct EFI_SIMPLE_POINTER_PROTOCOL *SPP; 7 | struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SFSP; 8 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *STIEP; 9 | struct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DPTTP; 10 | struct EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *DPFTP; 11 | struct EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DPUP; 12 | struct EFI_GUID lip_guid = {0x5b1b31a1, 0x9562, 0x11d2, 13 | {0x8e, 0x3f, 0x00, 0xa0, 14 | 0xc9, 0x69, 0x72, 0x3b}}; 15 | struct EFI_GUID dpp_guid = {0x09576e91, 0x6d3f, 0x11d2, 16 | {0x8e, 0x39, 0x00, 0xa0, 17 | 0xc9, 0x69, 0x72, 0x3b}}; 18 | struct EFI_GUID fi_guid = {0x09576e92, 0x6d3f, 0x11d2, 19 | {0x8e, 0x39, 0x00, 0xa0, 20 | 0xc9, 0x69, 0x72, 0x3b}}; 21 | 22 | void efi_init(struct EFI_SYSTEM_TABLE *SystemTable) 23 | { 24 | struct EFI_GUID gop_guid = {0x9042a9de, 0x23dc, 0x4a38, 25 | {0x96, 0xfb, 0x7a, 0xde, 26 | 0xd0, 0x80, 0x51, 0x6a}}; 27 | struct EFI_GUID spp_guid = {0x31878c87, 0xb75, 0x11d5, 28 | {0x9a, 0x4f, 0x0, 0x90, 29 | 0x27, 0x3f, 0xc1, 0x4d}}; 30 | struct EFI_GUID sfsp_guid = {0x0964e5b22, 0x6459, 0x11d2, 31 | {0x8e, 0x39, 0x00, 0xa0, 32 | 0xc9, 0x69, 0x72, 0x3b}}; 33 | struct EFI_GUID stiep_guid = {0xdd9e7534, 0x7762, 0x4698, 34 | {0x8c, 0x14, 0xf5, 0x85, 35 | 0x17, 0xa6, 0x25, 0xaa}}; 36 | struct EFI_GUID dpttp_guid = {0x8b843e20, 0x8132, 0x4852, 37 | {0x90, 0xcc, 0x55, 0x1a, 38 | 0x4e, 0x4a, 0x7f, 0x1c}}; 39 | struct EFI_GUID dpftp_guid = {0x5c99a21, 0xc70f, 0x4ad2, 40 | {0x8a, 0x5f, 0x35, 0xdf, 41 | 0x33, 0x43, 0xf5, 0x1e}}; 42 | struct EFI_GUID dpup_guid = {0x379be4e, 0xd706, 0x437d, 43 | {0xb0, 0x37, 0xed, 0xb8, 44 | 0x2f, 0xb7, 0x72, 0xa4}}; 45 | 46 | ST = SystemTable; 47 | ST->BootServices->SetWatchdogTimer(0, 0, 0, NULL); 48 | ST->BootServices->LocateProtocol(&gop_guid, NULL, (void **)&GOP); 49 | ST->BootServices->LocateProtocol(&spp_guid, NULL, (void **)&SPP); 50 | ST->BootServices->LocateProtocol(&sfsp_guid, NULL, (void **)&SFSP); 51 | ST->BootServices->LocateProtocol(&stiep_guid, NULL, (void **)&STIEP); 52 | ST->BootServices->LocateProtocol(&dpttp_guid, NULL, (void **)&DPTTP); 53 | ST->BootServices->LocateProtocol(&dpftp_guid, NULL, (void **)&DPFTP); 54 | ST->BootServices->LocateProtocol(&dpup_guid, NULL, (void **)&DPUP); 55 | } 56 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/fb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct fb fb; 5 | 6 | void init_fb(void) 7 | { 8 | fb.base = GOP->Mode->FrameBufferBase; 9 | fb.size = GOP->Mode->FrameBufferSize; 10 | fb.hr = GOP->Mode->Info->HorizontalResolution; 11 | fb.vr = GOP->Mode->Info->VerticalResolution; 12 | } 13 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct FILE file_list[MAX_FILE_NUM]; 6 | 7 | unsigned long long get_file_size(struct EFI_FILE_PROTOCOL *file) 8 | { 9 | unsigned long long status; 10 | unsigned long long fi_size = FILE_INFO_BUF_SIZE; 11 | unsigned long long fi_buf[FILE_INFO_BUF_SIZE]; 12 | struct EFI_FILE_INFO *fi_ptr; 13 | 14 | status = file->GetInfo(file, &fi_guid, &fi_size, fi_buf); 15 | if (!check_warn_error(status, L"file->GetInfo failure.")) 16 | return 0; 17 | 18 | fi_ptr = (struct EFI_FILE_INFO *)fi_buf; 19 | 20 | return fi_ptr->FileSize; 21 | } 22 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/graphics.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | const struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL white = {0xff, 0xff, 0xff, 0xff}; 6 | const struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL yellow = {0x00, 0xff, 0xff, 0xff}; 7 | 8 | void draw_pixel(unsigned int x, unsigned int y, 9 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) 10 | { 11 | unsigned int hr = GOP->Mode->Info->HorizontalResolution; 12 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL *base = 13 | (struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)GOP->Mode->FrameBufferBase; 14 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = base + (hr * y) + x; 15 | 16 | p->Blue = color.Blue; 17 | p->Green = color.Green; 18 | p->Red = color.Red; 19 | p->Reserved = color.Reserved; 20 | } 21 | 22 | void draw_rect(struct RECT r, struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL c) 23 | { 24 | unsigned int i; 25 | 26 | for (i = r.x; i < (r.x + r.w); i++) 27 | draw_pixel(i, r.y, c); 28 | for (i = r.x; i < (r.x + r.w); i++) 29 | draw_pixel(i, r.y + r.h - 1, c); 30 | 31 | for (i = r.y; i < (r.y + r.h); i++) 32 | draw_pixel(r.x, i, c); 33 | for (i = r.y; i < (r.y + r.h); i++) 34 | draw_pixel(r.x + r.w - 1, i, c); 35 | } 36 | 37 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL get_pixel(unsigned int x, unsigned int y) 38 | { 39 | unsigned int hr = GOP->Mode->Info->HorizontalResolution; 40 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL *base = 41 | (struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) 42 | GOP->Mode->FrameBufferBase; 43 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = base + (hr * y) + x; 44 | 45 | return *p; 46 | } 47 | 48 | unsigned char is_in_rect(unsigned int x, unsigned int y, struct RECT r) 49 | { 50 | if ((r.x <= x) && (x <= (r.x + r.w - 1)) 51 | && (r.y <= y) && (y <= (r.y + r.h - 1))) 52 | return TRUE; 53 | return FALSE; 54 | } 55 | 56 | void blt(unsigned char img[], unsigned int img_width, unsigned int img_height) 57 | { 58 | unsigned char *fb; 59 | unsigned int i, j, k, vr, hr, ofs = 0; 60 | 61 | fb = (unsigned char *)GOP->Mode->FrameBufferBase; 62 | vr = GOP->Mode->Info->VerticalResolution; 63 | hr = GOP->Mode->Info->HorizontalResolution; 64 | 65 | for (i = 0; i < vr; i++) { 66 | if (i >= img_height) 67 | break; 68 | for (j = 0; j < hr; j++) { 69 | if (j >= img_width) { 70 | fb += (hr - img_width) * 4; 71 | break; 72 | } 73 | for (k = 0; k < 4; k++) 74 | *fb++ = img[ofs++]; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/gui.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define WIDTH_PER_CH 8 9 | #define HEIGHT_PER_CH 20 10 | #define CURSOR_WIDTH 4 11 | #define CURSOR_HEIGHT 4 12 | #define EXIT_BUTTON_WIDTH 20 13 | #define EXIT_BUTTON_HEIGHT 20 14 | 15 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL cursor_tmp[CURSOR_HEIGHT][CURSOR_WIDTH] = 16 | { 17 | {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 18 | {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 19 | {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 20 | {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} 21 | }; 22 | int cursor_old_x; 23 | int cursor_old_y; 24 | struct FILE rect_exit_button; 25 | 26 | void draw_cursor(int x, int y) 27 | { 28 | int i, j; 29 | for (i = 0; i < CURSOR_HEIGHT; i++) 30 | for (j = 0; j < CURSOR_WIDTH; j++) 31 | if ((i * j) < CURSOR_WIDTH) 32 | draw_pixel(x + j, y + i, white); 33 | } 34 | 35 | void save_cursor_area(int x, int y) 36 | { 37 | int i, j; 38 | for (i = 0; i < CURSOR_HEIGHT; i++) { 39 | for (j = 0; j < CURSOR_WIDTH; j++) { 40 | if ((i * j) < CURSOR_WIDTH) { 41 | cursor_tmp[i][j] = get_pixel(x + j, y + i); 42 | cursor_tmp[i][j].Reserved = 0xff; 43 | } 44 | } 45 | } 46 | } 47 | 48 | void load_cursor_area(int x, int y) 49 | { 50 | int i, j; 51 | for (i = 0; i < CURSOR_HEIGHT; i++) 52 | for (j = 0; j < CURSOR_WIDTH; j++) 53 | if ((i * j) < CURSOR_WIDTH) 54 | draw_pixel(x + j, y + i, cursor_tmp[i][j]); 55 | } 56 | 57 | void put_cursor(int x, int y) 58 | { 59 | if (cursor_tmp[0][0].Reserved) 60 | load_cursor_area(cursor_old_x, cursor_old_y); 61 | 62 | save_cursor_area(x, y); 63 | 64 | draw_cursor(x, y); 65 | 66 | cursor_old_x = x; 67 | cursor_old_y = y; 68 | } 69 | 70 | void put_exit_button(void) 71 | { 72 | unsigned int hr = GOP->Mode->Info->HorizontalResolution; 73 | unsigned int x; 74 | 75 | rect_exit_button.rect.x = hr - EXIT_BUTTON_WIDTH; 76 | rect_exit_button.rect.y = 0; 77 | rect_exit_button.rect.w = EXIT_BUTTON_WIDTH; 78 | rect_exit_button.rect.h = EXIT_BUTTON_HEIGHT; 79 | rect_exit_button.is_highlight = FALSE; 80 | draw_rect(rect_exit_button.rect, white); 81 | 82 | /* EXITボタン内の各ピクセルを走査(バッテンを描く) */ 83 | for (x = 3; x < rect_exit_button.rect.w - 3; x++) { 84 | draw_pixel(x + rect_exit_button.rect.x, x, white); 85 | draw_pixel(x + rect_exit_button.rect.x, 86 | rect_exit_button.rect.w - x, white); 87 | } 88 | } 89 | 90 | unsigned char update_exit_button(int px, int py, unsigned char is_clicked) 91 | { 92 | unsigned char is_exit = FALSE; 93 | 94 | if (is_in_rect(px, py, rect_exit_button.rect)) { 95 | if (!rect_exit_button.is_highlight) { 96 | draw_rect(rect_exit_button.rect, yellow); 97 | rect_exit_button.is_highlight = TRUE; 98 | } 99 | if (is_clicked) 100 | is_exit = TRUE; 101 | } else { 102 | if (rect_exit_button.is_highlight) { 103 | draw_rect(rect_exit_button.rect, white); 104 | rect_exit_button.is_highlight = FALSE; 105 | } 106 | } 107 | 108 | return is_exit; 109 | } 110 | 111 | int ls_gui(void) 112 | { 113 | int file_num; 114 | struct RECT t; 115 | int idx; 116 | 117 | ST->ConOut->ClearScreen(ST->ConOut); 118 | 119 | file_num = ls(); 120 | 121 | t.x = 0; 122 | t.y = 0; 123 | t.w = (MAX_FILE_NAME_LEN - 1) * WIDTH_PER_CH; 124 | t.h = HEIGHT_PER_CH; 125 | for (idx = 0; idx < file_num; idx++) { 126 | file_list[idx].rect.x = t.x; 127 | file_list[idx].rect.y = t.y; 128 | file_list[idx].rect.w = t.w; 129 | file_list[idx].rect.h = t.h; 130 | draw_rect(file_list[idx].rect, white); 131 | t.x += file_list[idx].rect.w + WIDTH_PER_CH; 132 | 133 | file_list[idx].is_highlight = FALSE; 134 | } 135 | 136 | return file_num; 137 | } 138 | 139 | void cat_gui(unsigned short *file_name) 140 | { 141 | ST->ConOut->ClearScreen(ST->ConOut); 142 | 143 | cat(file_name); 144 | 145 | while (getc() != SC_ESC); 146 | } 147 | 148 | void gui(void) 149 | { 150 | unsigned long long status; 151 | struct EFI_SIMPLE_POINTER_STATE s; 152 | int px = 0, py = 0; 153 | unsigned long long waitidx; 154 | int file_num; 155 | int idx; 156 | unsigned char prev_lb = FALSE; 157 | unsigned char prev_rb = FALSE, executed_rb; 158 | unsigned char is_exit = FALSE; 159 | 160 | SPP->Reset(SPP, FALSE); 161 | file_num = ls_gui(); 162 | put_exit_button(); 163 | 164 | while (!is_exit) { 165 | ST->BootServices->WaitForEvent(1, &(SPP->WaitForInput), &waitidx); 166 | status = SPP->GetState(SPP, &s); 167 | if (!status) { 168 | /* マウスカーソル座標更新 */ 169 | px += s.RelativeMovementX >> 13; 170 | if (px < 0) 171 | px = 0; 172 | else if (GOP->Mode->Info->HorizontalResolution <= 173 | (unsigned int)px) 174 | px = GOP->Mode->Info->HorizontalResolution - 1; 175 | py += s.RelativeMovementY >> 13; 176 | if (py < 0) 177 | py = 0; 178 | else if (GOP->Mode->Info->VerticalResolution <= 179 | (unsigned int)py) 180 | py = GOP->Mode->Info->VerticalResolution - 1; 181 | 182 | /* マウスカーソル描画 */ 183 | put_cursor(px, py); 184 | 185 | /* 右クリックの実行済フラグをクリア */ 186 | executed_rb = FALSE; 187 | 188 | /* ファイルアイコン処理ループ */ 189 | for (idx = 0; idx < file_num; idx++) { 190 | if (is_in_rect(px, py, file_list[idx].rect)) { 191 | if (!file_list[idx].is_highlight) { 192 | draw_rect(file_list[idx].rect, 193 | yellow); 194 | file_list[idx].is_highlight = TRUE; 195 | } 196 | if (prev_lb && !s.LeftButton) { 197 | if (file_list[idx].name[0] != L'i') 198 | cat_gui(file_list[idx].name); 199 | else 200 | view(file_list[idx].name); 201 | file_num = ls_gui(); 202 | put_exit_button(); 203 | } 204 | if (prev_rb && !s.RightButton) { 205 | edit(file_list[idx].name); 206 | file_num = ls_gui(); 207 | put_exit_button(); 208 | executed_rb = TRUE; 209 | } 210 | } else { 211 | if (file_list[idx].is_highlight) { 212 | draw_rect(file_list[idx].rect, 213 | white); 214 | file_list[idx].is_highlight = 215 | FALSE; 216 | } 217 | } 218 | } 219 | 220 | /* ファイル新規作成・編集 */ 221 | if ((prev_rb && !s.RightButton) && !executed_rb) { 222 | /* アイコン外を右クリックした場合 */ 223 | dialogue_get_filename(file_num); 224 | edit(file_list[file_num].name); 225 | ST->ConOut->ClearScreen(ST->ConOut); 226 | file_num = ls_gui(); 227 | put_exit_button(); 228 | } 229 | 230 | /* 終了ボタン更新 */ 231 | is_exit = update_exit_button(px, py, 232 | prev_lb && !s.LeftButton); 233 | 234 | /* マウスの左右ボタンの前回の状態を更新 */ 235 | prev_lb = s.LeftButton; 236 | prev_rb = s.RightButton; 237 | } 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/mem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MEM_DESC_SIZE 4800 6 | 7 | unsigned char mem_desc[MEM_DESC_SIZE]; 8 | unsigned long long mem_desc_num; 9 | unsigned long long mem_desc_unit_size; 10 | unsigned long long map_key; 11 | 12 | void dump_memmap(void) 13 | { 14 | struct EFI_MEMORY_DESCRIPTOR *p = 15 | (struct EFI_MEMORY_DESCRIPTOR *)mem_desc; 16 | unsigned int i; 17 | 18 | for (i = 0; i < mem_desc_num; i++) { 19 | puth((unsigned long long)p, 16); 20 | putc(L' '); 21 | puth(p->Type, 2); 22 | putc(L' '); 23 | puth(p->PhysicalStart, 16); 24 | putc(L' '); 25 | puth(p->VirtualStart, 16); 26 | putc(L' '); 27 | puth(p->NumberOfPages, 16); 28 | putc(L' '); 29 | puth(p->Attribute, 16); 30 | puts(L"\r\n"); 31 | 32 | p = (struct EFI_MEMORY_DESCRIPTOR *)( 33 | (unsigned char *)p + mem_desc_unit_size); 34 | } 35 | } 36 | 37 | void init_memmap(void) 38 | { 39 | unsigned long long status; 40 | unsigned long long mmap_size = MEM_DESC_SIZE; 41 | unsigned int desc_ver; 42 | 43 | status = ST->BootServices->GetMemoryMap( 44 | &mmap_size, (struct EFI_MEMORY_DESCRIPTOR *)mem_desc, &map_key, 45 | &mem_desc_unit_size, &desc_ver); 46 | assert(status, L"GetMemoryMap"); 47 | mem_desc_num = mmap_size / mem_desc_unit_size; 48 | } 49 | 50 | struct EFI_MEMORY_DESCRIPTOR *get_allocatable_area(unsigned long long size) 51 | { 52 | struct EFI_MEMORY_DESCRIPTOR *p = 53 | (struct EFI_MEMORY_DESCRIPTOR *)mem_desc; 54 | unsigned long long i; 55 | 56 | for (i = 0; i < mem_desc_num; i++) { 57 | if ((p->Type == EfiConventionalMemory) && 58 | ((p->NumberOfPages * PAGE_SIZE) >= size)) 59 | break; 60 | 61 | p = (struct EFI_MEMORY_DESCRIPTOR *)( 62 | (unsigned char *)p + mem_desc_unit_size); 63 | } 64 | 65 | return p; 66 | } 67 | 68 | void exit_boot_services(void *IH) 69 | { 70 | unsigned long long status; 71 | unsigned long long mmap_size; 72 | unsigned int desc_ver; 73 | 74 | do { 75 | mmap_size = MEM_DESC_SIZE; 76 | status = ST->BootServices->GetMemoryMap( 77 | &mmap_size, (struct EFI_MEMORY_DESCRIPTOR *)mem_desc, 78 | &map_key, &mem_desc_unit_size, &desc_ver); 79 | } while (!check_warn_error(status, L"GetMemoryMap")); 80 | 81 | status = ST->BootServices->ExitBootServices(IH, map_key); 82 | assert(status, L"ExitBootServices"); 83 | } 84 | -------------------------------------------------------------------------------- /boot/uefi/libuefi/shell.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define MAX_COMMAND_LEN 100 9 | #define MAX_IMG_BUF 4194304 /* 4MB */ 10 | 11 | unsigned char img_buf[MAX_IMG_BUF]; 12 | 13 | void dialogue_get_filename(int idx) 14 | { 15 | int i; 16 | 17 | ST->ConOut->ClearScreen(ST->ConOut); 18 | 19 | puts(L"New File Name: "); 20 | for (i = 0; i < MAX_FILE_NAME_LEN; i++) { 21 | file_list[idx].name[i] = getc(); 22 | if (file_list[idx].name[i] != L'\r') 23 | putc(file_list[idx].name[i]); 24 | else 25 | break; 26 | } 27 | file_list[idx].name[i] = L'\0'; 28 | } 29 | 30 | void pstat(void) 31 | { 32 | unsigned long long status; 33 | struct EFI_SIMPLE_POINTER_STATE s; 34 | unsigned long long waitidx; 35 | 36 | SPP->Reset(SPP, FALSE); 37 | 38 | while (1) { 39 | ST->BootServices->WaitForEvent(1, &(SPP->WaitForInput), 40 | &waitidx); 41 | status = SPP->GetState(SPP, &s); 42 | if (!status) { 43 | puth(s.RelativeMovementX, 8); 44 | puts(L" "); 45 | puth(s.RelativeMovementY, 8); 46 | puts(L" "); 47 | puth(s.RelativeMovementZ, 8); 48 | puts(L" "); 49 | puth(s.LeftButton, 1); 50 | puts(L" "); 51 | puth(s.RightButton, 1); 52 | puts(L"\r\n"); 53 | } 54 | } 55 | } 56 | 57 | int ls(void) 58 | { 59 | unsigned long long status; 60 | struct EFI_FILE_PROTOCOL *root; 61 | unsigned long long buf_size; 62 | unsigned char file_buf[MAX_FILE_BUF]; 63 | struct EFI_FILE_INFO *file_info; 64 | int idx = 0; 65 | int file_num; 66 | 67 | status = SFSP->OpenVolume(SFSP, &root); 68 | assert(status, L"SFSP->OpenVolume"); 69 | 70 | while (1) { 71 | buf_size = MAX_FILE_BUF; 72 | status = root->Read(root, &buf_size, (void *)file_buf); 73 | assert(status, L"root->Read"); 74 | if (!buf_size) break; 75 | 76 | file_info = (struct EFI_FILE_INFO *)file_buf; 77 | strncpy(file_list[idx].name, file_info->FileName, 78 | MAX_FILE_NAME_LEN - 1); 79 | file_list[idx].name[MAX_FILE_NAME_LEN - 1] = L'\0'; 80 | puts(file_list[idx].name); 81 | puts(L" "); 82 | 83 | idx++; 84 | } 85 | puts(L"\r\n"); 86 | file_num = idx; 87 | 88 | root->Close(root); 89 | 90 | return file_num; 91 | } 92 | 93 | void cat(unsigned short *file_name) 94 | { 95 | unsigned long long status; 96 | struct EFI_FILE_PROTOCOL *root; 97 | struct EFI_FILE_PROTOCOL *file; 98 | unsigned long long buf_size = MAX_FILE_BUF; 99 | unsigned short file_buf[MAX_FILE_BUF / 2]; 100 | 101 | status = SFSP->OpenVolume(SFSP, &root); 102 | assert(status, L"SFSP->OpenVolume"); 103 | 104 | status = root->Open(root, &file, file_name, EFI_FILE_MODE_READ, 0); 105 | assert(status, L"root->Open"); 106 | 107 | status = file->Read(file, &buf_size, (void *)file_buf); 108 | assert(status, L"file->Read"); 109 | 110 | puts(file_buf); 111 | 112 | file->Close(file); 113 | root->Close(root); 114 | } 115 | 116 | void edit(unsigned short *file_name) 117 | { 118 | unsigned long long status; 119 | struct EFI_FILE_PROTOCOL *root; 120 | struct EFI_FILE_PROTOCOL *file; 121 | unsigned long long buf_size = MAX_FILE_BUF; 122 | unsigned short file_buf[MAX_FILE_BUF / 2]; 123 | int i = 0; 124 | unsigned short ch; 125 | 126 | ST->ConOut->ClearScreen(ST->ConOut); 127 | 128 | while (TRUE) { 129 | ch = getc(); 130 | 131 | if (ch == SC_ESC) 132 | break; 133 | 134 | putc(ch); 135 | file_buf[i++] = ch; 136 | 137 | if (ch == L'\r') { 138 | putc(L'\n'); 139 | file_buf[i++] = L'\n'; 140 | } 141 | } 142 | file_buf[i] = L'\0'; 143 | 144 | status = SFSP->OpenVolume(SFSP, &root); 145 | assert(status, L"SFSP->OpenVolume"); 146 | 147 | status = root->Open(root, &file, file_name, 148 | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | \ 149 | EFI_FILE_MODE_CREATE, 0); 150 | assert(status, L"root->Open"); 151 | 152 | status = file->Write(file, &buf_size, (void *)file_buf); 153 | assert(status, L"file->Write"); 154 | 155 | file->Flush(file); 156 | 157 | file->Close(file); 158 | root->Close(root); 159 | } 160 | 161 | void view(unsigned short *img_name) 162 | { 163 | unsigned long long buf_size = MAX_IMG_BUF; 164 | unsigned long long status; 165 | struct EFI_FILE_PROTOCOL *root; 166 | struct EFI_FILE_PROTOCOL *file; 167 | unsigned int vr = GOP->Mode->Info->VerticalResolution; 168 | unsigned int hr = GOP->Mode->Info->HorizontalResolution; 169 | 170 | status = SFSP->OpenVolume(SFSP, &root); 171 | assert(status, L"error: SFSP->OpenVolume"); 172 | 173 | status = root->Open(root, &file, img_name, EFI_FILE_MODE_READ, 174 | EFI_FILE_READ_ONLY); 175 | assert(status, L"error: root->Open"); 176 | 177 | status = file->Read(file, &buf_size, (void *)img_buf); 178 | if (check_warn_error(status, L"warning:file->Read")) 179 | blt(img_buf, hr, vr); 180 | 181 | while (getc() != SC_ESC); 182 | 183 | status = file->Close(file); 184 | status = root->Close(root); 185 | } 186 | 187 | void shell(void) 188 | { 189 | unsigned short com[MAX_COMMAND_LEN]; 190 | struct RECT r = {10, 10, 100, 200}; 191 | unsigned char is_exit = FALSE; 192 | 193 | while (!is_exit) { 194 | puts(L"poiOS> "); 195 | if (gets(com, MAX_COMMAND_LEN) <= 0) 196 | continue; 197 | 198 | if (!strcmp(L"hello", com)) 199 | puts(L"Hello UEFI!\r\n"); 200 | else if (!strcmp(L"rect", com)) 201 | draw_rect(r, white); 202 | else if (!strcmp(L"gui", com)) { 203 | gui(); 204 | ST->ConOut->ClearScreen(ST->ConOut); 205 | } else if (!strcmp(L"pstat", com)) 206 | pstat(); 207 | else if (!strcmp(L"ls", com)) 208 | ls(); 209 | else if (!strcmp(L"cat", com)) 210 | cat(L"abc"); 211 | else if (!strcmp(L"edit", com)) 212 | edit(L"abc"); 213 | else if (!strcmp(L"view", com)) { 214 | view(L"img"); 215 | ST->ConOut->ClearScreen(ST->ConOut); 216 | } else if (!strcmp(L"exit", com)) 217 | is_exit = TRUE; 218 | else 219 | puts(L"Command not found.\r\n"); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | SOURCE=$(shell ls *.org) 2 | TARGET=$(SOURCE:%.org=%.txt) 3 | 4 | all: $(TARGET) 5 | $(info $^) 6 | 7 | %.txt: %.org 8 | emacs -Q $< --batch -f org-ascii-export-to-ascii 9 | 10 | clean: 11 | rm -f *~ *.txt 12 | 13 | .PHONY: clean 14 | -------------------------------------------------------------------------------- /doc/memory_map.org: -------------------------------------------------------------------------------- 1 | #+title: メモリーマップについて 2 | #+author: Yuma Ohgami 3 | 4 | * boot loader 5 | | base | 0x0000 7c00 | 6 | | SS(stack segment) | 0x0000 | 7 | 8 | |-----------+------------------------------------------------------------| 9 | | 0000 0500 | Conventional Memory(first) | 10 | | ... | ... | 11 | | 0000 1000 | stack base | 12 | | ... | ... | 13 | | 0000 7c00 | MBR | 14 | | 0000 7dfe | MBR(0xaa55) | 15 | | 0000 7e00 | bootloader load disk(first) | 16 | | 0000 7e00 | track 0, head 0, sector 2 - all (loaded text section head) | 17 | | 0000 a000 | track 0, head 1, sector all | 18 | | 0000 c400 | track 1, head 0, sector all | 19 | | 0000 e800 | track 1, head 1, sector 1 - 12 | 20 | | 0001 0000 | track 1, head 1, sector 13 - 18 | 21 | | 0001 0c00 | track 2, head 0, sector all | 22 | | 0001 3000 | track 2, head 1, sector all | 23 | | 0001 5400 | track 3, head 0, sector all | 24 | | 0001 7800 | track 3, head 1, sector all | 25 | | 0001 9c00 | track 4, head 0, sector all | 26 | | 0001 c000 | track 4, head 1, sector all | 27 | | 0001 e400 | track 5, head 0, sector all | 28 | | 0001 ffff | bootloader load disk(last) | 29 | | ... | ... | 30 | | 0009 0000 | GDT_0 | 31 | | 0009 0008 | GDT_1 | 32 | | 0009 0010 | GDT_2(last) | 33 | | ... | ... | 34 | | 0009 ffff | Conventional Memory(last) | 35 | |-----------+------------------------------------------------------------| 36 | 37 | * kernel, app 38 | GDT 39 | | idx | ofs | | 40 | |-----+------+---------------| 41 | | 0 | 0x00 | NULL | 42 | | 1 | 0x08 | Code(Kern) | 43 | | 2 | 0x10 | Data(Kern) | 44 | | 3 | 0x18 | Code(Usr) | 45 | | 4 | 0x20 | Data(Usr) | 46 | | 5 | 0x28 | kern_task_tss | 47 | | 6 | 0x30 | shell_tss | 48 | | 7 | 0x38 | uptime_tss | 49 | | 8 | 0x40 | whoareyou_tss | 50 | 51 | ** Physical Address Space 52 | |-----------+--------------------------------| 53 | | 0000 0500 | Conventional Memory(first) | 54 | | ... | ... | 55 | | 0000 7e00 | loaded kernel binary(first) | 56 | | | - text | 57 | | | - rodata | 58 | | | - data | 59 | | | - bss | 60 | | ... | ... | 61 | | 0001 0ffe | - sign(0xbeef) | 62 | | 0001 0fff | loaded kernel binary(last) | 63 | | 0001 1000 | loaded fs control block(first) | 64 | | ... | ... | 65 | | 0001 1fff | loaded fs control block(last) | 66 | | 0001 2000 | loaded shell binary(first) | 67 | | | - text | 68 | | | - rodata | 69 | | | - data | 70 | | | - bss | 71 | | ... | ... | 72 | | 0001 3fff | loaded shell binary(last) | 73 | | 0001 4000 | loaded uptime binary(first) | 74 | | | - text | 75 | | | - rodata | 76 | | | - data | 77 | | | - bss | 78 | | ... | ... | 79 | | 0001 4fff | loaded uptime binary(last) | 80 | | 0001 5000 | loaded whoareyou binary(first) | 81 | | | - text | 82 | | | - rodata | 83 | | | - data | 84 | | | - bss | 85 | | ... | ... | 86 | | 0001 5fff | loaded whoareyou binary(last) | 87 | | ... | ... | 88 | | 0004 0000 | heap memory(first) | 89 | | ... | ... | 90 | | 0007 ffff | heap memory(last) | 91 | | 0008 0000 | kernel stack base | 92 | | ... | ... | 93 | | 0008 f000 | kernel page directory(first) | 94 | | ... | ... | 95 | | 0008 ffff | kernel page directory(last) | 96 | | 0009 0000 | kernel page table(first) | 97 | | ... | ... | 98 | | 0009 0fff | kernel page table(last) | 99 | | ... | ... | 100 | | 0009 ffff | Conventional Memory(last) | 101 | |-----------+--------------------------------| 102 | | ... | ... | 103 | |-----------+--------------------------------| 104 | | 000b 8000 | Video Memory(first) | 105 | | ... | ... | 106 | | 000b ffff | Video Memory(last) | 107 | |-----------+--------------------------------| 108 | 109 | ** Virtual Address Space 110 | |-----------+--------------------------------------| 111 | | 0000 0000 | Kernel Address Space(first) | 112 | | ... | ... | 113 | | 0000 7000 | kernel PT map(first) | 114 | | ... | ... | 115 | | 0000 7e00 | loaded kernel binary(first) | 116 | | | - text | 117 | | | - rodata | 118 | | | - data | 119 | | | - bss | 120 | | ... | ... | 121 | | 0001 0ffe | - sign(0xbeef) | 122 | | 0001 0fff | loaded kernel binary(last) | 123 | | 0001 1000 | loaded fs control block(first) | 124 | | ... | ... | 125 | | 0001 1fff | loaded fs control block(last) | 126 | | 0001 2000 | loaded shell binary(first) | 127 | | | - text | 128 | | | - rodata | 129 | | | - data | 130 | | | - bss | 131 | | ... | ... | 132 | | 0001 3fff | loaded shell binary(last) | 133 | | 0001 4000 | loaded uptime binary(first) | 134 | | | - text | 135 | | | - rodata | 136 | | | - data | 137 | | | - bss | 138 | | ... | ... | 139 | | 0001 4fff | loaded uptime binary(last) | 140 | | 0001 5000 | loaded whoareyou binary(first) | 141 | | | - text | 142 | | | - rodata | 143 | | | - data | 144 | | | - bss | 145 | | ... | ... | 146 | | 0001 5fff | loaded whoareyou binary(last) | 147 | | ... | ... | 148 | | 0004 0000 | heap memory(first) | 149 | | ... | ... | 150 | | 0007 ffff | heap memory(last) | 151 | | 0008 0000 | kernel stack base | 152 | | ... | ... | 153 | | 0008 5fff | kernel PT map(last) | 154 | | ... | ... | 155 | | 0009 5000 | kernel PT map(first) | 156 | | 0009 ffff | kernel PT map(last) | 157 | | ... | ... | 158 | | 000b 8000 | kernel PT map(first) | 159 | | 000b 8000 | Video Memory(first) | 160 | | ... | ... | 161 | | 000b ffff | Video Memory(last) | 162 | | 000b ffff | kernel PT map(last) | 163 | | ... | ... | 164 | | 1fff ffff | Kernel Address Space(last) | 165 | |-----------+--------------------------------------| 166 | | 2000 0000 | task PT map(first) | 167 | | 2000 0000 | User Address Space(first) | 168 | | 2000 0000 | loaded app binary(first) | 169 | | | - text | 170 | | | - rodata | 171 | | | - data | 172 | | | - bss | 173 | | ... | ... | 174 | | 200x xfff | loaded app binary(last) | 175 | | 200x xfff | task PT map(last) | 176 | | ... | ... | 177 | | ffff d000 | task PT map(first) | 178 | | ffff e800 | app stack base(Priv Level 3: Apps) | 179 | | ffff efff | task PT map(last) | 180 | | ffff f000 | app stack base(Priv Level 0: Kernel) | 181 | | ... | ... | 182 | | ffff ffff | User Address Space(last) | 183 | |-----------+--------------------------------------| 184 | 185 | ** ref. x86 convert address PA <-> VA 186 | | | PA | | | 187 | | | 31 - 22 | 21 - 12 | 11 - 0 | 188 | | | PD offset | PT offset | Page offset | 189 | |----+-----------+-----------+-------------| 190 | | VA | | | | 191 | -------------------------------------------------------------------------------- /kernel/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -Wall -Wextra 2 | CFLAGS += -nostdinc -nostdlib -fno-builtin -fno-common -c 3 | CFLAGS += -Iinclude 4 | ifneq ($(x86_64),true) 5 | CFLAGS += -m32 6 | else 7 | CFLAGS += -DX86_64 8 | endif 9 | LDFLAGS = -Map System.map -s -x 10 | ifneq ($(x86_64),true) 11 | LDFLAGS += -m elf_i386 -T sys.ld 12 | OBJS = sys.o cpu.o intr.o excp.o memory.o sched.o fs.o task.o \ 13 | syscall.o lock.o timer.o console_io.o queue.o \ 14 | common.o debug.o init.o kern_task_init.o 15 | else 16 | LDFLAGS += -T sys_64.ld 17 | OBJS = init_64.o fb.o font.o fbcon.o kbc.o cpu.o excp.o intr.o sys_64.o 18 | endif 19 | 20 | kernel_64.bin: $(OBJS) 21 | ld $(LDFLAGS) -o $@ $+ 22 | 23 | kernel.bin: $(OBJS) 24 | ld $(LDFLAGS) -o $@ $+ 25 | 26 | %.o: %.S 27 | gcc $(CFLAGS) -o $@ $< 28 | %.o: %.c 29 | gcc $(CFLAGS) -o $@ $< 30 | 31 | clean: 32 | rm -f *~ *.o *.bin *.dat *.img *.map 33 | 34 | .PHONY: clean 35 | -------------------------------------------------------------------------------- /kernel/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unsigned char error_status; 5 | 6 | int str_compare(const char *src, const char *dst) 7 | { 8 | char is_equal = 1; 9 | 10 | for (; (*src != '\0') && (*dst != '\0'); src++, dst++) { 11 | if (*src != *dst) { 12 | is_equal = 0; 13 | break; 14 | } 15 | } 16 | 17 | if (is_equal) { 18 | if (*src != '\0') { 19 | return 1; 20 | } else if (*dst != '\0') { 21 | return -1; 22 | } else { 23 | return 0; 24 | } 25 | } else { 26 | return (int)(*src - *dst); 27 | } 28 | } 29 | 30 | void copy_mem(const void *src, void *dst, unsigned int size) 31 | { 32 | unsigned char *d = (unsigned char *)dst; 33 | unsigned char *s = (unsigned char *)src; 34 | 35 | for (; size > 0; size--) { 36 | *d = *s; 37 | d++; 38 | s++; 39 | } 40 | } 41 | 42 | void enqueue(struct queue *q, unsigned char data) 43 | { 44 | unsigned char if_bit; 45 | 46 | if (q->is_full) { 47 | error_status = 1; 48 | } else { 49 | error_status = 0; 50 | kern_lock(&if_bit); 51 | q->buf[q->end] = data; 52 | q->end++; 53 | if (q->start == q->end) q->is_full = 1; 54 | kern_unlock(&if_bit); 55 | } 56 | } 57 | 58 | unsigned char dequeue(struct queue *q) 59 | { 60 | unsigned char data = 0; 61 | unsigned char if_bit; 62 | 63 | kern_lock(&if_bit); 64 | if (!q->is_full && (q->start == q->end)) { 65 | error_status = 1; 66 | } else { 67 | error_status = 0; 68 | data = q->buf[q->start]; 69 | q->start++; 70 | q->is_full = 0; 71 | } 72 | kern_unlock(&if_bit); 73 | 74 | return data; 75 | } 76 | -------------------------------------------------------------------------------- /kernel/console_io.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | const char keymap[] = { 11 | 0x00, ASCII_ESC, '1', '2', '3', '4', '5', '6', 12 | '7', '8', '9', '0', '-', '^', ASCII_BS, ASCII_HT, 13 | 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 14 | 'o', 'p', '@', '[', '\n', 0x00, 'a', 's', 15 | 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 16 | ':', 0x00, 0x00, ']', 'z', 'x', 'c', 'v', 17 | 'b', 'n', 'm', ',', '.', '/', 0x00, '*', 18 | 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '7', 20 | '8', '9', '-', '4', '5', '6', '+', '1', 21 | '2', '3', '0', '.', 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, '_', 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, '\\', 0x00, 0x00 27 | }; 28 | 29 | struct queue keycode_queue; 30 | 31 | struct cursor_position cursor_pos; 32 | 33 | void do_ir_keyboard(void) 34 | { 35 | unsigned char status, data; 36 | 37 | status = inb_p(IOADR_KBC_STATUS); 38 | if (status & IOADR_KBC_STATUS_BIT_OBF) { 39 | data = inb_p(IOADR_KBC_DATA); 40 | enqueue(&keycode_queue, data); 41 | } 42 | sched_update_wakeupevq(EVENT_TYPE_KBD); 43 | outb_p(IOADR_MPIC_OCW2_BIT_MANUAL_EOI | INTR_IR_KB, 44 | IOADR_MPIC_OCW2); 45 | } 46 | 47 | void con_init(void) 48 | { 49 | keycode_queue.start = 0; 50 | keycode_queue.end = 0; 51 | keycode_queue.is_full = 0; 52 | error_status = 0; 53 | } 54 | 55 | void update_cursor(void) 56 | { 57 | unsigned int cursor_address = (cursor_pos.y * 80) + cursor_pos.x; 58 | unsigned char cursor_address_msb = (unsigned char)(cursor_address >> 8); 59 | unsigned char cursor_address_lsb = (unsigned char)cursor_address; 60 | unsigned char if_bit; 61 | 62 | kern_lock(&if_bit); 63 | outb_p(0x0e, 0x3d4); 64 | outb_p(cursor_address_msb, 0x3d5); 65 | outb_p(0x0f, 0x3d4); 66 | outb_p(cursor_address_lsb, 0x3d5); 67 | kern_unlock(&if_bit); 68 | 69 | if (cursor_pos.y >= ROWS) { 70 | unsigned int start_address = (cursor_pos.y - ROWS + 1) * 80; 71 | unsigned char start_address_msb = 72 | (unsigned char)(start_address >> 8); 73 | unsigned char start_address_lsb = (unsigned char)start_address; 74 | 75 | kern_lock(&if_bit); 76 | outb_p(0x0c, 0x3d4); 77 | outb_p(start_address_msb, 0x3d5); 78 | outb_p(0x0d, 0x3d4); 79 | outb_p(start_address_lsb, 0x3d5); 80 | kern_unlock(&if_bit); 81 | } 82 | } 83 | 84 | void put_char_pos(char c, unsigned char x, unsigned char y) 85 | { 86 | unsigned char *pos; 87 | 88 | pos = (unsigned char *)(SCREEN_START + (((y * COLUMNS) + x) * 2)); 89 | *(unsigned short *)pos = (unsigned short)((ATTR << 8) | c); 90 | } 91 | 92 | void put_char(char c) 93 | { 94 | switch (c) { 95 | case '\r': 96 | cursor_pos.x = 0; 97 | break; 98 | 99 | case '\n': 100 | cursor_pos.y++; 101 | break; 102 | 103 | default: 104 | put_char_pos(c, cursor_pos.x, cursor_pos.y); 105 | if (cursor_pos.x < COLUMNS - 1) { 106 | cursor_pos.x++; 107 | } else { 108 | cursor_pos.x = 0; 109 | cursor_pos.y++; 110 | } 111 | break; 112 | } 113 | 114 | update_cursor(); 115 | } 116 | 117 | void put_str(char *str) 118 | { 119 | while (*str != '\0') { 120 | put_char(*str); 121 | str++; 122 | } 123 | } 124 | 125 | void put_str_pos(char *str, unsigned char x, unsigned char y) 126 | { 127 | while (*str != '\0') { 128 | switch (*str) { 129 | case '\r': 130 | x = 0; 131 | break; 132 | 133 | case '\n': 134 | y++; 135 | break; 136 | 137 | default: 138 | put_char_pos(*str, x, y); 139 | if (x < COLUMNS - 1) { 140 | x++; 141 | } else { 142 | x = 0; 143 | y++; 144 | } 145 | break; 146 | } 147 | str++; 148 | } 149 | } 150 | 151 | void dump_hex(unsigned int val, unsigned int num_digits) 152 | { 153 | unsigned int new_x = cursor_pos.x + num_digits; 154 | unsigned int dump_digit = new_x - 1; 155 | 156 | while (num_digits) { 157 | unsigned char tmp_val = val & 0x0000000f; 158 | if (tmp_val < 10) { 159 | put_char_pos('0' + tmp_val, dump_digit, cursor_pos.y); 160 | } else { 161 | put_char_pos('A' + tmp_val - 10, dump_digit, cursor_pos.y); 162 | } 163 | val >>= 4; 164 | dump_digit--; 165 | num_digits--; 166 | } 167 | 168 | cursor_pos.x = new_x; 169 | 170 | update_cursor(); 171 | } 172 | 173 | void dump_hex_pos(unsigned int val, unsigned int num_digits, 174 | unsigned char x, unsigned char y) 175 | { 176 | unsigned int new_x = x + num_digits; 177 | unsigned int dump_digit = new_x - 1; 178 | 179 | while (num_digits) { 180 | unsigned char tmp_val = val & 0x0000000f; 181 | if (tmp_val < 10) { 182 | put_char_pos('0' + tmp_val, dump_digit, y); 183 | } else { 184 | put_char_pos('A' + tmp_val - 10, dump_digit, y); 185 | } 186 | val >>= 4; 187 | dump_digit--; 188 | num_digits--; 189 | } 190 | } 191 | 192 | unsigned char get_keydata_noir(void) 193 | { 194 | while (!(inb_p(IOADR_KBC_STATUS) & IOADR_KBC_STATUS_BIT_OBF)); 195 | return inb_p(IOADR_KBC_DATA); 196 | } 197 | 198 | unsigned char get_keydata(void) 199 | { 200 | unsigned char data; 201 | unsigned char dequeuing = 1; 202 | unsigned char if_bit; 203 | 204 | while (dequeuing) { 205 | kern_lock(&if_bit); 206 | data = dequeue(&keycode_queue); 207 | if (!error_status) 208 | dequeuing = 0; 209 | kern_unlock(&if_bit); 210 | if (dequeuing) 211 | wakeup_after_event(EVENT_TYPE_KBD); 212 | } 213 | 214 | return data; 215 | } 216 | 217 | unsigned char get_keycode(void) 218 | { 219 | return get_keydata() & ~IOADR_KBC_DATA_BIT_BRAKE; 220 | } 221 | 222 | unsigned char get_keycode_pressed(void) 223 | { 224 | unsigned char keycode; 225 | while ((keycode = get_keydata()) & IOADR_KBC_DATA_BIT_BRAKE); 226 | return keycode & ~IOADR_KBC_DATA_BIT_BRAKE; 227 | } 228 | 229 | unsigned char get_keycode_released(void) 230 | { 231 | unsigned char keycode; 232 | while (!((keycode = get_keydata()) & IOADR_KBC_DATA_BIT_BRAKE)); 233 | return keycode & ~IOADR_KBC_DATA_BIT_BRAKE; 234 | } 235 | 236 | char get_char(void) 237 | { 238 | return keymap[get_keycode_pressed()]; 239 | } 240 | 241 | unsigned int get_line(char *buf, unsigned int buf_size) 242 | { 243 | unsigned int i; 244 | 245 | for (i = 0; i < buf_size - 1;) { 246 | buf[i] = get_char(); 247 | if (buf[i] == ASCII_BS) { 248 | if (i == 0) continue; 249 | cursor_pos.x--; 250 | update_cursor(); 251 | put_char_pos(' ', cursor_pos.x, cursor_pos.y); 252 | i--; 253 | } else { 254 | put_char(buf[i]); 255 | if (buf[i] == '\n') { 256 | put_char('\r'); 257 | break; 258 | } 259 | i++; 260 | } 261 | } 262 | buf[i] = '\0'; 263 | 264 | return i; 265 | } 266 | -------------------------------------------------------------------------------- /kernel/cpu.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef X86_64 4 | #include 5 | 6 | struct segment_descriptor gdt[GDT_SIZE]; 7 | unsigned long long gdtr[2]; 8 | 9 | void gdt_init(void) 10 | { 11 | unsigned char i; 12 | 13 | for (i = 0; i < GDT_SIZE; i++) 14 | gdt[i].a = gdt[i].b = 0; 15 | 16 | gdt_set(1, 0, 0xfffff, 1, 0, 1, 0, GDT_S_CODE_OR_DATA, 17 | GDT_TYPE_CODE_ER); 18 | gdt_set(2, 0, 0xfffff, 1, 1, 0, 0, GDT_S_CODE_OR_DATA, 19 | GDT_TYPE_DATA_RW); 20 | 21 | gdtr[0] = ((unsigned long long)gdt << 16) | (GDT_SIZE * 8 - 1); 22 | gdtr[1] = ((unsigned long long)gdt >> 48); 23 | 24 | __asm__ ("lgdt gdtr\n" 25 | "mov $2*8, %ax\n" 26 | "mov %ax, %ds\n" 27 | "mov %ax, %es\n" 28 | "mov %ax, %fs\n" 29 | "mov %ax, %gs\n" 30 | "mov %ax, %ss\n"); 31 | 32 | unsigned short selector = 8; 33 | unsigned long long dummy; 34 | __asm__ ("pushq %[selector];" 35 | "leaq ret_label(%%rip), %[dummy];" 36 | "pushq %[dummy];" 37 | "lretq;" 38 | "ret_label:" 39 | : [dummy]"=r"(dummy) 40 | : [selector]"m"(selector)); 41 | } 42 | #endif 43 | 44 | void gdt_set(unsigned int idx, unsigned int base, unsigned int limit, 45 | unsigned char g, unsigned char d, unsigned char l, 46 | unsigned char dpl, unsigned char s, unsigned char type) 47 | { 48 | gdt[idx].a = gdt[idx].b = 0; 49 | 50 | gdt[idx].limit0 = limit & 0x0000ffff; 51 | gdt[idx].limit1 = (limit & 0x000f0000) >> 16; 52 | 53 | gdt[idx].base0 = base & 0x0000ffff; 54 | gdt[idx].base1 = (base & 0x00ff0000) >> 16; 55 | gdt[idx].base2 = (base & 0xff000000) >> 24; 56 | 57 | gdt[idx].g = g; 58 | gdt[idx].d = d; 59 | gdt[idx].l = l; 60 | 61 | gdt[idx].dpl = dpl; 62 | 63 | gdt[idx].s = s; 64 | gdt[idx].type = type; 65 | gdt[idx].p = 1; 66 | } 67 | -------------------------------------------------------------------------------- /kernel/debug.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | volatile unsigned char _flag; 4 | 5 | void debug_init(void) 6 | { 7 | _flag = 0; 8 | } 9 | 10 | /* Test divide by zero exception */ 11 | void test_excp_de(void) 12 | { 13 | __asm__("\tmovw $8, %%ax\n" \ 14 | "\tmovb $0, %%bl\n" \ 15 | "\tdivb %%bl"::); 16 | } 17 | 18 | /* Test page fault exception */ 19 | void test_excp_pf(void) 20 | { 21 | volatile unsigned char tmp; 22 | __asm__("movb 0x000b8000, %0":"=r"(tmp):); 23 | } 24 | -------------------------------------------------------------------------------- /kernel/excp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #ifndef X86_64 3 | #include 4 | #else 5 | #include 6 | #endif 7 | 8 | void do_exception(void) 9 | { 10 | #ifndef X86_64 11 | put_str("exception\r\n"); 12 | #else 13 | puts("exception\r\n"); 14 | #endif 15 | while (1); 16 | } 17 | 18 | void do_page_fault(unsigned int error_code, unsigned int address) 19 | { 20 | #ifndef X86_64 21 | put_str("page fault\r\n"); 22 | put_str("error code: 0x"); 23 | dump_hex(error_code, 8); 24 | put_str("\r\n"); 25 | put_str("address : 0x"); 26 | dump_hex(address, 8); 27 | put_str("\r\n"); 28 | #else 29 | (void)error_code; 30 | (void)address; 31 | puts("page fault\r\n"); 32 | #endif 33 | while (1); 34 | } 35 | -------------------------------------------------------------------------------- /kernel/fb.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct fb fb; 4 | fb_pixel color_fg; 5 | fb_pixel color_bg; 6 | 7 | void fb_init(struct fb *_fb) 8 | { 9 | fb.base = _fb->base; 10 | fb.size = _fb->size; 11 | fb.hr = _fb->hr; 12 | fb.vr = _fb->vr; 13 | } 14 | 15 | void set_fg(unsigned char r, unsigned char g, unsigned char b) 16 | { 17 | color_fg.Blue = b; 18 | color_fg.Green = g; 19 | color_fg.Red = r; 20 | color_fg.Reserved = 255; 21 | } 22 | 23 | void set_bg(unsigned char r, unsigned char g, unsigned char b) 24 | { 25 | color_bg.Blue = b; 26 | color_bg.Green = g; 27 | color_bg.Red = r; 28 | color_bg.Reserved = 255; 29 | } 30 | 31 | inline void draw_px(unsigned int x, unsigned int y, 32 | unsigned char r, unsigned char g, unsigned char b) 33 | { 34 | fb_pixel *p = (fb_pixel *)fb.base; 35 | p += y * fb.hr + x; 36 | 37 | p->Blue = b; 38 | p->Green = g; 39 | p->Red = r; 40 | p->Reserved = 255; 41 | } 42 | 43 | inline void draw_px_fg(unsigned int x, unsigned int y) 44 | { 45 | fb_pixel *p = (fb_pixel *)fb.base; 46 | p += y * fb.hr + x; 47 | 48 | p->Blue = color_fg.Blue; 49 | p->Green = color_fg.Green; 50 | p->Red = color_fg.Red; 51 | p->Reserved = color_fg.Reserved; 52 | } 53 | 54 | inline void fill_rect(unsigned int x, unsigned int y, 55 | unsigned int w, unsigned int h, 56 | unsigned char r, unsigned char g, unsigned char b) 57 | { 58 | unsigned int i, j; 59 | for (i = y; i < (y + h); i++) 60 | for (j = x; j < (x + w); j++) 61 | draw_px(j, i, r, g, b); 62 | } 63 | 64 | void clear_screen(void) 65 | { 66 | fill_rect(0, 0, fb.hr, fb.vr, 67 | color_bg.Red, color_bg.Green, color_bg.Blue); 68 | } 69 | -------------------------------------------------------------------------------- /kernel/fbcon.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | unsigned int cursor_x, cursor_y; 7 | 8 | void fbcon_init(void) 9 | { 10 | cursor_x = cursor_y = 0; 11 | } 12 | 13 | void putc(char c) 14 | { 15 | unsigned int x, y; 16 | 17 | switch(c) { 18 | case '\r': 19 | cursor_x = 0; 20 | break; 21 | 22 | case '\n': 23 | cursor_y += FONT_HEIGHT; 24 | if ((cursor_y + FONT_HEIGHT) >= fb.vr) { 25 | cursor_x = cursor_y = 0; 26 | clear_screen(); 27 | } 28 | break; 29 | 30 | default: 31 | for (y = 0; y < FONT_HEIGHT; y++) 32 | for (x = 0; x < FONT_WIDTH; x++) 33 | if (font_bitmap[(unsigned int)c][y][x]) 34 | draw_px_fg(cursor_x + x, cursor_y + y); 35 | 36 | cursor_x += FONT_WIDTH; 37 | if ((cursor_x + FONT_WIDTH) >= fb.hr) { 38 | cursor_x = 0; 39 | cursor_y += FONT_HEIGHT; 40 | if ((cursor_y + FONT_HEIGHT) >= fb.vr) { 41 | cursor_x = cursor_y = 0; 42 | clear_screen(); 43 | } 44 | } 45 | 46 | break; 47 | } 48 | } 49 | 50 | void puts(char *s) 51 | { 52 | while (*s != '\0') 53 | putc(*s++); 54 | } 55 | 56 | char getc(void) 57 | { 58 | return keymap[get_keycode_pressed()]; 59 | } 60 | -------------------------------------------------------------------------------- /kernel/font.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const unsigned char font_bitmap[][FONT_HEIGHT][FONT_WIDTH] = { 4 | [' '] = { 5 | {0,0,0,0,0,0,0,0}, 6 | {0,0,0,0,0,0,0,0}, 7 | {0,0,0,0,0,0,0,0}, 8 | {0,0,0,0,0,0,0,0}, 9 | {0,0,0,0,0,0,0,0}, 10 | {0,0,0,0,0,0,0,0}, 11 | {0,0,0,0,0,0,0,0}, 12 | {0,0,0,0,0,0,0,0}, 13 | {0,0,0,0,0,0,0,0}, 14 | {0,0,0,0,0,0,0,0} 15 | }, 16 | ['!'] = { 17 | {0,0,0,0,0,0,0,0}, 18 | {0,0,0,0,1,0,0,0}, 19 | {0,0,0,0,1,0,0,0}, 20 | {0,0,0,0,1,0,0,0}, 21 | {0,0,0,0,1,0,0,0}, 22 | {0,0,0,0,1,0,0,0}, 23 | {0,0,0,0,1,0,0,0}, 24 | {0,0,0,0,0,0,0,0}, 25 | {0,0,0,0,1,0,0,0}, 26 | {0,0,0,0,0,0,0,0} 27 | }, 28 | [','] = { 29 | {0,0,0,0,0,0,0,0}, 30 | {0,0,0,0,0,0,0,0}, 31 | {0,0,0,0,0,0,0,0}, 32 | {0,0,0,0,0,0,0,0}, 33 | {0,0,0,0,0,0,0,0}, 34 | {0,0,0,0,0,0,0,0}, 35 | {0,0,0,0,0,0,0,0}, 36 | {0,0,0,0,1,0,0,0}, 37 | {0,0,0,1,0,0,0,0}, 38 | {0,0,0,0,0,0,0,0} 39 | }, 40 | ['.'] = { 41 | {0,0,0,0,0,0,0,0}, 42 | {0,0,0,0,0,0,0,0}, 43 | {0,0,0,0,0,0,0,0}, 44 | {0,0,0,0,0,0,0,0}, 45 | {0,0,0,0,0,0,0,0}, 46 | {0,0,0,0,0,0,0,0}, 47 | {0,0,0,0,0,0,0,0}, 48 | {0,0,0,0,0,0,0,0}, 49 | {0,0,0,0,1,0,0,0}, 50 | {0,0,0,0,0,0,0,0} 51 | }, 52 | ['0'] = { 53 | {0,0,0,0,0,0,0,0}, 54 | {0,0,1,1,1,1,0,0}, 55 | {0,1,0,0,0,1,1,0}, 56 | {0,1,0,0,1,0,1,0}, 57 | {0,1,0,0,1,0,1,0}, 58 | {0,1,0,1,0,0,1,0}, 59 | {0,1,0,1,0,0,1,0}, 60 | {0,1,1,0,0,0,1,0}, 61 | {0,0,1,1,1,1,0,0}, 62 | {0,0,0,0,0,0,0,0} 63 | }, 64 | ['1'] = { 65 | {0,0,0,0,0,0,0,0}, 66 | {0,0,0,0,1,0,0,0}, 67 | {0,0,0,1,1,0,0,0}, 68 | {0,0,0,0,1,0,0,0}, 69 | {0,0,0,0,1,0,0,0}, 70 | {0,0,0,0,1,0,0,0}, 71 | {0,0,0,0,1,0,0,0}, 72 | {0,0,0,0,1,0,0,0}, 73 | {0,0,1,1,1,1,0,0}, 74 | {0,0,0,0,0,0,0,0} 75 | }, 76 | ['2'] = { 77 | {0,0,0,0,0,0,0,0}, 78 | {0,0,1,1,1,1,0,0}, 79 | {0,1,0,0,0,0,1,0}, 80 | {0,0,0,0,0,1,0,0}, 81 | {0,0,0,0,1,0,0,0}, 82 | {0,0,0,1,0,0,0,0}, 83 | {0,0,1,0,0,0,0,0}, 84 | {0,1,0,0,0,0,0,0}, 85 | {0,1,1,1,1,1,1,0}, 86 | {0,0,0,0,0,0,0,0} 87 | }, 88 | ['3'] = { 89 | {0,0,0,0,0,0,0,0}, 90 | {0,0,1,1,1,1,0,0}, 91 | {0,1,0,0,0,0,1,0}, 92 | {0,0,0,0,0,1,0,0}, 93 | {0,0,0,1,1,0,0,0}, 94 | {0,0,0,1,1,0,0,0}, 95 | {0,0,0,0,0,1,0,0}, 96 | {0,1,0,0,0,0,1,0}, 97 | {0,0,1,1,1,1,0,0}, 98 | {0,0,0,0,0,0,0,0} 99 | }, 100 | ['4'] = { 101 | {0,0,0,0,0,0,0,0}, 102 | {0,0,0,0,0,1,0,0}, 103 | {0,0,0,0,1,1,0,0}, 104 | {0,0,0,1,0,1,0,0}, 105 | {0,0,1,0,0,1,0,0}, 106 | {0,1,0,0,0,1,0,0}, 107 | {0,1,1,1,1,1,1,0}, 108 | {0,0,0,0,0,1,0,0}, 109 | {0,0,0,0,0,1,0,0}, 110 | {0,0,0,0,0,0,0,0} 111 | }, 112 | ['5'] = { 113 | {0,0,0,0,0,0,0,0}, 114 | {0,1,1,1,1,1,1,0}, 115 | {0,1,0,0,0,0,0,0}, 116 | {0,1,0,0,0,0,0,0}, 117 | {0,1,1,1,1,1,0,0}, 118 | {0,0,0,0,0,0,1,0}, 119 | {0,0,0,0,0,0,1,0}, 120 | {0,1,0,0,0,0,1,0}, 121 | {0,0,1,1,1,1,0,0}, 122 | {0,0,0,0,0,0,0,0} 123 | }, 124 | ['6'] = { 125 | {0,0,0,0,0,0,0,0}, 126 | {0,0,1,1,1,1,0,0}, 127 | {0,1,0,0,0,0,1,0}, 128 | {0,1,0,0,0,0,0,0}, 129 | {0,1,1,1,1,1,0,0}, 130 | {0,1,0,0,0,0,1,0}, 131 | {0,1,0,0,0,0,1,0}, 132 | {0,1,0,0,0,0,1,0}, 133 | {0,0,1,1,1,1,0,0}, 134 | {0,0,0,0,0,0,0,0} 135 | }, 136 | ['7'] = { 137 | {0,0,0,0,0,0,0,0}, 138 | {0,1,1,1,1,1,1,0}, 139 | {0,0,0,0,0,0,1,0}, 140 | {0,0,0,0,0,1,0,0}, 141 | {0,0,0,0,0,1,0,0}, 142 | {0,0,0,0,1,0,0,0}, 143 | {0,0,0,0,1,0,0,0}, 144 | {0,0,0,1,0,0,0,0}, 145 | {0,0,0,1,0,0,0,0}, 146 | {0,0,0,0,0,0,0,0} 147 | }, 148 | ['8'] = { 149 | {0,0,0,0,0,0,0,0}, 150 | {0,0,1,1,1,1,0,0}, 151 | {0,1,0,0,0,0,1,0}, 152 | {0,1,0,0,0,0,1,0}, 153 | {0,0,1,1,1,1,0,0}, 154 | {0,1,0,0,0,0,1,0}, 155 | {0,1,0,0,0,0,1,0}, 156 | {0,1,0,0,0,0,1,0}, 157 | {0,0,1,1,1,1,0,0}, 158 | {0,0,0,0,0,0,0,0} 159 | }, 160 | ['9'] = { 161 | {0,0,0,0,0,0,0,0}, 162 | {0,0,1,1,1,1,0,0}, 163 | {0,1,0,0,0,0,1,0}, 164 | {0,1,0,0,0,0,1,0}, 165 | {0,0,1,1,1,1,1,0}, 166 | {0,0,0,0,0,0,1,0}, 167 | {0,0,0,0,0,0,1,0}, 168 | {0,1,0,0,0,0,1,0}, 169 | {0,0,1,1,1,1,0,0}, 170 | {0,0,0,0,0,0,0,0} 171 | }, 172 | ['A'] = { 173 | {0,0,0,0,0,0,0,0}, 174 | {0,0,0,1,1,0,0,0}, 175 | {0,0,0,1,1,0,0,0}, 176 | {0,0,1,0,0,1,0,0}, 177 | {0,0,1,0,0,1,0,0}, 178 | {0,1,0,0,0,0,1,0}, 179 | {0,1,1,1,1,1,1,0}, 180 | {0,1,0,0,0,0,1,0}, 181 | {0,1,0,0,0,0,1,0}, 182 | {0,0,0,0,0,0,0,0} 183 | }, 184 | ['B'] = { 185 | {0,0,0,0,0,0,0,0}, 186 | {0,1,1,1,1,1,0,0}, 187 | {0,1,0,0,0,0,1,0}, 188 | {0,1,0,0,0,0,1,0}, 189 | {0,1,1,1,1,1,0,0}, 190 | {0,1,0,0,0,0,1,0}, 191 | {0,1,0,0,0,0,1,0}, 192 | {0,1,0,0,0,0,1,0}, 193 | {0,1,1,1,1,1,0,0}, 194 | {0,0,0,0,0,0,0,0} 195 | }, 196 | ['C'] = { 197 | {0,0,0,0,0,0,0,0}, 198 | {0,0,1,1,1,1,0,0}, 199 | {0,1,0,0,0,0,1,0}, 200 | {0,1,0,0,0,0,0,0}, 201 | {0,1,0,0,0,0,0,0}, 202 | {0,1,0,0,0,0,0,0}, 203 | {0,1,0,0,0,0,0,0}, 204 | {0,1,0,0,0,0,1,0}, 205 | {0,0,1,1,1,1,0,0}, 206 | {0,0,0,0,0,0,0,0} 207 | }, 208 | ['D'] = { 209 | {0,0,0,0,0,0,0,0}, 210 | {0,1,1,1,1,1,0,0}, 211 | {0,1,0,0,0,0,1,0}, 212 | {0,1,0,0,0,0,1,0}, 213 | {0,1,0,0,0,0,1,0}, 214 | {0,1,0,0,0,0,1,0}, 215 | {0,1,0,0,0,0,1,0}, 216 | {0,1,0,0,0,0,1,0}, 217 | {0,1,1,1,1,1,0,0}, 218 | {0,0,0,0,0,0,0,0} 219 | }, 220 | ['E'] = { 221 | {0,0,0,0,0,0,0,0}, 222 | {0,1,1,1,1,1,1,0}, 223 | {0,1,0,0,0,0,0,0}, 224 | {0,1,0,0,0,0,0,0}, 225 | {0,1,1,1,1,1,0,0}, 226 | {0,1,0,0,0,0,0,0}, 227 | {0,1,0,0,0,0,0,0}, 228 | {0,1,0,0,0,0,0,0}, 229 | {0,1,1,1,1,1,1,0}, 230 | {0,0,0,0,0,0,0,0} 231 | }, 232 | ['F'] = { 233 | {0,0,0,0,0,0,0,0}, 234 | {0,1,1,1,1,1,1,0}, 235 | {0,1,0,0,0,0,0,0}, 236 | {0,1,0,0,0,0,0,0}, 237 | {0,1,1,1,1,1,0,0}, 238 | {0,1,0,0,0,0,0,0}, 239 | {0,1,0,0,0,0,0,0}, 240 | {0,1,0,0,0,0,0,0}, 241 | {0,1,0,0,0,0,0,0}, 242 | {0,0,0,0,0,0,0,0} 243 | }, 244 | ['G'] = { 245 | {0,0,0,0,0,0,0,0}, 246 | {0,0,1,1,1,1,0,0}, 247 | {0,1,0,0,0,0,1,0}, 248 | {0,1,0,0,0,0,0,0}, 249 | {0,1,0,0,0,0,0,0}, 250 | {0,1,0,0,1,1,1,0}, 251 | {0,1,0,0,0,0,1,0}, 252 | {0,1,0,0,0,0,1,0}, 253 | {0,0,1,1,1,1,0,0}, 254 | {0,0,0,0,0,0,0,0} 255 | }, 256 | ['H'] = { 257 | {0,0,0,0,0,0,0,0}, 258 | {0,1,0,0,0,0,1,0}, 259 | {0,1,0,0,0,0,1,0}, 260 | {0,1,0,0,0,0,1,0}, 261 | {0,1,1,1,1,1,1,0}, 262 | {0,1,0,0,0,0,1,0}, 263 | {0,1,0,0,0,0,1,0}, 264 | {0,1,0,0,0,0,1,0}, 265 | {0,1,0,0,0,0,1,0}, 266 | {0,0,0,0,0,0,0,0} 267 | }, 268 | ['I'] = { 269 | {0,0,0,0,0,0,0,0}, 270 | {0,0,1,1,1,1,0,0}, 271 | {0,0,0,1,1,0,0,0}, 272 | {0,0,0,1,1,0,0,0}, 273 | {0,0,0,1,1,0,0,0}, 274 | {0,0,0,1,1,0,0,0}, 275 | {0,0,0,1,1,0,0,0}, 276 | {0,0,0,1,1,0,0,0}, 277 | {0,0,1,1,1,1,0,0}, 278 | {0,0,0,0,0,0,0,0} 279 | }, 280 | ['J'] = { 281 | {0,0,0,0,0,0,0,0}, 282 | {0,0,0,0,0,0,1,0}, 283 | {0,0,0,0,0,0,1,0}, 284 | {0,0,0,0,0,0,1,0}, 285 | {0,0,0,0,0,0,1,0}, 286 | {0,0,0,0,0,0,1,0}, 287 | {0,0,0,0,0,0,1,0}, 288 | {0,1,0,0,0,0,1,0}, 289 | {0,0,1,1,1,1,0,0}, 290 | {0,0,0,0,0,0,0,0} 291 | }, 292 | ['K'] = { 293 | {0,0,0,0,0,0,0,0}, 294 | {0,1,0,0,0,0,1,0}, 295 | {0,1,0,0,0,1,0,0}, 296 | {0,1,0,0,1,0,0,0}, 297 | {0,1,0,1,0,0,0,0}, 298 | {0,1,1,1,0,0,0,0}, 299 | {0,1,0,0,1,0,0,0}, 300 | {0,1,0,0,0,1,0,0}, 301 | {0,1,0,0,0,0,1,0}, 302 | {0,0,0,0,0,0,0,0} 303 | }, 304 | ['L'] = { 305 | {0,0,0,0,0,0,0,0}, 306 | {0,1,0,0,0,0,0,0}, 307 | {0,1,0,0,0,0,0,0}, 308 | {0,1,0,0,0,0,0,0}, 309 | {0,1,0,0,0,0,0,0}, 310 | {0,1,0,0,0,0,0,0}, 311 | {0,1,0,0,0,0,0,0}, 312 | {0,1,0,0,0,0,0,0}, 313 | {0,1,1,1,1,1,0,0}, 314 | {0,0,0,0,0,0,0,0} 315 | }, 316 | ['M'] = { 317 | {0,0,0,0,0,0,0,0}, 318 | {0,1,0,0,0,0,1,0}, 319 | {0,1,1,0,0,1,1,0}, 320 | {0,1,0,1,1,0,1,0}, 321 | {0,1,0,1,1,0,1,0}, 322 | {0,1,0,1,1,0,1,0}, 323 | {0,1,0,0,0,0,1,0}, 324 | {0,1,0,0,0,0,1,0}, 325 | {0,1,0,0,0,0,1,0}, 326 | {0,0,0,0,0,0,0,0} 327 | }, 328 | ['N'] = { 329 | {0,0,0,0,0,0,0,0}, 330 | {0,1,0,0,0,0,1,0}, 331 | {0,1,1,0,0,0,1,0}, 332 | {0,1,0,1,0,0,1,0}, 333 | {0,1,0,0,1,0,1,0}, 334 | {0,1,0,0,0,1,1,0}, 335 | {0,1,0,0,0,1,1,0}, 336 | {0,1,0,0,0,0,1,0}, 337 | {0,1,0,0,0,0,1,0}, 338 | {0,0,0,0,0,0,0,0} 339 | }, 340 | ['O'] = { 341 | {0,0,0,0,0,0,0,0}, 342 | {0,0,1,1,1,1,0,0}, 343 | {0,1,0,0,0,0,1,0}, 344 | {0,1,0,0,0,0,1,0}, 345 | {0,1,0,0,0,0,1,0}, 346 | {0,1,0,0,0,0,1,0}, 347 | {0,1,0,0,0,0,1,0}, 348 | {0,1,0,0,0,0,1,0}, 349 | {0,0,1,1,1,1,0,0}, 350 | {0,0,0,0,0,0,0,0} 351 | }, 352 | ['P'] = { 353 | {0,0,0,0,0,0,0,0}, 354 | {0,1,1,1,1,1,0,0}, 355 | {0,1,0,0,0,0,1,0}, 356 | {0,1,0,0,0,0,1,0}, 357 | {0,1,1,1,1,1,0,0}, 358 | {0,1,0,0,0,0,0,0}, 359 | {0,1,0,0,0,0,0,0}, 360 | {0,1,0,0,0,0,0,0}, 361 | {0,1,0,0,0,0,0,0}, 362 | {0,0,0,0,0,0,0,0} 363 | }, 364 | ['Q'] = { 365 | {0,0,0,0,0,0,0,0}, 366 | {0,0,1,1,1,1,0,0}, 367 | {0,1,0,0,0,0,1,0}, 368 | {0,1,0,0,0,0,1,0}, 369 | {0,1,0,0,0,0,1,0}, 370 | {0,1,0,1,0,0,1,0}, 371 | {0,1,0,0,1,0,1,0}, 372 | {0,1,0,0,0,1,1,0}, 373 | {0,0,1,1,1,1,1,0}, 374 | {0,0,0,0,0,0,0,0} 375 | }, 376 | ['R'] = { 377 | {0,0,0,0,0,0,0,0}, 378 | {0,1,1,1,1,1,0,0}, 379 | {0,1,0,0,0,0,1,0}, 380 | {0,1,0,0,0,0,1,0}, 381 | {0,1,1,1,1,1,0,0}, 382 | {0,1,0,1,0,0,0,0}, 383 | {0,1,0,0,1,0,0,0}, 384 | {0,1,0,0,0,1,0,0}, 385 | {0,1,0,0,0,0,1,0}, 386 | {0,0,0,0,0,0,0,0} 387 | }, 388 | ['S'] = { 389 | {0,0,0,0,0,0,0,0}, 390 | {0,0,1,1,1,1,0,0}, 391 | {0,1,0,0,0,0,1,0}, 392 | {0,1,0,0,0,0,0,0}, 393 | {0,0,1,1,1,1,0,0}, 394 | {0,0,0,0,0,0,1,0}, 395 | {0,0,0,0,0,0,1,0}, 396 | {0,1,0,0,0,0,1,0}, 397 | {0,0,1,1,1,1,0,0}, 398 | {0,0,0,0,0,0,0,0} 399 | }, 400 | ['T'] = { 401 | {0,0,0,0,0,0,0,0}, 402 | {0,1,1,1,1,1,1,0}, 403 | {0,0,0,1,1,0,0,0}, 404 | {0,0,0,1,1,0,0,0}, 405 | {0,0,0,1,1,0,0,0}, 406 | {0,0,0,1,1,0,0,0}, 407 | {0,0,0,1,1,0,0,0}, 408 | {0,0,0,1,1,0,0,0}, 409 | {0,0,0,1,1,0,0,0}, 410 | {0,0,0,0,0,0,0,0} 411 | }, 412 | ['U'] = { 413 | {0,0,0,0,0,0,0,0}, 414 | {0,1,0,0,0,0,1,0}, 415 | {0,1,0,0,0,0,1,0}, 416 | {0,1,0,0,0,0,1,0}, 417 | {0,1,0,0,0,0,1,0}, 418 | {0,1,0,0,0,0,1,0}, 419 | {0,1,0,0,0,0,1,0}, 420 | {0,1,0,0,0,0,1,0}, 421 | {0,0,1,1,1,1,0,0}, 422 | {0,0,0,0,0,0,0,0} 423 | }, 424 | ['V'] = { 425 | {0,0,0,0,0,0,0,0}, 426 | {0,1,0,0,0,0,1,0}, 427 | {0,1,0,0,0,0,1,0}, 428 | {0,1,0,0,0,0,1,0}, 429 | {0,0,1,0,0,1,0,0}, 430 | {0,0,1,0,0,1,0,0}, 431 | {0,0,1,0,0,1,0,0}, 432 | {0,0,0,1,1,0,0,0}, 433 | {0,0,0,1,1,0,0,0}, 434 | {0,0,0,0,0,0,0,0} 435 | }, 436 | ['W'] = { 437 | {0,0,0,0,0,0,0,0}, 438 | {0,1,0,0,0,0,1,0}, 439 | {0,1,0,0,0,0,1,0}, 440 | {0,1,0,0,0,0,1,0}, 441 | {0,1,0,0,0,0,1,0}, 442 | {0,1,0,1,1,0,1,0}, 443 | {0,1,0,1,1,0,1,0}, 444 | {0,0,1,0,0,1,0,0}, 445 | {0,0,1,0,0,1,0,0}, 446 | {0,0,0,0,0,0,0,0} 447 | }, 448 | ['X'] = { 449 | {0,0,0,0,0,0,0,0}, 450 | {0,1,0,0,0,0,1,0}, 451 | {0,0,1,0,0,1,0,0}, 452 | {0,0,1,0,0,1,0,0}, 453 | {0,0,0,1,1,0,0,0}, 454 | {0,0,0,1,1,0,0,0}, 455 | {0,0,1,0,0,1,0,0}, 456 | {0,0,1,0,0,1,0,0}, 457 | {0,1,0,0,0,0,1,0}, 458 | {0,0,0,0,0,0,0,0} 459 | }, 460 | ['Y'] = { 461 | {0,0,0,0,0,0,0,0}, 462 | {0,1,0,0,0,0,1,0}, 463 | {0,0,1,0,0,1,0,0}, 464 | {0,0,0,1,1,0,0,0}, 465 | {0,0,0,1,1,0,0,0}, 466 | {0,0,0,1,1,0,0,0}, 467 | {0,0,0,1,1,0,0,0}, 468 | {0,0,0,1,1,0,0,0}, 469 | {0,0,0,1,1,0,0,0}, 470 | {0,0,0,0,0,0,0,0} 471 | }, 472 | ['Z'] = { 473 | {0,0,0,0,0,0,0,0}, 474 | {0,1,1,1,1,1,1,0}, 475 | {0,0,0,0,0,0,1,0}, 476 | {0,0,0,0,0,1,0,0}, 477 | {0,0,0,0,1,0,0,0}, 478 | {0,0,0,1,0,0,0,0}, 479 | {0,0,1,0,0,0,0,0}, 480 | {0,1,0,0,0,0,0,0}, 481 | {0,1,1,1,1,1,1,0}, 482 | {0,0,0,0,0,0,0,0} 483 | } 484 | }; 485 | -------------------------------------------------------------------------------- /kernel/fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct file_head fhead; 9 | struct file *fshell; 10 | 11 | void fs_init(void *fs_base_addr) 12 | { 13 | struct file *f; 14 | unsigned char i; 15 | unsigned char *file_start_addr = fs_base_addr; 16 | 17 | queue_init((struct list *)&fhead); 18 | fhead.num_files = *(unsigned char *)fs_base_addr; 19 | 20 | file_start_addr += PAGE_SIZE; 21 | for (i = 1; i <= fhead.num_files; i++) { 22 | f = (struct file *)mem_alloc(); 23 | f->head = (struct file_header *)file_start_addr; 24 | f->data_base_addr = 25 | (char *)file_start_addr + sizeof(struct file_header); 26 | file_start_addr += PAGE_SIZE * f->head->block_num; 27 | queue_enq((struct list *)f, (struct list *)&fhead); 28 | } 29 | fshell = (struct file *)fhead.lst.next; 30 | } 31 | 32 | struct file *fs_open(const char *name) 33 | { 34 | struct file *f; 35 | 36 | /* 将来的には、struct fileのtask_idメンバにopenしたタスクの 37 | * TASK_IDを入れるようにする。そして、openしようとしているファ 38 | * イルのtask_idが既に設定されていれば、fs_openはエラーを返す 39 | * ようにする */ 40 | 41 | for (f = (struct file *)fhead.lst.next; f != (struct file *)&fhead; 42 | f = (struct file *)f->lst.next) { 43 | if (!str_compare(name, f->head->name)) 44 | return f; 45 | } 46 | 47 | return NULL; 48 | } 49 | 50 | int fs_close(struct file *f __attribute__ ((unused))) 51 | { 52 | /* 将来的には、fidに対応するstruct fileのtask_idメンバーを設定 53 | * なし(0)にする。 */ 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /kernel/include/asm/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASM_CPU_H_ 2 | #define _ASM_CPU_H_ 3 | 4 | #define GDT_SIZE 16 5 | 6 | #endif /* _ASM_CPU_H_ */ 7 | -------------------------------------------------------------------------------- /kernel/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_H_ 2 | #define _COMMON_H_ 3 | 4 | #define QUEUE_BUF_SIZE 256 5 | 6 | struct queue { 7 | unsigned char buf[QUEUE_BUF_SIZE]; 8 | unsigned char start, end; 9 | unsigned char is_full; 10 | }; 11 | 12 | extern unsigned char error_status; 13 | 14 | int str_compare(const char *src, const char *dst); 15 | void copy_mem(const void *src, void *dst, unsigned int size); 16 | void enqueue(struct queue *q, unsigned char data); 17 | unsigned char dequeue(struct queue *q); 18 | 19 | #endif /* _COMMON_H_ */ 20 | -------------------------------------------------------------------------------- /kernel/include/console_io.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONSOLE_IO_H_ 2 | #define _CONSOLE_IO_H_ 3 | 4 | #define IOADR_KBC_DATA 0x0060 5 | #define IOADR_KBC_DATA_BIT_BRAKE 0x80 6 | #define IOADR_KBC_STATUS 0x0064 7 | #define IOADR_KBC_STATUS_BIT_OBF 0x01 8 | 9 | #define COLUMNS 80 10 | #define ROWS 25 11 | 12 | #define ASCII_ESC 0x1b 13 | #define ASCII_BS 0x08 14 | #define ASCII_HT 0x09 15 | 16 | #ifndef COMPILE_APP 17 | 18 | #define INTR_IR_KB 1 19 | #define INTR_NUM_KB 33 20 | #define INTR_MASK_BIT_KB 0x02 21 | #define SCREEN_START 0xb8000 22 | #define ATTR 0x07 23 | #define CHATT_CNT 1 24 | 25 | struct cursor_position { 26 | unsigned int x, y; 27 | }; 28 | 29 | extern unsigned char keyboard_handler; 30 | extern struct cursor_position cursor_pos; 31 | 32 | void con_init(void); 33 | void update_cursor(void); 34 | void put_char_pos(char c, unsigned char x, unsigned char y); 35 | void put_char(char c); 36 | void put_str(char *str); 37 | void put_str_pos(char *str, unsigned char x, unsigned char y); 38 | void dump_hex(unsigned int val, unsigned int num_digits); 39 | void dump_hex_pos(unsigned int val, unsigned int num_digits, 40 | unsigned char x, unsigned char y); 41 | unsigned char get_keydata_noir(void); 42 | unsigned char get_keydata(void); 43 | unsigned char get_keycode(void); 44 | unsigned char get_keycode_pressed(void); 45 | unsigned char get_keycode_released(void); 46 | char get_char(void); 47 | unsigned int get_line(char *buf, unsigned int buf_size); 48 | 49 | #endif /* COMPILE_APP */ 50 | 51 | #endif /* _CONSOLE_IO_H_ */ 52 | -------------------------------------------------------------------------------- /kernel/include/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef _CPU_H_ 2 | #define _CPU_H_ 3 | 4 | #include 5 | 6 | #define X86_EFLAGS_IF 0x00000200 7 | #define GDT_KERN_DS_OFS 0x0010 8 | 9 | #define GDT_S_SYSTEM 0 10 | #define GDT_S_CODE_OR_DATA 1 11 | #define GDT_TYPE_SYS_TSS_AVAIL 9 12 | #define GDT_TYPE_DATA_RW 2 13 | #define GDT_TYPE_CODE_ER 10 14 | 15 | #define SS_KERNEL_CODE 0x0008 16 | #define SS_KERNEL_DATA 0x0010 17 | 18 | #define sti() __asm__ ("sti"::) 19 | #define cli() __asm__ ("cli"::) 20 | #define x86_get_eflags() ({ \ 21 | unsigned int _v; \ 22 | __asm__ volatile ("\tpushf\n" \ 23 | "\tpopl %0\n":"=r"(_v):); \ 24 | _v; \ 25 | }) 26 | #define x86_get_rflags() ({ \ 27 | unsigned long long _v; \ 28 | __asm__ volatile ("\tpushf\n" \ 29 | "\tpopq %0\n":"=r"(_v):); \ 30 | _v; \ 31 | }) 32 | #ifndef X86_64 33 | #define x86_get_flags x86_get_eflags 34 | #else 35 | #define x86_get_flags x86_get_rflags 36 | #endif 37 | #define x86_get_tr() ({ \ 38 | unsigned short _v; \ 39 | __asm__ volatile ("\tstr %0\n":"=r"(_v):); \ 40 | _v; \ 41 | }) 42 | #define x86_halt() __asm__ ("hlt"::) 43 | 44 | struct segment_descriptor { 45 | union { 46 | struct { 47 | unsigned int a; 48 | unsigned int b; 49 | }; 50 | struct { 51 | unsigned short limit0; 52 | unsigned short base0; 53 | unsigned short base1: 8, type: 4, s: 1, dpl: 2, p: 1; 54 | unsigned short limit1: 4, avl: 1, l: 1, d: 1, g: 1, 55 | base2: 8; 56 | }; 57 | }; 58 | }; 59 | 60 | struct tss { 61 | unsigned short back_link, __blh; 62 | unsigned int esp0; 63 | unsigned short ss0, __ss0h; 64 | unsigned int esp1; 65 | unsigned short ss1, __ss1h; 66 | unsigned int esp2; 67 | unsigned short ss2, __ss2h; 68 | unsigned int __cr3; 69 | unsigned int eip; 70 | unsigned int eflags; 71 | unsigned int eax; 72 | unsigned int ecx; 73 | unsigned int edx; 74 | unsigned int ebx; 75 | unsigned int esp; 76 | unsigned int ebp; 77 | unsigned int esi; 78 | unsigned int edi; 79 | unsigned short es, __esh; 80 | unsigned short cs, __csh; 81 | unsigned short ss, __ssh; 82 | unsigned short ds, __dsh; 83 | unsigned short fs, __fsh; 84 | unsigned short gs, __gsh; 85 | unsigned short ldt, __ldth; 86 | unsigned short trace; 87 | unsigned short io_bitmap_base; 88 | }; 89 | 90 | extern struct segment_descriptor gdt[GDT_SIZE]; 91 | 92 | #ifdef X86_64 93 | void gdt_init(void); 94 | #endif 95 | void gdt_set(unsigned int idx, unsigned int base, unsigned int limit, 96 | unsigned char g, unsigned char d, unsigned char l, 97 | unsigned char dpl, unsigned char s, unsigned char type); 98 | 99 | #endif /* _CPU_H_ */ 100 | -------------------------------------------------------------------------------- /kernel/include/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | extern volatile unsigned char _flag; 5 | 6 | void debug_init(void); 7 | void test_excp_de(void); 8 | void test_excp_pf(void); 9 | 10 | #endif /* __DEBUG_H__ */ 11 | -------------------------------------------------------------------------------- /kernel/include/efi.h: -------------------------------------------------------------------------------- 1 | #ifndef _EFI_H_ 2 | #define _EFI_H_ 3 | 4 | #define EFI_FILE_MODE_READ 0x0000000000000001 5 | #define EFI_FILE_MODE_WRITE 0x0000000000000002 6 | #define EFI_FILE_MODE_CREATE 0x8000000000000000 7 | 8 | #define EFI_FILE_READ_ONLY 0x0000000000000001 9 | 10 | //******************************************************* 11 | // Attributes 12 | //******************************************************* 13 | #define EFI_BLACK 0x00 14 | #define EFI_BLUE 0x01 15 | #define EFI_GREEN 0x02 16 | #define EFI_CYAN 0x03 17 | #define EFI_RED 0x04 18 | #define EFI_MAGENTA 0x05 19 | #define EFI_BROWN 0x06 20 | #define EFI_LIGHTGRAY 0x07 21 | #define EFI_BRIGHT 0x08 22 | #define EFI_DARKGRAY 0x08 23 | #define EFI_LIGHTBLUE 0x09 24 | #define EFI_LIGHTGREEN 0x0A 25 | #define EFI_LIGHTCYAN 0x0B 26 | #define EFI_LIGHTRED 0x0C 27 | #define EFI_LIGHTMAGENTA 0x0D 28 | #define EFI_YELLOW 0x0E 29 | #define EFI_WHITE 0x0F 30 | 31 | #define EFI_BACKGROUND_BLACK 0x00 32 | #define EFI_BACKGROUND_BLUE 0x10 33 | #define EFI_BACKGROUND_GREEN 0x20 34 | #define EFI_BACKGROUND_CYAN 0x30 35 | #define EFI_BACKGROUND_RED 0x40 36 | #define EFI_BACKGROUND_MAGENTA 0x50 37 | #define EFI_BACKGROUND_BROWN 0x60 38 | #define EFI_BACKGROUND_LIGHTGRAY 0x70 39 | 40 | #define EFI_SUCCESS 0 41 | #define EFI_ERROR 0x8000000000000000 42 | #define EFI_UNSUPPORTED (EFI_ERROR | 3) 43 | 44 | #define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 45 | #define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 46 | #define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 47 | #define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 48 | #define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 49 | #define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 50 | 51 | #define EVT_TIMER 0x80000000 52 | #define EVT_RUNTIME 0x40000000 53 | #define EVT_NOTIFY_WAIT 0x00000100 54 | #define EVT_NOTIFY_SIGNAL 0x00000200 55 | #define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 56 | #define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 57 | 58 | #define TPL_APPLICATION 4 59 | #define TPL_CALLBACK 8 60 | #define TPL_NOTIFY 16 61 | #define TPL_HIGH_LEVEL 31 62 | 63 | struct EFI_INPUT_KEY { 64 | unsigned short ScanCode; 65 | unsigned short UnicodeChar; 66 | }; 67 | 68 | struct EFI_GUID { 69 | unsigned int Data1; 70 | unsigned short Data2; 71 | unsigned short Data3; 72 | unsigned char Data4[8]; 73 | }; 74 | 75 | enum EFI_MEMORY_TYPE { 76 | EfiReservedMemoryType, 77 | EfiLoaderCode, 78 | EfiLoaderData, 79 | EfiBootServicesCode, 80 | EfiBootServicesData, 81 | EfiRuntimeServicesCode, 82 | EfiRuntimeServicesData, 83 | EfiConventionalMemory, 84 | EfiUnusableMemory, 85 | EfiACPIReclaimMemory, 86 | EfiACPIMemoryNVS, 87 | EfiMemoryMappedIO, 88 | EfiMemoryMappedIOPortSpace, 89 | EfiPalCode, 90 | EfiMaxMemoryType 91 | }; 92 | 93 | enum EFI_TIMER_DELAY { 94 | TimerCancel, 95 | TimerPeriodic, 96 | TimerRelative 97 | }; 98 | 99 | enum EFI_RESET_TYPE { 100 | EfiResetCold, 101 | EfiResetWarm, 102 | EfiResetShutdown, 103 | EfiResetPlatformSpecific 104 | }; 105 | 106 | struct EFI_DEVICE_PATH_PROTOCOL { 107 | unsigned char Type; 108 | unsigned char SubType; 109 | unsigned char Length[2]; 110 | }; 111 | 112 | struct EFI_MEMORY_DESCRIPTOR { 113 | unsigned int Type; 114 | unsigned long long PhysicalStart; 115 | unsigned long long VirtualStart; 116 | unsigned long long NumberOfPages; 117 | unsigned long long Attribute; 118 | }; 119 | 120 | struct EFI_SYSTEM_TABLE { 121 | char _buf1[44]; 122 | struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL { 123 | unsigned long long _buf; 124 | unsigned long long (*ReadKeyStroke)( 125 | struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, 126 | struct EFI_INPUT_KEY *Key); 127 | void *WaitForKey; 128 | } *ConIn; 129 | unsigned long long _buf2; 130 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { 131 | unsigned long long _buf; 132 | unsigned long long (*OutputString)( 133 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 134 | unsigned short *String); 135 | unsigned long long (*TestString)( 136 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 137 | unsigned short *String); 138 | unsigned long long (*QueryMode)( 139 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 140 | unsigned long long ModeNumber, 141 | unsigned long long *Columns, 142 | unsigned long long *Rows); 143 | unsigned long long (*SetMode)( 144 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 145 | unsigned long long ModeNumber); 146 | unsigned long long (*SetAttribute)( 147 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, 148 | unsigned long long Attribute); 149 | unsigned long long (*ClearScreen)( 150 | struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This); 151 | unsigned long long _buf4[2]; 152 | struct SIMPLE_TEXT_OUTPUT_MODE { 153 | int MaxMode; 154 | int Mode; 155 | int Attribute; 156 | int CursorColumn; 157 | int CursorRow; 158 | unsigned char CursorVisible; 159 | } *Mode; 160 | } *ConOut; 161 | unsigned long long _buf3[2]; 162 | struct EFI_RUNTIME_SERVICES { 163 | char _buf_rs1[24]; 164 | 165 | // 166 | // Time Services 167 | // 168 | unsigned long long _buf_rs2[4]; 169 | 170 | // 171 | // Virtual Memory Services 172 | // 173 | unsigned long long _buf_rs3[2]; 174 | 175 | // 176 | // Variable Services 177 | // 178 | unsigned long long _buf_rs4[3]; 179 | 180 | // 181 | // Miscellaneous Services 182 | // 183 | unsigned long long _buf_rs5; 184 | void (*ResetSystem)(enum EFI_RESET_TYPE ResetType, 185 | unsigned long long ResetStatus, 186 | unsigned long long DataSize, 187 | void *ResetData); 188 | } *RuntimeServices; 189 | struct EFI_BOOT_SERVICES { 190 | char _buf1[24]; 191 | 192 | // 193 | // Task Priority Services 194 | // 195 | unsigned long long _buf2[2]; 196 | 197 | // 198 | // Memory Services 199 | // 200 | unsigned long long _buf3[2]; 201 | unsigned long long (*GetMemoryMap)( 202 | unsigned long long *MemoryMapSize, 203 | struct EFI_MEMORY_DESCRIPTOR *MemoryMap, 204 | unsigned long long *MapKey, 205 | unsigned long long *DescriptorSize, 206 | unsigned int *DescriptorVersion); 207 | unsigned long long (*AllocatePool)( 208 | enum EFI_MEMORY_TYPE PoolType, 209 | unsigned long long Size, 210 | void **Buffer); 211 | unsigned long long (*FreePool)( 212 | void *Buffer); 213 | 214 | // 215 | // Event & Timer Services 216 | // 217 | unsigned long long (*CreateEvent)( 218 | unsigned int Type, 219 | unsigned long long NotifyTpl, 220 | void (*NotifyFunction)(void *Event, void *Context), 221 | void *NotifyContext, 222 | void *Event); 223 | unsigned long long (*SetTimer)(void *Event, 224 | enum EFI_TIMER_DELAY Type, 225 | unsigned long long TriggerTime); 226 | unsigned long long (*WaitForEvent)( 227 | unsigned long long NumberOfEvents, 228 | void **Event, 229 | unsigned long long *Index); 230 | unsigned long long _buf4_2[3]; 231 | 232 | // 233 | // Protocol Handler Services 234 | // 235 | unsigned long long _buf5[9]; 236 | 237 | // 238 | // Image Services 239 | // 240 | unsigned long long (*LoadImage)( 241 | unsigned char BootPolicy, 242 | void *ParentImageHandle, 243 | struct EFI_DEVICE_PATH_PROTOCOL *DevicePath, 244 | void *SourceBuffer, 245 | unsigned long long SourceSize, 246 | void **ImageHandle); 247 | unsigned long long (*StartImage)( 248 | void *ImageHandle, 249 | unsigned long long *ExitDataSize, 250 | unsigned short **ExitData); 251 | unsigned long long _buf6[2]; 252 | unsigned long long (*ExitBootServices)( 253 | void *ImageHandle, 254 | unsigned long long MapKey); 255 | 256 | // 257 | // Miscellaneous Services 258 | // 259 | unsigned long long _buf7[2]; 260 | unsigned long long (*SetWatchdogTimer)( 261 | unsigned long long Timeout, 262 | unsigned long long WatchdogCode, 263 | unsigned long long DataSize, 264 | unsigned short *WatchdogData); 265 | 266 | // 267 | // DriverSupport Services 268 | // 269 | unsigned long long _buf8[2]; 270 | 271 | // 272 | // Open and Close Protocol Services 273 | // 274 | unsigned long long (*OpenProtocol)( 275 | void *Handle, 276 | struct EFI_GUID *Protocol, 277 | void **Interface, 278 | void *AgentHandle, 279 | void *ControllerHandle, 280 | unsigned int Attributes); 281 | unsigned long long _buf9[2]; 282 | 283 | // 284 | // Library Services 285 | // 286 | unsigned long long _buf10[2]; 287 | unsigned long long (*LocateProtocol)( 288 | struct EFI_GUID *Protocol, 289 | void *Registration, 290 | void **Interface); 291 | unsigned long long _buf10_2[2]; 292 | 293 | // 294 | // 32-bit CRC Services 295 | // 296 | unsigned long long _buf11; 297 | 298 | // 299 | // Miscellaneous Services 300 | // 301 | void (*CopyMem)( 302 | void *Destination, 303 | void *Source, 304 | unsigned long long Length); 305 | unsigned long long _buf12[2]; 306 | } *BootServices; 307 | }; 308 | 309 | struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL { 310 | unsigned char Blue; 311 | unsigned char Green; 312 | unsigned char Red; 313 | unsigned char Reserved; 314 | }; 315 | 316 | struct EFI_GRAPHICS_OUTPUT_PROTOCOL { 317 | unsigned long long _buf[3]; 318 | struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE { 319 | unsigned int MaxMode; 320 | unsigned int Mode; 321 | struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION { 322 | unsigned int Version; 323 | unsigned int HorizontalResolution; 324 | unsigned int VerticalResolution; 325 | enum EFI_GRAPHICS_PIXEL_FORMAT { 326 | PixelRedGreenBlueReserved8BitPerColor, 327 | PixelBlueGreenRedReserved8BitPerColor, 328 | PixelBitMask, 329 | PixelBltOnly, 330 | PixelFormatMax 331 | } PixelFormat; 332 | } *Info; 333 | unsigned long long SizeOfInfo; 334 | unsigned long long FrameBufferBase; 335 | unsigned long long FrameBufferSize; 336 | } *Mode; 337 | }; 338 | 339 | struct EFI_SIMPLE_POINTER_STATE { 340 | int RelativeMovementX; 341 | int RelativeMovementY; 342 | int RelativeMovementZ; 343 | unsigned char LeftButton; 344 | unsigned char RightButton; 345 | }; 346 | 347 | struct EFI_SIMPLE_POINTER_PROTOCOL { 348 | unsigned long long (*Reset)( 349 | struct EFI_SIMPLE_POINTER_PROTOCOL *This, 350 | unsigned char ExtendedVerification); 351 | unsigned long long (*GetState)( 352 | struct EFI_SIMPLE_POINTER_PROTOCOL *This, 353 | struct EFI_SIMPLE_POINTER_STATE *State); 354 | void *WaitForInput; 355 | }; 356 | 357 | struct EFI_FILE_INFO { 358 | unsigned char _buf[80]; 359 | unsigned short FileName[]; 360 | }; 361 | 362 | struct EFI_FILE_PROTOCOL { 363 | unsigned long long _buf; 364 | unsigned long long (*Open)(struct EFI_FILE_PROTOCOL *This, 365 | struct EFI_FILE_PROTOCOL **NewHandle, 366 | unsigned short *FileName, 367 | unsigned long long OpenMode, 368 | unsigned long long Attributes); 369 | unsigned long long (*Close)(struct EFI_FILE_PROTOCOL *This); 370 | unsigned long long _buf2; 371 | unsigned long long (*Read)(struct EFI_FILE_PROTOCOL *This, 372 | unsigned long long *BufferSize, 373 | void *Buffer); 374 | unsigned long long (*Write)(struct EFI_FILE_PROTOCOL *This, 375 | unsigned long long *BufferSize, 376 | void *Buffer); 377 | unsigned long long _buf3[4]; 378 | unsigned long long (*Flush)(struct EFI_FILE_PROTOCOL *This); 379 | }; 380 | 381 | struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL { 382 | unsigned long long Revision; 383 | unsigned long long (*OpenVolume)( 384 | struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, 385 | struct EFI_FILE_PROTOCOL **Root); 386 | }; 387 | 388 | struct EFI_KEY_STATE { 389 | unsigned int KeyShiftState; 390 | unsigned char KeyToggleState; 391 | }; 392 | 393 | struct EFI_KEY_DATA { 394 | struct EFI_INPUT_KEY Key; 395 | struct EFI_KEY_STATE KeyState; 396 | }; 397 | 398 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { 399 | unsigned long long (*Reset)( 400 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 401 | unsigned char ExtendedVerification); 402 | unsigned long long (*ReadKeyStrokeEx)( 403 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 404 | struct EFI_KEY_DATA *KeyData); 405 | void *WaitForKeyEx; 406 | unsigned long long (*SetState)( 407 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 408 | unsigned char *KeyToggleState); 409 | unsigned long long (*RegisterKeyNotify)( 410 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 411 | struct EFI_KEY_DATA *KeyData, 412 | unsigned long long (*KeyNotificationFunction)( 413 | struct EFI_KEY_DATA *KeyData), 414 | void **NotifyHandle); 415 | unsigned long long (*UnregisterKeyNotify)( 416 | struct EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, 417 | void *NotificationHandle); 418 | }; 419 | 420 | struct EFI_LOADED_IMAGE_PROTOCOL { 421 | unsigned int Revision; 422 | void *ParentHandle; 423 | struct EFI_SYSTEM_TABLE *SystemTable; 424 | // Source location of the image 425 | void *DeviceHandle; 426 | struct EFI_DEVICE_PATH_PROTOCOL *FilePath; 427 | void *Reserved; 428 | // Image’s load options 429 | unsigned int LoadOptionsSize; 430 | void *LoadOptions; 431 | // Location where image was loaded 432 | void *ImageBase; 433 | unsigned long long ImageSize; 434 | enum EFI_MEMORY_TYPE ImageCodeType; 435 | enum EFI_MEMORY_TYPE ImageDataType; 436 | unsigned long long (*Unload)(void *ImageHandle); 437 | }; 438 | 439 | struct EFI_DEVICE_PATH_TO_TEXT_PROTOCOL { 440 | unsigned long long _buf; 441 | unsigned short *(*ConvertDevicePathToText)( 442 | const struct EFI_DEVICE_PATH_PROTOCOL* DeviceNode, 443 | unsigned char DisplayOnly, 444 | unsigned char AllowShortcuts); 445 | }; 446 | 447 | struct EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL { 448 | struct EFI_DEVICE_PATH_PROTOCOL *(*ConvertTextToDeviceNode) ( 449 | const unsigned short *TextDeviceNode); 450 | struct EFI_DEVICE_PATH_PROTOCOL *(*ConvertTextToDevicePath) ( 451 | const unsigned short *TextDevicePath); 452 | }; 453 | 454 | struct EFI_DEVICE_PATH_UTILITIES_PROTOCOL { 455 | unsigned long long _buf[3]; 456 | struct EFI_DEVICE_PATH_PROTOCOL *(*AppendDeviceNode)( 457 | const struct EFI_DEVICE_PATH_PROTOCOL *DevicePath, 458 | const struct EFI_DEVICE_PATH_PROTOCOL *DeviceNode); 459 | }; 460 | 461 | #endif 462 | -------------------------------------------------------------------------------- /kernel/include/excp.h: -------------------------------------------------------------------------------- 1 | #ifndef _EXCP_H_ 2 | #define _EXCP_H_ 3 | 4 | enum { 5 | EXCP_NUM_DE, 6 | EXCP_NUM_DB, 7 | EXCP_NUM_NMI, 8 | EXCP_NUM_BP, 9 | EXCP_NUM_OF, 10 | EXCP_NUM_BR, 11 | EXCP_NUM_UD, 12 | EXCP_NUM_NM, 13 | EXCP_NUM_DF, 14 | EXCP_NUM_CSO, 15 | EXCP_NUM_TS, 16 | EXCP_NUM_NP, 17 | EXCP_NUM_SS, 18 | EXCP_NUM_GP, 19 | EXCP_NUM_PF, 20 | EXCP_NUM_MF = 16, 21 | EXCP_NUM_AC, 22 | EXCP_NUM_MC, 23 | EXCP_NUM_XM, 24 | EXCP_NUM_VE, 25 | EXCEPTION_MAX 26 | }; 27 | 28 | void exception_handler(void); 29 | void divide_error_handler(void); 30 | void debug_handler(void); 31 | void nmi_handler(void); 32 | void breakpoint_handler(void); 33 | void overflow_handler(void); 34 | void bound_range_exceeded_handler(void); 35 | void invalid_opcode_handler(void); 36 | void device_not_available_handler(void); 37 | void double_fault_handler(void); 38 | void coprocessor_segment_overrun_handler(void); 39 | void invalid_tss_handler(void); 40 | void segment_not_present_handler(void); 41 | void stack_fault_handler(void); 42 | void general_protection_handler(void); 43 | void page_fault_handler(void); 44 | void x87_fpu_floating_point_error_handler(void); 45 | void alignment_check_handler(void); 46 | void machine_check_handler(void); 47 | void simd_floating_point_handler(void); 48 | void virtualization_handler(void); 49 | 50 | void do_exception(void); 51 | void do_page_fault(unsigned int error_code, unsigned int address); 52 | 53 | #endif /* _EXCP_H_ */ 54 | -------------------------------------------------------------------------------- /kernel/include/fb.h: -------------------------------------------------------------------------------- 1 | #ifndef _FB_H_ 2 | #define _FB_H_ 3 | 4 | #include 5 | 6 | struct fb { 7 | unsigned long long base; 8 | unsigned long long size; 9 | unsigned int hr; 10 | unsigned int vr; 11 | }; 12 | 13 | typedef struct EFI_GRAPHICS_OUTPUT_BLT_PIXEL fb_pixel; 14 | 15 | extern struct fb fb; 16 | 17 | void fb_init(struct fb *_fb); 18 | void set_fg(unsigned char r, unsigned char g, unsigned char b); 19 | void set_bg(unsigned char r, unsigned char g, unsigned char b); 20 | inline void draw_px(unsigned int x, unsigned int y, 21 | unsigned char r, unsigned char g, unsigned char b); 22 | inline void draw_px_fg(unsigned int x, unsigned int y); 23 | inline void fill_rect(unsigned int x, unsigned int y, 24 | unsigned int w, unsigned int h, 25 | unsigned char r, unsigned char g, unsigned char b); 26 | void clear_screen(void); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /kernel/include/fbcon.h: -------------------------------------------------------------------------------- 1 | #ifndef _FBCON_H_ 2 | #define _FBCON_H_ 3 | 4 | void fbcon_init(void); 5 | void putc(char c); 6 | void puts(char *s); 7 | char getc(void); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /kernel/include/font.h: -------------------------------------------------------------------------------- 1 | #ifndef _FONT_H_ 2 | #define _FONT_H_ 3 | 4 | #define FONT_WIDTH 8 5 | #define FONT_HEIGHT 10 6 | 7 | extern const unsigned char font_bitmap[][FONT_HEIGHT][FONT_WIDTH]; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /kernel/include/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef _FS_H_ 2 | #define _FS_H_ 3 | 4 | #include 5 | 6 | #define MAX_FILE_NAME 32 7 | #define RESERVED_FILE_HEADER_SIZE 15 8 | 9 | struct file_head { 10 | struct list lst; 11 | unsigned char num_files; 12 | }; 13 | 14 | struct file_header { 15 | char name[MAX_FILE_NAME]; 16 | unsigned char block_num; 17 | unsigned char reserve[RESERVED_FILE_HEADER_SIZE]; 18 | }; 19 | 20 | struct file { 21 | struct list lst; 22 | struct file_header *head; 23 | void *data_base_addr; 24 | }; 25 | 26 | extern struct file *fshell; 27 | 28 | void fs_init(void *fs_base_addr); 29 | struct file *fs_open(const char *name); 30 | int fs_close(struct file *f); 31 | 32 | #endif /* _FS_H_ */ 33 | -------------------------------------------------------------------------------- /kernel/include/intr.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTR_H_ 2 | #define _INTR_H_ 3 | 4 | #define IOADR_MPIC_OCW2 0x0020 5 | #define IOADR_MPIC_OCW2_BIT_MANUAL_EOI 0x60 6 | #define IOADR_MPIC_ICW1 0x0020 7 | #define IOADR_MPIC_ICW2 0x0021 8 | #define IOADR_MPIC_ICW3 0x0021 9 | #define IOADR_MPIC_ICW4 0x0021 10 | #define IOADR_MPIC_OCW1 0x0021 11 | #define IOADR_SPIC_ICW1 0x00a0 12 | #define IOADR_SPIC_ICW2 0x00a1 13 | #define IOADR_SPIC_ICW3 0x00a1 14 | #define IOADR_SPIC_ICW4 0x00a1 15 | #define IOADR_SPIC_OCW1 0x00a1 16 | 17 | #define INTR_NUM_USER128 0x80 18 | 19 | void intr_init(void); 20 | void intr_set_mask_master(unsigned char mask); 21 | unsigned char intr_get_mask_master(void); 22 | void intr_set_mask_slave(unsigned char mask); 23 | unsigned char intr_get_mask_slave(void); 24 | #ifndef X86_64 25 | void intr_set_handler(unsigned char intr_num, unsigned int handler_addr); 26 | #else 27 | void intr_set_handler(unsigned char intr_num, unsigned long long handler_addr); 28 | #endif 29 | 30 | #endif /* _INTR_H_ */ 31 | -------------------------------------------------------------------------------- /kernel/include/io_port.h: -------------------------------------------------------------------------------- 1 | #ifndef _IO_PORT_H_ 2 | #define _IO_PORT_H_ 3 | 4 | #define outb(value, port) \ 5 | __asm__ ("outb %%al,%%dx"::"a" (value),"d" (port)) 6 | 7 | #define inb(port) ({ \ 8 | unsigned char _v; \ 9 | __asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \ 10 | _v; \ 11 | }) 12 | 13 | #define outb_p(value, port) \ 14 | __asm__ ("outb %%al,%%dx\n" \ 15 | "\tjmp 1f\n" \ 16 | "1:\tjmp 1f\n" \ 17 | "1:"::"a" (value),"d" (port)) 18 | 19 | #define inb_p(port) ({ \ 20 | unsigned char _v; \ 21 | __asm__ volatile ("inb %%dx,%%al\n" \ 22 | "\tjmp 1f\n" \ 23 | "1:\tjmp 1f\n" \ 24 | "1:":"=a" (_v):"d" (port)); \ 25 | _v; \ 26 | }) 27 | 28 | #endif /* _IO_PORT_H_ */ 29 | -------------------------------------------------------------------------------- /kernel/include/kbc.h: -------------------------------------------------------------------------------- 1 | #ifndef _KBC_H_ 2 | #define _KBC_H_ 3 | 4 | #define IOADR_KBC_DATA 0x0060 5 | #define IOADR_KBC_DATA_BIT_BRAKE 0x80 6 | #define IOADR_KBC_STATUS 0x0064 7 | #define IOADR_KBC_STATUS_BIT_OBF 0x01 8 | 9 | #define ASCII_ESC 0x1b 10 | #define ASCII_BS 0x08 11 | #define ASCII_HT 0x09 12 | 13 | #define INTR_IR_KB 1 14 | #define INTR_NUM_KB 33 15 | #define INTR_MASK_BIT_KB 0x02 16 | 17 | extern const char keymap[]; 18 | extern unsigned char keyboard_handler; 19 | 20 | unsigned char get_keycode_pressed(void); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /kernel/include/kern_task.h: -------------------------------------------------------------------------------- 1 | #ifndef _KERN_TASK_H_ 2 | #define _KERN_TASK_H_ 3 | 4 | #define KERN_TASK_ID 0 5 | 6 | void kern_task_init(void); 7 | 8 | #endif /* _KERN_TASK_H_ */ 9 | -------------------------------------------------------------------------------- /kernel/include/kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef _KERNEL_H_ 2 | #define _KERNEL_H_ 3 | 4 | enum { 5 | SYSCALL_TIMER_GET_GLOBAL_COUNTER = 1, 6 | SYSCALL_SCHED_WAKEUP_MSEC, 7 | SYSCALL_SCHED_WAKEUP_EVENT, 8 | SYSCALL_CON_GET_CURSOR_POS_Y, 9 | SYSCALL_CON_PUT_STR, 10 | SYSCALL_CON_PUT_STR_POS, 11 | SYSCALL_CON_DUMP_HEX, 12 | SYSCALL_CON_DUMP_HEX_POS, 13 | SYSCALL_CON_GET_LINE, 14 | SYSCALL_OPEN, 15 | SYSCALL_EXEC, 16 | SYSCALL_EXIT 17 | }; 18 | 19 | enum { 20 | EVENT_TYPE_KBD = 1, 21 | EVENT_TYPE_EXIT 22 | }; 23 | 24 | #endif /* _KERNEL_H_ */ 25 | -------------------------------------------------------------------------------- /kernel/include/list.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIST_H_ 2 | #define _LIST_H_ 3 | 4 | struct list { 5 | struct list *next; 6 | struct list *prev; 7 | }; 8 | 9 | #endif /* _LIST_H_ */ 10 | -------------------------------------------------------------------------------- /kernel/include/lock.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOCK_H_ 2 | #define _LOCK_H_ 3 | 4 | void kern_lock(unsigned char *if_bit); 5 | void kern_unlock(unsigned char *if_bit); 6 | 7 | #endif /* _LOCK_H_ */ 8 | -------------------------------------------------------------------------------- /kernel/include/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef __MEMORY_H__ 2 | #define __MEMORY_H__ 3 | 4 | #define PAGE_SIZE 0x1000 5 | #define PAGE_ADDR_MASK 0xfffff000 6 | 7 | struct page_directory_entry { 8 | union { 9 | struct { 10 | unsigned int all; 11 | }; 12 | struct { 13 | unsigned int p: 1, r_w: 1, u_s: 1, pwt: 1, pcd: 1, a: 1, 14 | reserved: 1, ps: 1, g: 1, usable: 3, 15 | pt_base: 20; 16 | }; 17 | }; 18 | }; 19 | struct page_table_entry { 20 | union { 21 | struct { 22 | unsigned int all; 23 | }; 24 | struct { 25 | unsigned int p: 1, r_w: 1, u_s: 1, pwt: 1, pcd: 1, a: 1, 26 | d: 1, pat: 1, g: 1, usable: 3, page_base: 20; 27 | }; 28 | }; 29 | }; 30 | 31 | void mem_init(void); 32 | void mem_page_start(void); 33 | void *mem_alloc(void); 34 | void mem_free(void *page); 35 | 36 | #endif /* __MEMORY_H__ */ 37 | -------------------------------------------------------------------------------- /kernel/include/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUEUE_H_ 2 | #define _QUEUE_H_ 3 | 4 | #include 5 | 6 | void queue_init(struct list *head); 7 | void queue_enq(struct list *entry, struct list *head); 8 | void queue_del(struct list *entry); 9 | void queue_dump(struct list *head); 10 | 11 | #endif /* _QUEUE_H_ */ 12 | -------------------------------------------------------------------------------- /kernel/include/sched.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHED_H_ 2 | #define _SCHED_H_ 3 | 4 | #include 5 | #include 6 | 7 | #define TASK_NUM 3 8 | 9 | extern struct task task_instance_table[TASK_NUM]; 10 | extern struct task *current_task; 11 | 12 | unsigned short sched_get_current(void); 13 | int sched_runq_enq(struct task *t); 14 | int sched_runq_del(struct task *t); 15 | void schedule(void); 16 | int sched_update_wakeupq(void); 17 | void wakeup_after_msec(unsigned int msec); 18 | int sched_update_wakeupevq(unsigned char event_type); 19 | void wakeup_after_event(unsigned char event_type); 20 | 21 | #endif /* _SCHED_H_ */ 22 | -------------------------------------------------------------------------------- /kernel/include/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDDEF_H_ 2 | #define _STDDEF_H_ 3 | 4 | #define NULL ((void *)0) 5 | 6 | #endif /* _STDDEF_H_ */ 7 | -------------------------------------------------------------------------------- /kernel/include/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYSCALL_H_ 2 | #define _SYSCALL_H_ 3 | 4 | unsigned int do_syscall(unsigned int syscall_id, unsigned int arg1, 5 | unsigned int arg2, unsigned int arg3); 6 | 7 | #endif /* _SYSCALL_H_ */ 8 | -------------------------------------------------------------------------------- /kernel/include/task.h: -------------------------------------------------------------------------------- 1 | #ifndef _TASK_H_ 2 | #define _TASK_H_ 3 | 4 | #include 5 | #include 6 | 7 | #define CONTEXT_SWITCH_FN_SIZE 12 8 | #define CONTEXT_SWITCH_FN_TSKNO_FIELD 8 9 | 10 | struct task { 11 | /* ランキュー・ウェイクアップキュー(時間経過待ち・イベント待ち)の 12 | * いずれかに繋がれる(同時に複数のキューに存在することが無いよう 13 | * 運用する) */ 14 | struct task *prev; 15 | struct task *next; 16 | 17 | unsigned short task_id; 18 | struct tss tss; 19 | void (*context_switch)(void); 20 | unsigned char context_switch_func[CONTEXT_SWITCH_FN_SIZE]; 21 | char task_switched_in_time_slice; 22 | unsigned int wakeup_after_msec; 23 | unsigned char wakeup_after_event; 24 | }; 25 | 26 | extern unsigned char context_switch_template[CONTEXT_SWITCH_FN_SIZE]; 27 | 28 | void task_init(struct file *f, int argc, char *argv[]); 29 | void task_exit(struct task *t); 30 | 31 | #endif /* _TASK_H_ */ 32 | -------------------------------------------------------------------------------- /kernel/include/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef _TIMER_H_ 2 | #define _TIMER_H_ 3 | 4 | #define IOADR_PIT_COUNTER0 0x0040 5 | #define IOADR_PIT_CONTROL_WORD 0x0043 6 | #define IOADR_PIT_CONTROL_WORD_BIT_COUNTER0 0x00 7 | #define IOADR_PIT_CONTROL_WORD_BIT_16BIT_READ_LOAD 0x30 8 | #define IOADR_PIT_CONTROL_WORD_BIT_MODE2 0x04 9 | /* Rate Generator */ 10 | 11 | #define INTR_IR_TIMER 0 12 | #define INTR_NUM_TIMER 32 13 | #define INTR_MASK_BIT_TIMER 0x01 14 | 15 | #define TIMER_TICK_MS 10 16 | 17 | extern unsigned char timer_handler; 18 | extern unsigned int global_counter; 19 | 20 | void timer_init(void); 21 | unsigned int timer_get_global_counter(void); 22 | 23 | #endif /* _TIMER_H_ */ 24 | -------------------------------------------------------------------------------- /kernel/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | int kern_init(void) 19 | { 20 | extern unsigned char syscall_handler; 21 | 22 | unsigned char mask; 23 | 24 | /* Setup console */ 25 | cursor_pos.y += 2; 26 | update_cursor(); 27 | 28 | /* Setup exception handler */ 29 | intr_set_handler(EXCP_NUM_DE, (unsigned int)divide_error_handler); 30 | intr_set_handler(EXCP_NUM_DB, (unsigned int)debug_handler); 31 | intr_set_handler(EXCP_NUM_NMI, (unsigned int)nmi_handler); 32 | intr_set_handler(EXCP_NUM_BP, (unsigned int)breakpoint_handler); 33 | intr_set_handler(EXCP_NUM_OF, (unsigned int)overflow_handler); 34 | intr_set_handler(EXCP_NUM_BR, (unsigned int)bound_range_exceeded_handler); 35 | intr_set_handler(EXCP_NUM_UD, (unsigned int)invalid_opcode_handler); 36 | intr_set_handler(EXCP_NUM_NM, (unsigned int)device_not_available_handler); 37 | intr_set_handler(EXCP_NUM_DF, (unsigned int)double_fault_handler); 38 | intr_set_handler(EXCP_NUM_CSO, 39 | (unsigned int)coprocessor_segment_overrun_handler); 40 | intr_set_handler(EXCP_NUM_TS, (unsigned int)invalid_tss_handler); 41 | intr_set_handler(EXCP_NUM_NP, (unsigned int)segment_not_present_handler); 42 | intr_set_handler(EXCP_NUM_SS, (unsigned int)stack_fault_handler); 43 | intr_set_handler(EXCP_NUM_GP, (unsigned int)general_protection_handler); 44 | intr_set_handler(EXCP_NUM_PF, (unsigned int)page_fault_handler); 45 | intr_set_handler(EXCP_NUM_MF, 46 | (unsigned int)x87_fpu_floating_point_error_handler); 47 | intr_set_handler(EXCP_NUM_AC, (unsigned int)alignment_check_handler); 48 | intr_set_handler(EXCP_NUM_MC, (unsigned int)machine_check_handler); 49 | intr_set_handler(EXCP_NUM_XM, (unsigned int)simd_floating_point_handler); 50 | intr_set_handler(EXCP_NUM_VE, (unsigned int)virtualization_handler); 51 | 52 | /* Setup devices */ 53 | con_init(); 54 | timer_init(); 55 | mem_init(); 56 | 57 | /* Setup File System */ 58 | fs_init((void *)0x00011000); 59 | 60 | /* Setup tasks */ 61 | kern_task_init(); 62 | task_init(fshell, 0, NULL); 63 | 64 | /* Start paging */ 65 | mem_page_start(); 66 | 67 | /* Setup interrupt handler and mask register */ 68 | intr_set_handler(INTR_NUM_TIMER, (unsigned int)&timer_handler); 69 | intr_set_handler(INTR_NUM_KB, (unsigned int)&keyboard_handler); 70 | intr_set_handler(INTR_NUM_USER128, (unsigned int)&syscall_handler); 71 | intr_init(); 72 | mask = intr_get_mask_master(); 73 | mask &= ~(INTR_MASK_BIT_TIMER | INTR_MASK_BIT_KB); 74 | intr_set_mask_master(mask); 75 | sti(); 76 | 77 | /* End of kernel initialization process */ 78 | while (1) { 79 | x86_halt(); 80 | } 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /kernel/init_64.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int kern_init(struct EFI_SYSTEM_TABLE *st __attribute__ ((unused)), 10 | struct fb *_fb) 11 | { 12 | fb_init(_fb); 13 | set_fg(255, 255, 255); 14 | set_bg(0, 70, 250); 15 | clear_screen(); 16 | 17 | fbcon_init(); 18 | 19 | gdt_init(); 20 | 21 | unsigned char i; 22 | for (i = 0; i < EXCEPTION_MAX; i++) 23 | intr_set_handler(i, (unsigned long long)&exception_handler); 24 | 25 | intr_set_handler(INTR_NUM_KB, (unsigned long long)&keyboard_handler); 26 | intr_init(); 27 | unsigned char mask = intr_get_mask_master(); 28 | mask &= ~INTR_MASK_BIT_KB; 29 | intr_set_mask_master(mask); 30 | sti(); 31 | 32 | while (1) 33 | x86_halt(); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /kernel/intr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAX_IDT 256 6 | 7 | #ifdef X86_64 8 | unsigned long long idt[MAX_IDT * 2]; 9 | unsigned long long idtr[2]; 10 | #endif 11 | 12 | void intr_init(void) 13 | { 14 | /* マスタPICの初期化 */ 15 | outb_p(0x11, IOADR_MPIC_ICW1); 16 | outb_p(0x20, IOADR_MPIC_ICW2); 17 | outb_p(0x04, IOADR_MPIC_ICW3); 18 | outb_p(0x01, IOADR_MPIC_ICW4); 19 | outb_p(0xff, IOADR_MPIC_OCW1); 20 | 21 | /* スレーブPICの初期化 */ 22 | outb_p(0x11, IOADR_SPIC_ICW1); 23 | outb_p(0x28, IOADR_SPIC_ICW2); 24 | outb_p(0x02, IOADR_SPIC_ICW3); 25 | outb_p(0x01, IOADR_SPIC_ICW4); 26 | outb_p(0xff, IOADR_SPIC_OCW1); 27 | 28 | #ifdef X86_64 29 | idtr[0] = ((unsigned long long)idt << 16) | (MAX_IDT * 16 - 1); 30 | idtr[1] = ((unsigned long long)idt >> 48); 31 | __asm__ ("lidt idtr"); 32 | #endif 33 | } 34 | 35 | void intr_set_mask_master(unsigned char mask) 36 | { 37 | outb_p(mask, IOADR_MPIC_OCW1); 38 | } 39 | 40 | unsigned char intr_get_mask_master(void) 41 | { 42 | return inb_p(IOADR_MPIC_OCW1); 43 | } 44 | 45 | void intr_set_mask_slave(unsigned char mask) 46 | { 47 | outb_p(mask, IOADR_SPIC_OCW1); 48 | } 49 | 50 | unsigned char intr_get_mask_slave(void) 51 | { 52 | return inb_p(IOADR_SPIC_OCW1); 53 | } 54 | 55 | #ifndef X86_64 56 | void intr_set_handler(unsigned char intr_num, unsigned int handler_addr) 57 | { 58 | extern unsigned char idt; 59 | unsigned int intr_dscr_top_half, intr_dscr_bottom_half; 60 | unsigned int *idt_ptr; 61 | 62 | idt_ptr = (unsigned int *)&idt; 63 | intr_dscr_bottom_half = handler_addr; 64 | intr_dscr_top_half = 0x00080000; 65 | intr_dscr_top_half = (intr_dscr_top_half & 0xffff0000) 66 | | (intr_dscr_bottom_half & 0x0000ffff); 67 | intr_dscr_bottom_half = (intr_dscr_bottom_half & 0xffff0000) | 0x00008e00; 68 | if (intr_num == INTR_NUM_USER128) 69 | intr_dscr_bottom_half |= 3 << 13; 70 | idt_ptr += intr_num * 2; 71 | *idt_ptr = intr_dscr_top_half; 72 | *(idt_ptr + 1) = intr_dscr_bottom_half; 73 | } 74 | #else 75 | void intr_set_handler(unsigned char intr_num, unsigned long long handler_addr) 76 | { 77 | unsigned int intr_dscr[3]; 78 | unsigned int *idt_ptr; 79 | unsigned char i; 80 | 81 | idt_ptr = (unsigned int *)idt; 82 | 83 | intr_dscr[0] = (SS_KERNEL_CODE << 16) | (handler_addr & 0x0000ffff); 84 | intr_dscr[1] = (handler_addr & 0xffff0000) | 0x00008e00; 85 | intr_dscr[2] = handler_addr >> 32; 86 | 87 | idt_ptr += intr_num * 4; 88 | for (i = 0; i < 3; i++) 89 | *idt_ptr++ = intr_dscr[i]; 90 | } 91 | #endif 92 | -------------------------------------------------------------------------------- /kernel/kbc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | const char keymap[] = { 7 | 0x00, ASCII_ESC, '1', '2', '3', '4', '5', '6', 8 | '7', '8', '9', '0', '-', '^', ASCII_BS, ASCII_HT, 9 | 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 10 | 'o', 'p', '@', '[', '\n', 0x00, 'a', 's', 11 | 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 12 | ':', 0x00, 0x00, ']', 'z', 'x', 'c', 'v', 13 | 'b', 'n', 'm', ',', '.', '/', 0x00, '*', 14 | 0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '7', 16 | '8', '9', '-', '4', '5', '6', '+', '1', 17 | '2', '3', '0', '.', 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, '_', 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, '\\', 0x00, 0x00 23 | }; 24 | 25 | void do_ir_keyboard(void) 26 | { 27 | unsigned char status; 28 | status = inb_p(IOADR_KBC_STATUS); 29 | if (status & IOADR_KBC_STATUS_BIT_OBF) { 30 | unsigned char keycode = inb_p(IOADR_KBC_DATA); 31 | if (!(keycode & IOADR_KBC_DATA_BIT_BRAKE)) { 32 | char c = keymap[keycode]; 33 | if (('a' <= c) && (c <= 'z')) 34 | c = c - 'a' + 'A'; 35 | else if (c == '\n') 36 | putc('\r'); 37 | putc(c); 38 | } 39 | } 40 | outb_p(IOADR_MPIC_OCW2_BIT_MANUAL_EOI | INTR_IR_KB, 41 | IOADR_MPIC_OCW2); 42 | } 43 | 44 | unsigned char get_keydata_noir(void) 45 | { 46 | while (!(inb_p(IOADR_KBC_STATUS) & IOADR_KBC_STATUS_BIT_OBF)); 47 | return inb_p(IOADR_KBC_DATA); 48 | } 49 | 50 | unsigned char get_keycode_pressed(void) 51 | { 52 | unsigned char keycode; 53 | while ((keycode = get_keydata_noir()) & IOADR_KBC_DATA_BIT_BRAKE); 54 | return keycode & ~IOADR_KBC_DATA_BIT_BRAKE; 55 | } 56 | -------------------------------------------------------------------------------- /kernel/kern_task_init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define KERN_TASK_GDT_IDX 5 6 | 7 | struct tss kern_task_tss; 8 | 9 | static void kern_task_context_switch(void) 10 | { 11 | __asm__("ljmp $0x28, $0"); 12 | } 13 | 14 | void kern_task_init(void) 15 | { 16 | unsigned int old_cr3, cr3 = 0x0008f018; 17 | unsigned short segment_selector = 8 * KERN_TASK_GDT_IDX; 18 | 19 | kern_task_tss.esp0 = 0x0007f800; 20 | kern_task_tss.ss0 = GDT_KERN_DS_OFS; 21 | kern_task_tss.__cr3 = 0x0008f018; 22 | gdt_set(KERN_TASK_GDT_IDX, (unsigned int)&kern_task_tss, 23 | sizeof(kern_task_tss), 0, 0, 0, 0, GDT_S_SYSTEM, 24 | GDT_TYPE_SYS_TSS_AVAIL); 25 | __asm__("movl %%cr3, %0":"=r"(old_cr3):); 26 | cr3 |= old_cr3 & 0x00000fe7; 27 | __asm__("movl %0, %%cr3"::"r"(cr3)); 28 | __asm__("ltr %0"::"r"(segment_selector)); 29 | 30 | /* Setup context switch function */ 31 | task_instance_table[KERN_TASK_ID].context_switch = 32 | kern_task_context_switch; 33 | } 34 | -------------------------------------------------------------------------------- /kernel/lock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void kern_lock(unsigned char *if_bit) 5 | { 6 | /* Save EFlags.IF */ 7 | *if_bit = (x86_get_flags() & X86_EFLAGS_IF) ? 1 : 0; 8 | 9 | /* if saved IF == true, then cli */ 10 | if (*if_bit) 11 | cli(); 12 | } 13 | 14 | void kern_unlock(unsigned char *if_bit) 15 | { 16 | /* if saved IF == true, then sti */ 17 | if (*if_bit) 18 | sti(); 19 | } 20 | -------------------------------------------------------------------------------- /kernel/memory.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define CR4_BIT_PGE (1U << 7) 5 | #define MAX_HEAP_PAGES 64 6 | #define HEAP_START_ADDR 0x00040000 7 | 8 | static char heap_alloc_table[MAX_HEAP_PAGES] = {0}; 9 | 10 | void mem_init(void) 11 | { 12 | struct page_directory_entry *pde; 13 | struct page_table_entry *pte; 14 | unsigned int paging_base_addr; 15 | unsigned int i; 16 | unsigned int cr4; 17 | 18 | /* Enable PGE(Page Global Enable) flag of CR4*/ 19 | __asm__("movl %%cr4, %0":"=r"(cr4):); 20 | cr4 |= CR4_BIT_PGE; 21 | __asm__("movl %0, %%cr4"::"r"(cr4)); 22 | 23 | /* Initialize kernel page directory */ 24 | pde = (struct page_directory_entry *)0x0008f000; 25 | pde->all = 0; 26 | pde->p = 1; 27 | pde->r_w = 1; 28 | pde->pt_base = 0x00090; 29 | pde++; 30 | for (i = 1; i < 0x400; i++) { 31 | pde->all = 0; 32 | pde++; 33 | } 34 | 35 | /* Initialize kernel page table */ 36 | pte = (struct page_table_entry *)0x00090000; 37 | for (i = 0x000; i < 0x007; i++) { 38 | pte->all = 0; 39 | pte++; 40 | } 41 | paging_base_addr = 0x00007; 42 | for (; i <= 0x085; i++) { 43 | pte->all = 0; 44 | pte->p = 1; 45 | pte->r_w = 1; 46 | pte->g = 1; 47 | pte->page_base = paging_base_addr; 48 | paging_base_addr += 0x00001; 49 | pte++; 50 | } 51 | for (; i < 0x095; i++) { 52 | pte->all = 0; 53 | pte++; 54 | } 55 | paging_base_addr = 0x00095; 56 | for (; i <= 0x09f; i++) { 57 | pte->all = 0; 58 | pte->p = 1; 59 | pte->r_w = 1; 60 | pte->g = 1; 61 | pte->page_base = paging_base_addr; 62 | paging_base_addr += 0x00001; 63 | pte++; 64 | } 65 | for (; i < 0x0b8; i++) { 66 | pte->all = 0; 67 | pte++; 68 | } 69 | paging_base_addr = 0x000b8; 70 | for (; i <= 0x0bf; i++) { 71 | pte->all = 0; 72 | pte->p = 1; 73 | pte->r_w = 1; 74 | pte->pwt = 1; 75 | pte->pcd = 1; 76 | pte->g = 1; 77 | pte->page_base = paging_base_addr; 78 | paging_base_addr += 0x00001; 79 | pte++; 80 | } 81 | for (; i < 0x400; i++) { 82 | pte->all = 0; 83 | pte++; 84 | } 85 | } 86 | 87 | void mem_page_start(void) 88 | { 89 | unsigned int cr0; 90 | 91 | __asm__("movl %%cr0, %0":"=r"(cr0):); 92 | cr0 |= 0x80000000; 93 | __asm__("movl %0, %%cr0"::"r"(cr0)); 94 | } 95 | 96 | void *mem_alloc(void) 97 | { 98 | unsigned int i; 99 | 100 | for (i = 0; heap_alloc_table[i] && (i < MAX_HEAP_PAGES); i++); 101 | 102 | if (i >= MAX_HEAP_PAGES) 103 | return (void *)NULL; 104 | 105 | heap_alloc_table[i] = 1; 106 | return (void *)(HEAP_START_ADDR + i * PAGE_SIZE); 107 | } 108 | 109 | void mem_free(void *page) 110 | { 111 | unsigned int i = ((unsigned int)page - HEAP_START_ADDR) / PAGE_SIZE; 112 | heap_alloc_table[i] = 0; 113 | } 114 | -------------------------------------------------------------------------------- /kernel/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void queue_init(struct list *head) 6 | { 7 | head->next = head; 8 | head->prev = head; 9 | } 10 | 11 | void queue_enq(struct list *entry, struct list *head) 12 | { 13 | entry->prev = head->prev; 14 | entry->next = head; 15 | head->prev->next = entry; 16 | head->prev = entry; 17 | } 18 | 19 | void queue_del(struct list *entry) 20 | { 21 | entry->prev->next = entry->next; 22 | entry->next->prev = entry->prev; 23 | } 24 | 25 | void queue_dump(struct list *head) 26 | { 27 | unsigned int n; 28 | struct list *entry; 29 | 30 | put_str("h ="); 31 | dump_hex((unsigned int)head, 8); 32 | put_str(": p="); 33 | dump_hex((unsigned int)head->prev, 8); 34 | put_str(", n="); 35 | dump_hex((unsigned int)head->next, 8); 36 | put_str("\r\n"); 37 | 38 | for (entry = head->next, n = 0; entry != head; entry = entry->next, n++) { 39 | dump_hex(n, 2); 40 | put_str("="); 41 | dump_hex((unsigned int)entry, 8); 42 | put_str(": p="); 43 | dump_hex((unsigned int)entry->prev, 8); 44 | put_str(", n="); 45 | dump_hex((unsigned int)entry->next, 8); 46 | put_str("\r\n"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /kernel/sched.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | static struct { 11 | struct task *head; 12 | unsigned int len; 13 | } run_queue = {NULL, 0}; 14 | static struct { 15 | struct task *head; 16 | unsigned int len; 17 | } wakeup_queue = {NULL, 0}; 18 | static struct { 19 | struct task *head; 20 | unsigned int len; 21 | } wakeup_event_queue = {NULL, 0}; 22 | static struct task dummy_task; 23 | static unsigned char is_task_switched_in_time_slice = 0; 24 | 25 | struct task task_instance_table[TASK_NUM]; 26 | struct task *current_task = NULL; 27 | 28 | unsigned short sched_get_current(void) 29 | { 30 | return x86_get_tr() / 8; 31 | } 32 | 33 | int sched_runq_enq(struct task *t) 34 | { 35 | unsigned char if_bit; 36 | 37 | kern_lock(&if_bit); 38 | 39 | if (run_queue.head) { 40 | t->prev = run_queue.head->prev; 41 | t->next = run_queue.head; 42 | run_queue.head->prev->next = t; 43 | run_queue.head->prev = t; 44 | } else { 45 | t->prev = t; 46 | t->next = t; 47 | run_queue.head = t; 48 | } 49 | run_queue.len++; 50 | 51 | kern_unlock(&if_bit); 52 | 53 | return 0; 54 | } 55 | 56 | int sched_runq_del(struct task *t) 57 | { 58 | unsigned char if_bit; 59 | 60 | if (!run_queue.head) 61 | return -1; 62 | 63 | kern_lock(&if_bit); 64 | 65 | if (run_queue.head->next != run_queue.head) { 66 | if (run_queue.head == t) 67 | run_queue.head = run_queue.head->next; 68 | t->prev->next = t->next; 69 | t->next->prev = t->prev; 70 | } else 71 | run_queue.head = NULL; 72 | run_queue.len--; 73 | 74 | kern_unlock(&if_bit); 75 | 76 | return 0; 77 | } 78 | 79 | void schedule(void) 80 | { 81 | if (!run_queue.head) { 82 | if (current_task) { 83 | current_task = NULL; 84 | outb_p(IOADR_MPIC_OCW2_BIT_MANUAL_EOI | INTR_IR_TIMER, 85 | IOADR_MPIC_OCW2); 86 | task_instance_table[KERN_TASK_ID].context_switch(); 87 | } 88 | } else if (current_task) { 89 | if (current_task != current_task->next) { 90 | current_task = current_task->next; 91 | if (is_task_switched_in_time_slice) { 92 | current_task->task_switched_in_time_slice = 1; 93 | is_task_switched_in_time_slice = 0; 94 | } 95 | outb_p(IOADR_MPIC_OCW2_BIT_MANUAL_EOI | INTR_IR_TIMER, 96 | IOADR_MPIC_OCW2); 97 | current_task->context_switch(); 98 | } 99 | } else { 100 | current_task = run_queue.head; 101 | if (is_task_switched_in_time_slice) { 102 | current_task->task_switched_in_time_slice = 1; 103 | is_task_switched_in_time_slice = 0; 104 | } 105 | outb_p(IOADR_MPIC_OCW2_BIT_MANUAL_EOI | INTR_IR_TIMER, 106 | IOADR_MPIC_OCW2); 107 | current_task->context_switch(); 108 | } 109 | } 110 | 111 | int sched_wakeupq_enq(struct task *t) 112 | { 113 | unsigned char if_bit; 114 | 115 | kern_lock(&if_bit); 116 | 117 | if (wakeup_queue.head) { 118 | t->prev = wakeup_queue.head->prev; 119 | t->next = wakeup_queue.head; 120 | wakeup_queue.head->prev->next = t; 121 | wakeup_queue.head->prev = t; 122 | } else { 123 | t->prev = t; 124 | t->next = t; 125 | wakeup_queue.head = t; 126 | } 127 | wakeup_queue.len++; 128 | 129 | kern_unlock(&if_bit); 130 | 131 | return 0; 132 | } 133 | 134 | int sched_wakeupq_del(struct task *t) 135 | { 136 | unsigned char if_bit; 137 | 138 | if (!wakeup_queue.head) 139 | return -1; 140 | 141 | kern_lock(&if_bit); 142 | 143 | if (wakeup_queue.head->next != wakeup_queue.head) { 144 | if (wakeup_queue.head == t) 145 | wakeup_queue.head = wakeup_queue.head->next; 146 | t->prev->next = t->next; 147 | t->next->prev = t->prev; 148 | } else 149 | wakeup_queue.head = NULL; 150 | wakeup_queue.len--; 151 | 152 | kern_unlock(&if_bit); 153 | 154 | return 0; 155 | } 156 | 157 | int sched_update_wakeupq(void) 158 | { 159 | struct task *t, *next; 160 | unsigned char if_bit; 161 | 162 | if (!wakeup_queue.head) 163 | return -1; 164 | 165 | kern_lock(&if_bit); 166 | 167 | t = wakeup_queue.head; 168 | do { 169 | next = t->next; 170 | if (t->wakeup_after_msec > TIMER_TICK_MS) { 171 | t->wakeup_after_msec -= TIMER_TICK_MS; 172 | } else { 173 | t->wakeup_after_msec = 0; 174 | sched_wakeupq_del(t); 175 | sched_runq_enq(t); 176 | } 177 | t = next; 178 | } while (wakeup_queue.head && t != wakeup_queue.head); 179 | 180 | kern_unlock(&if_bit); 181 | 182 | return 0; 183 | } 184 | 185 | void wakeup_after_msec(unsigned int msec) 186 | { 187 | unsigned char if_bit; 188 | 189 | kern_lock(&if_bit); 190 | 191 | if (current_task->next != current_task) 192 | dummy_task.next = current_task->next; 193 | current_task->wakeup_after_msec = msec; 194 | sched_runq_del(current_task); 195 | sched_wakeupq_enq(current_task); 196 | current_task = &dummy_task; 197 | is_task_switched_in_time_slice = 1; 198 | schedule(); 199 | 200 | kern_unlock(&if_bit); 201 | } 202 | 203 | int sched_wakeupevq_enq(struct task *t) 204 | { 205 | unsigned char if_bit; 206 | 207 | kern_lock(&if_bit); 208 | 209 | if (wakeup_event_queue.head) { 210 | t->prev = wakeup_event_queue.head->prev; 211 | t->next = wakeup_event_queue.head; 212 | wakeup_event_queue.head->prev->next = t; 213 | wakeup_event_queue.head->prev = t; 214 | } else { 215 | t->prev = t; 216 | t->next = t; 217 | wakeup_event_queue.head = t; 218 | } 219 | wakeup_event_queue.len++; 220 | 221 | kern_unlock(&if_bit); 222 | 223 | return 0; 224 | } 225 | 226 | int sched_wakeupevq_del(struct task *t) 227 | { 228 | unsigned char if_bit; 229 | 230 | if (!wakeup_event_queue.head) 231 | return -1; 232 | 233 | kern_lock(&if_bit); 234 | 235 | if (wakeup_event_queue.head->next != wakeup_event_queue.head) { 236 | if (wakeup_event_queue.head == t) 237 | wakeup_event_queue.head = wakeup_event_queue.head->next; 238 | t->prev->next = t->next; 239 | t->next->prev = t->prev; 240 | } else 241 | wakeup_event_queue.head = NULL; 242 | wakeup_event_queue.len--; 243 | 244 | kern_unlock(&if_bit); 245 | 246 | return 0; 247 | } 248 | 249 | int sched_update_wakeupevq(unsigned char event_type) 250 | { 251 | struct task *t, *next; 252 | unsigned char if_bit; 253 | 254 | if (!wakeup_event_queue.head) 255 | return -1; 256 | 257 | kern_lock(&if_bit); 258 | 259 | t = wakeup_event_queue.head; 260 | do { 261 | next = t->next; 262 | if (t->wakeup_after_event == event_type) { 263 | t->wakeup_after_event = 0; 264 | sched_wakeupevq_del(t); 265 | sched_runq_enq(t); 266 | } 267 | t = next; 268 | } while (wakeup_event_queue.head && t != wakeup_event_queue.head); 269 | 270 | kern_unlock(&if_bit); 271 | 272 | return 0; 273 | } 274 | 275 | void wakeup_after_event(unsigned char event_type) 276 | { 277 | unsigned char if_bit; 278 | 279 | kern_lock(&if_bit); 280 | 281 | if (current_task->next != current_task) 282 | dummy_task.next = current_task->next; 283 | current_task->wakeup_after_event = event_type; 284 | sched_runq_del(current_task); 285 | sched_wakeupevq_enq(current_task); 286 | current_task = &dummy_task; 287 | is_task_switched_in_time_slice = 1; 288 | schedule(); 289 | 290 | kern_unlock(&if_bit); 291 | } 292 | -------------------------------------------------------------------------------- /kernel/sys.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | .code32 4 | 5 | .text 6 | 7 | .global kern_init, idt, gdt, keyboard_handler, timer_handler 8 | .global exception_handler, divide_error_handler, debug_handler 9 | .global nmi_handler, breakpoint_handler, overflow_handler 10 | .global bound_range_exceeded_handler, invalid_opcode_handler 11 | .global device_not_available_handler, double_fault_handler 12 | .global coprocessor_segment_overrun_handler, invalid_tss_handler 13 | .global segment_not_present_handler, stack_fault_handler 14 | .global general_protection_handler, page_fault_handler 15 | .global x87_fpu_floating_point_error_handler, alignment_check_handler 16 | .global machine_check_handler, simd_floating_point_handler 17 | .global virtualization_handler, syscall_handler 18 | 19 | movl $0x00080000, %esp 20 | 21 | lgdt gdt_descr 22 | 23 | lea ignore_int, %edx 24 | movl $0x00080000, %eax 25 | movw %dx, %ax 26 | movw $0x8E00, %dx 27 | lea idt, %edi 28 | mov $256, %ecx 29 | rp_sidt: 30 | movl %eax, (%edi) 31 | movl %edx, 4(%edi) 32 | addl $8, %edi 33 | dec %ecx 34 | jne rp_sidt 35 | lidt idt_descr 36 | 37 | pushl $0 38 | pushl $0 39 | pushl $0 40 | pushl $end 41 | pushl $kern_init 42 | ret 43 | 44 | end: 45 | jmp end 46 | 47 | keyboard_handler: 48 | pushal 49 | call do_ir_keyboard 50 | popal 51 | iret 52 | 53 | timer_handler: 54 | pushal 55 | call do_ir_timer 56 | popal 57 | iret 58 | 59 | exception_handler: 60 | popl excp_error_code 61 | pushal 62 | call do_exception 63 | popal 64 | iret 65 | 66 | /* interrupt 0 (#DE) */ 67 | divide_error_handler: 68 | jmp divide_error_handler 69 | iret 70 | 71 | /* interrupt 1 (#DB) */ 72 | debug_handler: 73 | jmp debug_handler 74 | iret 75 | 76 | /* interrupt 2 */ 77 | nmi_handler: 78 | jmp nmi_handler 79 | iret 80 | 81 | /* interrupt 3 (#BP) */ 82 | breakpoint_handler: 83 | jmp breakpoint_handler 84 | iret 85 | 86 | /* interrupt 4 (#OF) */ 87 | overflow_handler: 88 | jmp overflow_handler 89 | iret 90 | 91 | /* interrupt 5 (#BR) */ 92 | bound_range_exceeded_handler: 93 | jmp bound_range_exceeded_handler 94 | iret 95 | 96 | /* interrupt 6 (#UD) */ 97 | invalid_opcode_handler: 98 | jmp invalid_opcode_handler 99 | iret 100 | 101 | /* interrupt 7 (#NM) */ 102 | device_not_available_handler: 103 | jmp device_not_available_handler 104 | iret 105 | 106 | /* interrupt 8 (#DF) */ 107 | double_fault_handler: 108 | jmp double_fault_handler 109 | iret 110 | 111 | /* interrupt 9 */ 112 | coprocessor_segment_overrun_handler: 113 | jmp coprocessor_segment_overrun_handler 114 | iret 115 | 116 | /* interrupt 10 (#TS) */ 117 | invalid_tss_handler: 118 | jmp invalid_tss_handler 119 | iret 120 | 121 | /* interrupt 11 (#NP) */ 122 | segment_not_present_handler: 123 | jmp segment_not_present_handler 124 | iret 125 | 126 | /* interrupt 12 (#SS) */ 127 | stack_fault_handler: 128 | jmp stack_fault_handler 129 | iret 130 | 131 | /* interrupt 13 (#GP) */ 132 | general_protection_handler: 133 | jmp general_protection_handler 134 | iret 135 | 136 | /* interrupt 14 (#PF) */ 137 | page_fault_handler: 138 | popl excp_error_code 139 | pushal 140 | movl %cr2, %eax 141 | pushl %eax 142 | pushl excp_error_code 143 | call do_page_fault 144 | popl %eax 145 | popl %eax 146 | popal 147 | iret 148 | 149 | /* interrupt 16 (#MF) */ 150 | x87_fpu_floating_point_error_handler: 151 | jmp x87_fpu_floating_point_error_handler 152 | iret 153 | 154 | /* interrupt 17 (#AC) */ 155 | alignment_check_handler: 156 | jmp alignment_check_handler 157 | iret 158 | 159 | /* interrupt 18 (#MC) */ 160 | machine_check_handler: 161 | jmp machine_check_handler 162 | iret 163 | 164 | /* interrupt 19 (#XM) */ 165 | simd_floating_point_handler: 166 | jmp simd_floating_point_handler 167 | iret 168 | 169 | /* interrupt 20 (#VE) */ 170 | virtualization_handler: 171 | jmp virtualization_handler 172 | iret 173 | 174 | /* interrupt 128 */ 175 | syscall_handler: 176 | pushl %esp 177 | pushl %ebp 178 | pushl %esi 179 | pushl %edi 180 | pushl %edx 181 | pushl %ecx 182 | pushl %ebx 183 | pushl %eax 184 | call do_syscall 185 | popl %ebx 186 | popl %ebx 187 | popl %ecx 188 | popl %edx 189 | popl %edi 190 | popl %esi 191 | popl %ebp 192 | popl %esp 193 | iret 194 | 195 | ignore_int: 196 | iret 197 | 198 | .data 199 | idt_descr: 200 | .word 256*8-1 /* idt contains 256 entries */ 201 | .long idt 202 | 203 | gdt_descr: 204 | .word GDT_SIZE*8-1 205 | .long gdt 206 | 207 | .balign 8 208 | idt: 209 | .fill 256, 8, 0 /* idt is uninitialized */ 210 | 211 | gdt: 212 | .quad 0x0000000000000000 /* NULL descriptor */ 213 | .quad 0x00cf9a000000ffff /* 4GB(r-x:Code, DPL=0) */ 214 | .quad 0x00cf92000000ffff /* 4GB(rw-:Data, DPL=0) */ 215 | .quad 0x00cffa000000ffff /* 4GB(r-x:Code, DPL=3) */ 216 | .quad 0x00cff2000000ffff /* 4GB(rw-:Data, DPL=3) */ 217 | .fill GDT_SIZE-5, 8, 0 218 | 219 | excp_error_code: 220 | .long 0x00000000 221 | -------------------------------------------------------------------------------- /kernel/sys.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("binary"); 2 | 3 | SECTIONS 4 | { 5 | . = 0x7e00; 6 | .text : {*(.text)} 7 | .rodata : { 8 | *(.strings) 9 | *(.rodata) 10 | *(.rodata.*) 11 | } 12 | .data : {*(.data)} 13 | .bss : {*(.bss)} 14 | 15 | . = 0x7e00 + 0x91fe; 16 | .sign : {SHORT(0xbeef)} 17 | } 18 | -------------------------------------------------------------------------------- /kernel/sys_64.S: -------------------------------------------------------------------------------- 1 | .text 2 | 3 | .global keyboard_handler 4 | keyboard_handler: 5 | push %rax 6 | push %rcx 7 | push %rdx 8 | push %rbx 9 | push %rbp 10 | push %rsi 11 | push %rdi 12 | push %rsp 13 | call do_ir_keyboard 14 | pop %rsp 15 | pop %rdi 16 | pop %rsi 17 | pop %rbp 18 | pop %rbx 19 | pop %rdx 20 | pop %rcx 21 | pop %rax 22 | iretq 23 | 24 | .global exception_handler 25 | exception_handler: 26 | jmp exception_handler 27 | iretq 28 | -------------------------------------------------------------------------------- /kernel/sys_64.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("binary"); 2 | 3 | MEMORY 4 | { 5 | exec_file(r) : ORIGIN = 0x00000000, LENGTH = 1m 6 | ram(wx) : ORIGIN = 0x00110000, LENGTH = 960k 7 | } 8 | 9 | SECTIONS 10 | { 11 | .header : { 12 | QUAD(__bss_start) 13 | QUAD(__bss_end - __bss_start) 14 | } > exec_file 15 | 16 | .body : { 17 | *(.text) 18 | 19 | *(.rodata) 20 | 21 | *(.data) 22 | 23 | __bss_start = .; 24 | *(.bss) 25 | __bss_end = .; 26 | 27 | *(.eh_frame) 28 | } > ram AT> exec_file 29 | } 30 | -------------------------------------------------------------------------------- /kernel/syscall.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | unsigned int do_syscall(unsigned int syscall_id, unsigned int arg1, 11 | unsigned int arg2, unsigned int arg3) 12 | { 13 | unsigned int result = -1; 14 | unsigned int gdt_idx; 15 | unsigned int tss_base_addr; 16 | 17 | switch (syscall_id) { 18 | case SYSCALL_TIMER_GET_GLOBAL_COUNTER: 19 | result = timer_get_global_counter(); 20 | break; 21 | case SYSCALL_SCHED_WAKEUP_MSEC: 22 | wakeup_after_msec(arg1); 23 | result = 0; 24 | break; 25 | case SYSCALL_SCHED_WAKEUP_EVENT: 26 | wakeup_after_event(arg1); 27 | result = 0; 28 | break; 29 | case SYSCALL_CON_GET_CURSOR_POS_Y: 30 | result = (unsigned int)cursor_pos.y; 31 | break; 32 | case SYSCALL_CON_PUT_STR: 33 | put_str((char *)arg1); 34 | result = 0; 35 | break; 36 | case SYSCALL_CON_PUT_STR_POS: 37 | put_str_pos((char *)arg1, (unsigned char)arg2, 38 | (unsigned char)arg3); 39 | result = 0; 40 | break; 41 | case SYSCALL_CON_DUMP_HEX: 42 | dump_hex(arg1, arg2); 43 | result = 0; 44 | break; 45 | case SYSCALL_CON_DUMP_HEX_POS: 46 | dump_hex_pos(arg1, arg2, (unsigned char)(arg3 >> 16), 47 | (unsigned char)(arg3 & 0x0000ffff)); 48 | result= 0; 49 | break; 50 | case SYSCALL_CON_GET_LINE: 51 | result = get_line((char *)arg1, arg2); 52 | break; 53 | case SYSCALL_OPEN: 54 | result = (unsigned int)fs_open((char *)arg1); 55 | break; 56 | case SYSCALL_EXEC: 57 | task_init((struct file *)arg1, (int)arg2, (char **)arg3); 58 | result = 0; 59 | break; 60 | case SYSCALL_EXIT: 61 | gdt_idx = x86_get_tr() / 8; 62 | tss_base_addr = (gdt[gdt_idx].base2 << 24) | 63 | (gdt[gdt_idx].base1 << 16) | (gdt[gdt_idx].base0); 64 | task_exit((struct task *)(tss_base_addr - 0x0000000c)); 65 | result = 0; 66 | break; 67 | } 68 | 69 | return result; 70 | } 71 | -------------------------------------------------------------------------------- /kernel/task.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define GDT_IDX_OFS 5 11 | #define APP_ENTRY_POINT 0x20000030 12 | #define APP_STACK_BASE_USER 0xffffe800 13 | #define APP_STACK_BASE_KERN 0xfffff000 14 | #define APP_STACK_SIZE 4096 15 | #define GDT_USER_CS_OFS 0x0018 16 | #define GDT_USER_DS_OFS 0x0020 17 | 18 | /* 19 | 00000000 : 20 | 0: 55 push %ebp 21 | 1: 89 e5 mov %esp,%ebp 22 | 3: ea 00 00 00 00 00 00 ljmp $0x00,$0x0 23 | a: 5d pop %ebp 24 | b: c3 ret 25 | */ 26 | unsigned char context_switch_template[CONTEXT_SWITCH_FN_SIZE] = { 27 | 0x55, 28 | 0x89, 0xe5, 29 | 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 | 0x5d, 31 | 0xc3 32 | }; 33 | 34 | static unsigned short task_id_counter = 1; 35 | 36 | static int str_get_len(const char *src) 37 | { 38 | int len; 39 | for (len = 0; src[len] != '\0'; len++); 40 | return len + 1; 41 | } 42 | 43 | void task_init(struct file *f, int argc, char *argv[]) 44 | { 45 | struct page_directory_entry *pd_base_addr, *pde; 46 | struct page_table_entry *pt_base_addr, *pt_stack_base_addr, *pte; 47 | struct task *new_task; 48 | unsigned int paging_base_addr, phys_stack_base, phys_stack_base2; 49 | unsigned int i; 50 | unsigned int len = 0; 51 | unsigned int argv_space_num, vsp, arg_size; 52 | unsigned char *sp, *sp2; 53 | char *t; 54 | 55 | /* Allocate task resources */ 56 | pd_base_addr = (struct page_directory_entry *)mem_alloc(); 57 | pt_base_addr = (struct page_table_entry *)mem_alloc(); 58 | pt_stack_base_addr = (struct page_table_entry *)mem_alloc(); 59 | new_task = (struct task *)mem_alloc(); 60 | phys_stack_base = (unsigned int)mem_alloc(); 61 | phys_stack_base2 = (unsigned int)mem_alloc(); 62 | 63 | /* Initialize task page directory */ 64 | pde = pd_base_addr; 65 | pde->all = 0; 66 | pde->p = 1; 67 | pde->r_w = 1; 68 | pde->pt_base = 0x00090; 69 | pde++; 70 | for (i = 1; i < 0x080; i++) { 71 | pde->all = 0; 72 | pde++; 73 | } 74 | pde->all = 0; 75 | pde->p = 1; 76 | pde->r_w = 1; 77 | pde->u_s = 1; 78 | pde->pt_base = (unsigned int)pt_base_addr >> 12; 79 | pde++; 80 | for (i++; i < 0x3ff; i++) { 81 | pde->all = 0; 82 | pde++; 83 | } 84 | pde->all = 0; 85 | pde->p = 1; 86 | pde->r_w = 1; 87 | pde->u_s = 1; 88 | pde->pt_base = (unsigned int)pt_stack_base_addr >> 12; 89 | pde++; 90 | 91 | /* Initialize task page table */ 92 | pte = pt_base_addr; 93 | paging_base_addr = (unsigned int)f->data_base_addr >> 12; 94 | for (i = 0; i < f->head->block_num; i++) { 95 | pte->all = 0; 96 | pte->p = 1; 97 | pte->r_w = 1; 98 | pte->u_s = 1; 99 | pte->page_base = paging_base_addr++; 100 | pte++; 101 | } 102 | for (; i < 0x400; i++) { 103 | pte->all = 0; 104 | pte++; 105 | } 106 | 107 | /* Initialize stack page table */ 108 | pte = pt_stack_base_addr; 109 | for (i = 0; i < 0x3fd; i++) { 110 | pte->all = 0; 111 | pte++; 112 | } 113 | paging_base_addr = phys_stack_base >> 12; 114 | pte->all = 0; 115 | pte->p = 1; 116 | pte->r_w = 1; 117 | pte->u_s = 1; 118 | pte->page_base = paging_base_addr; 119 | pte++; 120 | paging_base_addr = phys_stack_base2 >> 12; 121 | pte->all = 0; 122 | pte->p = 1; 123 | pte->r_w = 1; 124 | pte->u_s = 1; 125 | pte->page_base = paging_base_addr; 126 | pte++; 127 | pte->all = 0; 128 | pte++; 129 | 130 | /* Setup task_id */ 131 | new_task->task_id = task_id_counter++; 132 | 133 | /* Setup context switch function */ 134 | copy_mem(context_switch_template, new_task->context_switch_func, 135 | CONTEXT_SWITCH_FN_SIZE); 136 | new_task->context_switch_func[CONTEXT_SWITCH_FN_TSKNO_FIELD] = 137 | 8 * (new_task->task_id + GDT_IDX_OFS); 138 | new_task->context_switch = (void (*)(void))new_task->context_switch_func; 139 | 140 | /* Setup GDT for task_tss */ 141 | gdt_set(new_task->task_id + GDT_IDX_OFS, (unsigned int)&new_task->tss, 142 | sizeof(struct tss), 0, 0, 0, 3, GDT_S_SYSTEM, 143 | GDT_TYPE_SYS_TSS_AVAIL); 144 | 145 | /* Setup task stack */ 146 | /* スタックにint argcとchar *argv[]を積み、 147 | * call命令でジャンプした直後を再現する。 148 | * 149 | * 例) argc=3, argv={"HOGE", "P", "FUGAA"} 150 | * | VA | 内容 | 備考 | 151 | * |-------------+-------------------+--------------------------------| 152 | * | 0x2000 17d0 | | | 153 | * | 0x2000 17d4 | (Don't Care) | ESPはここを指した状態にする(*) | 154 | * | 0x2000 17d8 | 3 | argc | 155 | * | 0x2000 17dc | 0x2000 17e4 | argv | 156 | * | 0x2000 17e0 | (Don't Care) | | 157 | * | 0x2000 17e4 | 0x2000 17f0 | argv[0] | 158 | * | 0x2000 17e8 | 0x2000 17f5 | argv[1] | 159 | * | 0x2000 17ec | 0x2000 17f7 | argv[2] | 160 | * | 0x2000 17f0 | 'H' 'O' 'G' 'E' | | 161 | * | 0x2000 17f4 | '\0' 'P' '\0' 'F' | | 162 | * | 0x2000 17f8 | 'U' 'G' 'A' 'A' | | 163 | * | 0x2000 17fc | '\0' | | 164 | * |-------------+-------------------+--------------------------------| 165 | * | 0x2000 1800 | | | 166 | * (*) call命令はnearジャンプ時、call命令の次の命令のアドレスを 167 | * 復帰時のEIPとしてスタックに積むため。 168 | */ 169 | for (i = 0; i < (unsigned int)argc; i++) { 170 | len += str_get_len(argv[i]); 171 | } 172 | argv_space_num = (len / 4) + 1; 173 | arg_size = 4 * (4 + argc + argv_space_num); 174 | 175 | sp = (unsigned char *)(phys_stack_base2 + (APP_STACK_SIZE / 2)); 176 | sp -= arg_size; 177 | 178 | sp += 4; 179 | 180 | *(int *)sp = argc; 181 | sp += 4; 182 | 183 | *(unsigned int *)sp = APP_STACK_BASE_USER - (4 * (argc + argv_space_num)); 184 | sp += 4; 185 | 186 | sp += 4; 187 | 188 | vsp = APP_STACK_BASE_USER - (4 * argv_space_num); 189 | sp2 = sp + (4 * argc); 190 | for (i = 0; i < (unsigned int)argc; i++) { 191 | *(unsigned int *)sp = vsp; 192 | sp += 4; 193 | t = argv[i]; 194 | for (; *t != '\0'; t++) { 195 | vsp++; 196 | *sp2++ = *t; 197 | } 198 | *sp2++ = '\0'; 199 | vsp++; 200 | } 201 | 202 | /* Setup task_tss */ 203 | new_task->tss.eip = APP_ENTRY_POINT; 204 | new_task->tss.esp = APP_STACK_BASE_USER - arg_size; 205 | new_task->tss.eflags = 0x00000200; 206 | new_task->tss.esp0 = APP_STACK_BASE_KERN; 207 | new_task->tss.ss0 = GDT_KERN_DS_OFS; 208 | new_task->tss.es = GDT_USER_DS_OFS | 0x0003; 209 | new_task->tss.cs = GDT_USER_CS_OFS | 0x0003; 210 | new_task->tss.ss = GDT_USER_DS_OFS | 0x0003; 211 | new_task->tss.ds = GDT_USER_DS_OFS | 0x0003; 212 | new_task->tss.fs = GDT_USER_DS_OFS | 0x0003; 213 | new_task->tss.gs = GDT_USER_DS_OFS | 0x0003; 214 | new_task->tss.__cr3 = (unsigned int)pd_base_addr | 0x18; 215 | 216 | /* Add task to run_queue */ 217 | sched_runq_enq(new_task); 218 | } 219 | 220 | void task_exit(struct task *t) 221 | { 222 | unsigned char if_bit; 223 | struct page_directory_entry *pd_base_addr, *pde; 224 | struct page_table_entry *pt_base_addr, *pt_stack_base_addr, *pte; 225 | unsigned int phys_stack_base, phys_stack_base2; 226 | 227 | kern_lock(&if_bit); 228 | 229 | sched_update_wakeupevq(EVENT_TYPE_EXIT); 230 | sched_runq_del(t); 231 | 232 | pd_base_addr = 233 | (struct page_directory_entry *)(t->tss.__cr3 & PAGE_ADDR_MASK); 234 | pde = pd_base_addr + 0x080; 235 | pt_base_addr = (struct page_table_entry *)(pde->pt_base << 12); 236 | pde = pd_base_addr + 0x3ff; 237 | pt_stack_base_addr = (struct page_table_entry *)(pde->pt_base << 12); 238 | pte = pt_stack_base_addr + 0x3fd; 239 | phys_stack_base = pte->page_base << 12; 240 | pte = pt_stack_base_addr + 0x3fe; 241 | phys_stack_base2 = pte->page_base << 12; 242 | 243 | mem_free((void *)phys_stack_base2); 244 | mem_free((void *)phys_stack_base); 245 | mem_free(t); 246 | mem_free(pt_stack_base_addr); 247 | mem_free(pt_base_addr); 248 | mem_free(pd_base_addr); 249 | 250 | schedule(); 251 | 252 | kern_unlock(&if_bit); 253 | } 254 | -------------------------------------------------------------------------------- /kernel/timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | unsigned int global_counter = 0; 7 | 8 | void do_ir_timer(void) 9 | { 10 | global_counter += TIMER_TICK_MS; 11 | sched_update_wakeupq(); 12 | if (!current_task || !current_task->task_switched_in_time_slice) { 13 | /* タイムスライス中のコンテキストスイッチではない */ 14 | schedule(); 15 | } else { 16 | /* タイムスライス中のコンテキストスイッチである */ 17 | current_task->task_switched_in_time_slice = 0; 18 | } 19 | outb_p(IOADR_MPIC_OCW2_BIT_MANUAL_EOI | INTR_IR_TIMER, IOADR_MPIC_OCW2); 20 | } 21 | 22 | void timer_init(void) 23 | { 24 | /* Setup PIT */ 25 | outb_p(IOADR_PIT_CONTROL_WORD_BIT_COUNTER0 26 | | IOADR_PIT_CONTROL_WORD_BIT_16BIT_READ_LOAD 27 | | IOADR_PIT_CONTROL_WORD_BIT_MODE2, IOADR_PIT_CONTROL_WORD); 28 | /* 割り込み周期11932(0x2e9c)サイクル(=100Hz、10ms毎)に設定 */ 29 | outb_p(0x9c, IOADR_PIT_COUNTER0); 30 | outb_p(0x2e, IOADR_PIT_COUNTER0); 31 | } 32 | 33 | unsigned int timer_get_global_counter(void) 34 | { 35 | return global_counter; 36 | } 37 | -------------------------------------------------------------------------------- /tools/cap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | work_dir=cap_$(date '+%Y%m%d%H%M%S') 4 | 5 | mkdir ${work_dir} 6 | 7 | qemu-system-i386 -fda fd.img & 8 | 9 | sleep 1 10 | echo "convert -loop 0 -delay 15 ${work_dir}/cap_*.gif anime.gif" 11 | 12 | window_id=$(xwininfo -name QEMU | grep 'Window id' | cut -d' ' -f4) 13 | 14 | i=0 15 | while :; do 16 | import -window ${window_id} "${work_dir}/$(printf 'cap_%04d.gif' $i)" 17 | i=$((i + 1)) 18 | sleep 0.1 19 | done 20 | -------------------------------------------------------------------------------- /tools/make_os5_fs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | block_size=4096 4 | 5 | # make control block 6 | echo $# | awk '{printf "%c", $1}' 7 | dd if=/dev/zero count=$((block_size - 1)) bs=1 8 | 9 | # make data block(s) 10 | while [ -n "$1" ]; do 11 | # make header 12 | name=$(basename $1) 13 | echo -n $name 14 | dd if=/dev/zero count=$((32 - ${#name})) bs=1 15 | header_size=48 16 | data_size=$(stat -c '%s' $1) 17 | block_num=$((((header_size + data_size) / block_size) + 1)) 18 | echo $block_num | awk '{printf "%c", $1}' 19 | dd if=/dev/zero count=15 bs=1 20 | 21 | # make data 22 | dd if=$1 23 | data_size_1st_block=$((block_size - header_size)) 24 | if [ $data_size -le $data_size_1st_block ]; then 25 | dd if=/dev/zero count=$((data_size_1st_block - data_size)) bs=1 26 | else 27 | cnt=$((block_size - ((header_size + data_size) % block_size))) 28 | dd if=/dev/zero count=$cnt bs=1 29 | fi 30 | 31 | shift 32 | done 33 | --------------------------------------------------------------------------------