├── .gitignore ├── LICENSE ├── README.md ├── chapter0 └── README.md ├── chapter1 └── README.md ├── chapter2 ├── Makefile ├── README.md ├── boot │ └── boot.asm ├── kernel │ └── kmain.c └── scripts │ ├── grub.cfg │ └── link.ld ├── chapter3 ├── Makefile ├── README.md ├── boot │ └── boot.asm ├── driver │ ├── kport.c │ └── kvga.c ├── include │ ├── kport.h │ ├── ktypes.h │ └── kvga.h ├── kernel │ ├── .cquery │ └── kmain.c └── scripts │ ├── grub.cfg │ └── link.ld ├── chapter4 ├── Makefile ├── README.md ├── boot │ └── boot.asm ├── driver │ ├── kport.c │ └── kvga.c ├── include │ ├── karg.h │ ├── kdebug.h │ ├── kelf.h │ ├── kio.h │ ├── kmultiboot.h │ ├── kport.h │ ├── kstring.h │ ├── ktypes.h │ └── kvga.h ├── kernel │ ├── kio.c │ └── kmain.c ├── lib │ ├── kdebug.c │ ├── kelf.c │ └── kstring.c └── scripts │ ├── gdbinit │ ├── grub.cfg │ └── link.ld ├── chapter5 ├── Makefile ├── README.md ├── boot │ └── boot.asm ├── driver │ ├── kport.c │ └── kvga.c ├── include │ ├── karg.h │ ├── kdebug.h │ ├── kelf.h │ ├── kgdt.h │ ├── kio.h │ ├── kmultiboot.h │ ├── kport.h │ ├── kstring.h │ ├── ktypes.h │ └── kvga.h ├── init │ ├── kgdt.asm │ └── kgdt.c ├── kernel │ ├── kio.c │ └── kmain.c ├── lib │ ├── kdebug.c │ ├── kelf.c │ └── kstring.c └── scripts │ ├── gdbinit │ ├── grub.cfg │ └── link.ld ├── chapter6 ├── Makefile ├── README.md ├── boot │ └── boot.asm ├── driver │ ├── kport.c │ └── kvga.c ├── include │ ├── karg.h │ ├── kdebug.h │ ├── kelf.h │ ├── kgdt.h │ ├── kidt.h │ ├── kio.h │ ├── kisr.h │ ├── kmultiboot.h │ ├── kport.h │ ├── kstring.h │ ├── ktypes.h │ └── kvga.h ├── init │ ├── kgdt.asm │ ├── kgdt.c │ ├── kidt.asm │ ├── kidt.c │ ├── kisr.asm │ └── kisr.c ├── kernel │ ├── kio.c │ └── kmain.c ├── lib │ ├── kdebug.c │ ├── kelf.c │ └── kstring.c └── scripts │ ├── gdbinit │ ├── grub.cfg │ └── link.ld ├── chapter7 ├── Makefile ├── README.md ├── boot │ └── boot.asm ├── driver │ ├── kport.c │ └── kvga.c ├── include │ ├── karg.h │ ├── kdebug.h │ ├── kelf.h │ ├── kgdt.h │ ├── kidt.h │ ├── kio.h │ ├── kisr.h │ ├── kmultiboot.h │ ├── kpit.h │ ├── kport.h │ ├── kstring.h │ ├── ktypes.h │ └── kvga.h ├── init │ ├── kgdt.asm │ ├── kgdt.c │ ├── kidt.asm │ ├── kidt.c │ ├── kisr.asm │ ├── kisr.c │ └── kpit.c ├── kernel │ ├── kio.c │ └── kmain.c ├── lib │ ├── kdebug.c │ ├── kelf.c │ └── kstring.c └── scripts │ ├── gdbinit │ ├── grub.cfg │ └── link.ld └── etc ├── Screenshot from 2018-04-18 09-27-34.png ├── Screenshot from 2018-04-18 11-39-42.png ├── Screenshot from 2018-04-20 09-33-54.png ├── Screenshot from 2018-04-21 09-15-08.png ├── Screenshot from 2018-04-22 12-53-01.png └── Screenshot from 2018-04-22 16-48-51.png /.gitignore: -------------------------------------------------------------------------------- 1 | */build 2 | */.cquery 3 | */.cquery_cached_index 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Osmanthus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Osmanthus-tutorial 2 | 3 | this tutorial is base on the developing operating system kernel [Osmanthus](https://github.com/iosmanthus/Osmanthus) -------------------------------------------------------------------------------- /chapter0/README.md: -------------------------------------------------------------------------------- 1 | # Chapter0 -- 前言 2 | 3 | 本教程旨在通过逐步解析的方式, 帮助读者构建起一个简易内核 4 | 5 | 我们的目标是: 6 | 7 | 1. 通过GRUB引导 8 | 2. VGA兼容模式驱动 9 | 3. 格式打印函数 && 内核调试函数 10 | 4. GDT表的设置 11 | 5. IDT表的设置 12 | 6. 中断管理 13 | 7. 定时器编程 14 | 8. 物理内存管理 15 | 9. 虚拟内存管理 16 | 10. 内核堆管理 17 | 11. 内核级多线程 18 | 19 | 20 | 不用觉得这些有多高大上, 写这篇东西的人只是一个大二的小菜鸡, 哈哈 21 | 22 | 这篇教程大部分是参考了[x86架构操作系统内核的实现](http://wiki.0xffffff.org), 当然也有一些改进和除虫的地方, 具体细节的阐述方法也不一样. 无论如何, 我都十分佩服作者刘欢能够写出这么优质的博客. 23 | 24 | 当然还有[JamesM's kernel development tutorials](http://www.jamesmolloy.co.uk/tutorial_html/), 说实话这个我没参考多少, 看上去挺好, 深入进去就发现, 实在是太简陋了, [OSDEV的这篇Wiki](https://wiki.osdev.org/James_Molloy's_Tutorial_Known_Bugs)抓出了他一堆BUG和奇奇怪怪的问题, 但是还是有一定作用的. -------------------------------------------------------------------------------- /chapter1/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 1 -- 搭建基本的开发环境 2 | 3 | 首先, 我们还是选择在`Linux`下来进行我们内核的开发, 本章主要是帮助读者将基本的内核开发环境搭建起来. 4 | 5 | 我们将内核开发循环分为五个步骤: 6 | 7 | 1. 编辑 8 | 9 | 编辑器的选择看个人, 怎么顺手怎么来. 我在本地使用是`emacs` 10 | 11 | 2. 编译 && 汇编 12 | 13 | 这里我们需要要`GCC >= 4.7.1` , 当然`Clang`也是可以的, 但是`Clang`某些编译参数可能不一样. 14 | 15 | 汇编器为了后续的方便, 我们使用`yasm` 而不是`nasm`, `yasm`是兼容`nasm`的, 不同之处是`yasm`具有更加丰富的功能, 在后边的开发中我们可以看到`yasm`可以给我们用汇编编写的函数修改`ElF`属性 16 | 17 | 3. 链接 18 | 19 | 这里我们就用`GNU ld` 20 | 21 | 4. 运行 22 | 23 | 对于运行步骤, 我们需要先对链接好的内核进行打包, 通过`GRUB`提供的工具链生成一个镜像文件, 放到虚拟机中去运行. 这里我们使用`qemu-i386`, 现在大多数发行版提供的默认是`qmeu-x86_64`, 可能各位要去利用包管理器搜索一下`qemu`其他处理器架构的版本. 24 | 25 | 5. 调试 26 | 27 | 这里只需要`GDB`就行了, 不需要其他的工具, 如果需要功能更加强大`gdb`前端, 可以上`github`搜索`gdbgui` 28 | 29 | 30 | 31 | 在我的环境下(`ArchLinux`), 我总结了一下, 我安装的包, 不同的发行版本包名可能不同, 但是基本上是有规律可循的, 用包管理搜索一下就好. 32 | 33 | 1. `yasm` 34 | 2. `gcc` 35 | 3. `gdb` 36 | 4. `grub` 37 | 5. `mtools` 38 | 6. `xorriso` 39 | 7. `qemu-arch-extra` (只要你有`qemu-system-i386`就行) 40 | 8. `git` (版本管理) 41 | 42 | 你可以把我在[Github的项目Clone](https://github.com/iosmanthus/Osmanthus)下来看看能不能编译, 如果没有问题, 那么说明环境已经搭建起来了. 43 | 44 | 如果你遇到了问题, 我建议你粗略的看看我写的`Makefile`, 里边已经说明了一切工具依赖. -------------------------------------------------------------------------------- /chapter2/Makefile: -------------------------------------------------------------------------------- 1 | OS_NAME=Osmanthus 2 | KERNEL_NAME=osmanthus 3 | ISO_DIR=isodir 4 | ISO_NAME=${KERNEL_NAME}.iso 5 | 6 | BUILD=build 7 | SCRIPTS=scripts 8 | BOOT=boot 9 | KERNEL=kernel 10 | INCLUDE=include 11 | 12 | ASM=yasm 13 | CC=gcc 14 | LD=ld 15 | 16 | CFLAGS=-c -m32 -Wextra -Wall \ 17 | -nostdinc -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ 18 | -Xassembler --32 \ 19 | -I${INCLUDE} 20 | 21 | RFLAGS=-DNDEBUG -O0 22 | DFLAGS=-g -ggdb -gstabs+ 23 | 24 | LDFLAGS = -T $(SCRIPTS)/link.ld -m elf_i386 -nostdlib 25 | ASFLAGS = -f elf 26 | 27 | C_SOURCES=${wildcard ${KERNEL}/*.c} 28 | 29 | C_OBJ=$(addprefix ${BUILD}/,${C_SOURCES:.c=_c.o}) 30 | 31 | ASM_SOURCES=${wildcard ${BOOT}/*.asm} 32 | 33 | ASM_OBJ=$(addprefix ${BUILD}/,${ASM_SOURCES:.asm=_asm.o}) 34 | 35 | .PHONY: all 36 | all : CFLAGS+=${DFLAGS} 37 | all : ${BUILD} ${KERNEL_NAME} 38 | @cp ${BUILD}/${KERNEL_NAME} ${BUILD}/${ISO_DIR}/boot/ 39 | @sed 's,os-name,${OS_NAME},g; s,kernel-name,${KERNEL_NAME},g' \ 40 | ${SCRIPTS}/grub.cfg > ${BUILD}/${ISO_DIR}/boot/grub/grub.cfg 41 | @echo -e "\033[0;31mMakeing Kernel ISO \033[0m" 42 | @grub-mkrescue -o ${BUILD}/${ISO_NAME} ${BUILD}/${ISO_DIR} > /dev/null 2>&1 43 | 44 | ${BUILD}: 45 | @echo -e "\033[0;34mBuilding 'build' directory\033[0m" 46 | @mkdir -p $@/${ISO_DIR}/boot/grub \ 47 | $@/${BOOT} \ 48 | $@/${KERNEL} 49 | 50 | 51 | ${KERNEL_NAME} : ${ASM_OBJ} ${C_OBJ} 52 | @echo -e "\033[0;34mLinking kernel \033[0m" 53 | @${LD} ${LDFLAGS} $^ -o ${BUILD}/$@ 54 | 55 | ${BUILD}/%_asm.o : %.asm 56 | @echo -e "\033[0;32mAssembling module :\t\033[0m" $< 57 | @${ASM} ${ASFLAGS} $< -o $@ 58 | 59 | ${BUILD}/%_c.o : %.c 60 | @echo -e "\033[0;32mCompiling module :\t\033[0m" $< 61 | @${CC} ${CFLAGS} $< -o $@ 62 | 63 | .PHONY: run 64 | run: CFLAGS += ${RFLAGS} 65 | run: 66 | @make CFLAGS="${CFLAGS}" --no-print-directory 67 | @echo -e "\033[0;34mStarting QEMU\033[0m" 68 | @qemu-system-i386 \ 69 | ${BUILD}/${ISO_NAME} > /dev/null 2>&1 70 | 71 | .PHONY: release 72 | release: CFLAGS += ${RFLAGS} 73 | release: 74 | @echo -e "\033[0;34mMaking release version\033[0m" 75 | @make CFLAGS="${CFLAGS}" --no-print-directory 76 | 77 | .PHONY: debug 78 | debug: CFLAGS += ${DFLAGS} 79 | debug: 80 | @echo -e "\033[0;34mMaking debug version\033[0m" 81 | @make CFLAGS="${CFLAGS}" --no-print-directory 82 | 83 | 84 | .PHONY: clean 85 | clean: 86 | @echo -e "\033[0;34mCleaning \033[0m" 87 | @rm -rf \ 88 | build/*/*.o 89 | @echo -e "\033[0;31mFinished\033[0m" 90 | -------------------------------------------------------------------------------- /chapter2/boot/boot.asm: -------------------------------------------------------------------------------- 1 | [bits 32] ;; 以下是32位代码 2 | MULTIBOOT_HEADER_MAGIC equ 0x1badb002 ;; 魔数 3 | MULTIBOOT_PAGE_ALIGN equ 1 << 0 ;; 所有引导模块页(4KB)对齐 4 | MULTIBOOT_MEMORY_INFO equ 1 << 1 ;; 将内存信息写到MultiBoot结构体中 5 | 6 | ;; 将上两行属性结合起来 7 | MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO 8 | 9 | ;; 校验码 10 | MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS) 11 | 12 | ;; 内核临时栈大小 13 | KERNEL_STACK_SIZE equ 0x400 14 | 15 | ;; 内核虚拟起始地址 我们先写在这里 暂时不用管他们的作用 16 | ;; KERNEL_VM_OFFSET equ 0xC0000000 17 | 18 | 19 | ;; section .init.text 这个注释以后可以去掉, 我们暂时用.text去代替 20 | 21 | section .text 22 | 23 | dd MULTIBOOT_HEADER_MAGIC ;; 24 | dd MULTIBOOT_HEADER_FLAGS ;; 将定义好的信息写进文件头 25 | dd MULTIBOOT_CHECKSUM ;; 26 | 27 | [global __start:function] ;; 内核入口 :function是yasm的修饰符 28 | [extern kmain] ;; 内核主函数 29 | 30 | __start: 31 | cli 32 | 33 | mov esp, __kernel_stack_top ;; 设置好内核的临时栈顶 34 | and esp, 0xfffffff0 ;; 按16字节对齐 35 | mov ebp , 0x0 ;; 作为以后backtrace的终止条件 36 | 37 | push ebx ;; Grub将内存信息写到了一块内存中, 将内存的首地址放在了ebx 我们作为参数传给内核主函数 38 | call kmain ;; 调用内核主函数 这里我们假定主函数永远不会返回 如果有强迫症 可以将下边注释去掉 39 | ;; 但是正确性在启用分页之后不保证. 40 | 41 | ;;__stop: 42 | ;; hlt 43 | ;; jmp __stop: 44 | 45 | .end 46 | size __start __start.end - __start ;; 指定函数__start的大小 47 | 48 | ;; section .init.data 同上.init.text 49 | section .data 50 | ; Temporary kernel stack 51 | __kernel_stack_base: 52 | times KERNEL_STACK_SIZE db 0 ; 1KB 内核临时栈空间 53 | __kernel_stack_top: 54 | -------------------------------------------------------------------------------- /chapter2/kernel/kmain.c: -------------------------------------------------------------------------------- 1 | typedef struct _KMultiBoot 2 | { 3 | ; 4 | } KMultiBoot; // 暂时不做详细定义 5 | 6 | void hlt() 7 | { 8 | while(1) 9 | __asm__ volatile ("hlt"); 10 | } 11 | 12 | void kmain(KMultiBoot *mb) 13 | { 14 | char *vga = (char *)0xb8000; // VGA 显存首地址 15 | const char *str = "hello world"; 16 | while(*str) { 17 | *vga++=*str++; // 打印hello world ... 18 | *vga++=0x0f; // 黑底白字 19 | } 20 | hlt(); 21 | } 22 | -------------------------------------------------------------------------------- /chapter2/scripts/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "os-name" { 2 | multiboot /boot/kernel-name 3 | } 4 | -------------------------------------------------------------------------------- /chapter2/scripts/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(__start) 2 | SECTIONS 3 | { 4 | PROVIDE( __kernel_begin_addr = . ); 5 | .text : 6 | { 7 | *(.text) 8 | . = ALIGN(4096); 9 | } 10 | .data : 11 | { 12 | *(.data) 13 | *(.rodata) 14 | . = ALIGN(4096); 15 | } 16 | .bss : 17 | { 18 | *(.bss) 19 | . = ALIGN(4096); 20 | } 21 | .stab : 22 | { 23 | *(.stab) 24 | . = ALIGN(4096); 25 | } 26 | .stabstr : 27 | { 28 | *(.stabstr) 29 | . = ALIGN(4096); 30 | } 31 | PROVIDE( __kernel_end_addr = . ); 32 | 33 | /DISCARD/ : { *(.comment) *(.eh_frame) } 34 | } 35 | -------------------------------------------------------------------------------- /chapter3/Makefile: -------------------------------------------------------------------------------- 1 | OS_NAME=Osmanthus 2 | KERNEL_NAME=osmanthus 3 | ISO_DIR=isodir 4 | ISO_NAME=${KERNEL_NAME}.iso 5 | 6 | BUILD=build 7 | SCRIPTS=scripts 8 | BOOT=boot 9 | DRIVER=driver 10 | KERNEL=kernel 11 | INCLUDE=include 12 | 13 | ASM=yasm 14 | CC=gcc 15 | LD=ld 16 | 17 | CFLAGS=-c -m32 -Wextra -Wall \ 18 | -nostdinc -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ 19 | -Xassembler --32 \ 20 | -I${INCLUDE} 21 | 22 | RFLAGS=-DNDEBUG -O0 23 | DFLAGS=-g -ggdb -gstabs+ 24 | 25 | LDFLAGS = -T $(SCRIPTS)/link.ld -m elf_i386 -nostdlib 26 | ASFLAGS = -f elf 27 | 28 | C_SOURCES=${wildcard ${DRIVER}/*.c ${KERNEL}/*.c} 29 | 30 | C_OBJ=$(addprefix ${BUILD}/,${C_SOURCES:.c=_c.o}) 31 | 32 | ASM_SOURCES=${wildcard ${BOOT}/*.asm} 33 | 34 | ASM_OBJ=$(addprefix ${BUILD}/,${ASM_SOURCES:.asm=_asm.o}) 35 | 36 | .PHONY: all 37 | all : CFLAGS+=${DFLAGS} 38 | all : ${BUILD} ${KERNEL_NAME} 39 | @cp ${BUILD}/${KERNEL_NAME} ${BUILD}/${ISO_DIR}/boot/ 40 | @sed 's,os-name,${OS_NAME},g; s,kernel-name,${KERNEL_NAME},g' \ 41 | ${SCRIPTS}/grub.cfg > ${BUILD}/${ISO_DIR}/boot/grub/grub.cfg 42 | @echo -e "\033[0;31mMakeing Kernel ISO \033[0m" 43 | @grub-mkrescue -o ${BUILD}/${ISO_NAME} ${BUILD}/${ISO_DIR} > /dev/null 2>&1 44 | 45 | ${BUILD}: 46 | @echo -e "\033[0;34mBuilding 'build' directory\033[0m" 47 | @mkdir -p $@/${ISO_DIR}/boot/grub \ 48 | $@/${BOOT} \ 49 | $@/${DRIVER} \ 50 | $@/${KERNEL} 51 | 52 | 53 | ${KERNEL_NAME} : ${ASM_OBJ} ${C_OBJ} 54 | @echo -e "\033[0;34mLinking kernel \033[0m" 55 | @${LD} ${LDFLAGS} $^ -o ${BUILD}/$@ 56 | 57 | ${BUILD}/%_asm.o : %.asm 58 | @echo -e "\033[0;32mAssembling module :\t\033[0m" $< 59 | @${ASM} ${ASFLAGS} $< -o $@ 60 | 61 | ${BUILD}/%_c.o : %.c 62 | @echo -e "\033[0;32mCompiling module :\t\033[0m" $< 63 | @${CC} ${CFLAGS} $< -o $@ 64 | 65 | .PHONY: run 66 | run: CFLAGS += ${RFLAGS} 67 | run: 68 | @make CFLAGS="${CFLAGS}" --no-print-directory 69 | @echo -e "\033[0;34mStarting QEMU\033[0m" 70 | @qemu-system-i386 \ 71 | ${BUILD}/${ISO_NAME} > /dev/null 2>&1 72 | 73 | .PHONY: release 74 | release: CFLAGS += ${RFLAGS} 75 | release: 76 | @echo -e "\033[0;34mMaking release version\033[0m" 77 | @make CFLAGS="${CFLAGS}" --no-print-directory 78 | 79 | .PHONY: debug 80 | debug: CFLAGS += ${DFLAGS} 81 | debug: 82 | @echo -e "\033[0;34mMaking debug version\033[0m" 83 | @make CFLAGS="${CFLAGS}" --no-print-directory 84 | 85 | 86 | .PHONY: clean 87 | clean: 88 | @echo -e "\033[0;34mCleaning \033[0m" 89 | @rm -rf \ 90 | build/*/*.o 91 | @echo -e "\033[0;31mFinished\033[0m" 92 | -------------------------------------------------------------------------------- /chapter3/boot/boot.asm: -------------------------------------------------------------------------------- 1 | [bits 32] ;; 以下是32位代码 2 | MULTIBOOT_HEADER_MAGIC equ 0x1badb002 ;; 魔数 3 | MULTIBOOT_PAGE_ALIGN equ 1 << 0 ;; 所有引导模块页(4KB)对齐 4 | MULTIBOOT_MEMORY_INFO equ 1 << 1 ;; 将内存信息写到MultiBoot结构体中 5 | 6 | ;; 将上两行属性结合起来 7 | MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO 8 | 9 | ;; 校验码 10 | MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS) 11 | 12 | ;; 内核临时栈大小 13 | KERNEL_STACK_SIZE equ 0x400 14 | 15 | ;; 内核虚拟起始地址 我们先写在这里 暂时不用管他们的作用 16 | ;; KERNEL_VM_OFFSET equ 0xC0000000 17 | 18 | 19 | ;; section .init.text 这个注释以后可以去掉, 我们暂时用.text去代替 20 | 21 | section .text 22 | 23 | dd MULTIBOOT_HEADER_MAGIC ;; 24 | dd MULTIBOOT_HEADER_FLAGS ;; 将定义好的信息写进文件头 25 | dd MULTIBOOT_CHECKSUM ;; 26 | 27 | [global __start:function] ;; 内核入口 :function是yasm的修饰符 28 | [extern kmain] ;; 内核主函数 29 | 30 | __start: 31 | cli 32 | 33 | mov esp, __kernel_stack_top ;; 设置好内核的临时栈顶 34 | and esp, 0xfffffff0 ;; 按16字节对齐 35 | mov ebp , 0x0 ;; 作为以后backtrace的终止条件 36 | 37 | push ebx ;; Grub将内存信息写到了一块内存中, 将内存的首地址放在了ebx 我们作为参数传给内核主函数 38 | call kmain ;; 调用内核主函数 这里我们假定主函数永远不会返回 如果有强迫症 可以将下边注释去掉 39 | ;; 但是正确性在启用分页之后不保证. 40 | 41 | ;;__stop: 42 | ;; hlt 43 | ;; jmp __stop: 44 | 45 | .end 46 | size __start __start.end - __start ;; 指定函数__start的大小 47 | 48 | ;; section .init.data 同上.init.text 49 | section .data 50 | ; Temporary kernel stack 51 | __kernel_stack_base: 52 | times KERNEL_STACK_SIZE db 0 ; 1KB 内核临时栈空间 53 | __kernel_stack_top: 54 | -------------------------------------------------------------------------------- /chapter3/driver/kport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | void kout(u16 port, u32 data, KDataSize size) 26 | { 27 | if (size == KBYTE) 28 | __asm__ volatile("outb %%al,%%dx" ::"d"(port), "a"(data)); 29 | else if (size == KWORD) 30 | __asm__ volatile("outw %%ax,%%dx" ::"d"(port), "a"(data)); 31 | else if (size == KDWORD) 32 | __asm__ volatile("outl %%eax,%%dx" ::"d"(port), "a"(data)); 33 | } 34 | 35 | u32 kin(u16 port, KDataSize size) 36 | { 37 | u8 db = 0; 38 | u16 dw = 0; 39 | u32 dl = 0; 40 | if (size == KBYTE) { 41 | __asm__ volatile("inb %%dx, %%al" 42 | : "=a"(db) 43 | : "d"(port)); 44 | return db; 45 | } else if (size == KWORD) { 46 | __asm__ volatile("inw %%dx, %%ax" 47 | : "=a"(dw) 48 | : "d"(port)); 49 | return dw; 50 | } else if (size == KDWORD) { 51 | __asm__ volatile("inl %%dx, %%eax" 52 | : "=a"(dl) 53 | : "d"(port)); 54 | return dl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /chapter3/include/kport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KPORTS_H_ 24 | #define _KPORTS_H_ 25 | 26 | #include 27 | 28 | /* 29 | * Write 'data' to 'port' while specifying the data size: 'size' 30 | * */ 31 | void kout(u16 port, u32 data, KDataSize size); 32 | 33 | /* 34 | * Read 'size' byte(s) from 'port' 35 | * */ 36 | u32 kin(u16 port, KDataSize size); 37 | 38 | #endif /* ifndef _KPORTS_H_ */ 39 | -------------------------------------------------------------------------------- /chapter3/include/ktypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KTYPES_H_ 25 | #define _KTYPES_H_ 26 | 27 | #ifndef NULL 28 | #define NULL (void *)0 29 | #endif 30 | 31 | #ifndef EOF 32 | #define EOF -1 33 | #endif /* ifndef EOF */ 34 | 35 | /* Some type alias in 32-bit machine */ 36 | typedef unsigned int u32; 37 | typedef int i32; 38 | typedef unsigned short u16; 39 | typedef short i16; 40 | typedef unsigned char u8; 41 | typedef char i8; 42 | 43 | typedef enum _KDataSize { 44 | KBYTE = sizeof(u8), 45 | KWORD = sizeof(u16), 46 | KDWORD = sizeof(u32) 47 | } KDataSize; 48 | 49 | typedef enum _KMemUnit { B, KB, MB, GB } KMemUnit; 50 | 51 | #endif /* ifndef _KTYPES_H_ */ 52 | -------------------------------------------------------------------------------- /chapter3/include/kvga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KVGA_H_ 24 | #define _KVGA_H_ 25 | 26 | #include 27 | 28 | #define TAB_WIDTH 4 29 | 30 | typedef enum _VgaTextAtrr { 31 | VGA_BLACK = 0, 32 | VGA_BLUE, 33 | VGA_GREEN, 34 | VGA_CYAN, 35 | VGA_RED, 36 | VGA_MAGENTA, 37 | VGA_BROWN, 38 | VGA_LIGHT_GREY, 39 | VGA_DARK_GREY, 40 | VGA_LIGHT_BLUE, 41 | VGA_LIGHT_GREEN, 42 | VGA_LIGHT_CYAN, 43 | VGA_LIGHT_RED, 44 | VGA_LIGHT_MAGENTA, 45 | VGA_LIGHT_BROWN, // Yellow 46 | VGA_WHITE 47 | } VgaTextAtrr; 48 | 49 | i32 kvga_cputc(char ch, VgaTextAtrr bg, VgaTextAtrr fg); // With color 50 | 51 | i32 kvga_putc(char ch); 52 | 53 | i32 kvga_cputs(const char* str, VgaTextAtrr bg, VgaTextAtrr fg); // With color 54 | 55 | i32 kvga_puts(const char* str); 56 | 57 | void kvga_scroll(); 58 | 59 | void kvga_clear(); 60 | 61 | #endif /* ifndef _kvga_H_ */ 62 | -------------------------------------------------------------------------------- /chapter3/kernel/.cquery: -------------------------------------------------------------------------------- 1 | %clang 2 | %c -std=c11 3 | -Wall 4 | -I/home/programmatore/Projects/Osmanthus-tutorial/chapter3/include 5 | 6 | -------------------------------------------------------------------------------- /chapter3/kernel/kmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | typedef struct _KMultiBoot { 4 | ; 5 | } KMultiBoot; // 暂时不做详细定义 6 | 7 | void hlt() { 8 | while (1) 9 | __asm__ volatile("hlt"); 10 | } 11 | 12 | void kmain(KMultiBoot *mb) { 13 | kvga_puts("hello world\n"); 14 | hlt(); 15 | } 16 | -------------------------------------------------------------------------------- /chapter3/scripts/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "os-name" { 2 | multiboot /boot/kernel-name 3 | } 4 | -------------------------------------------------------------------------------- /chapter3/scripts/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(__start) 2 | SECTIONS 3 | { 4 | PROVIDE( __kernel_begin_addr = . ); 5 | .text : 6 | { 7 | *(.text) 8 | . = ALIGN(4096); 9 | } 10 | .data : 11 | { 12 | *(.data) 13 | *(.rodata) 14 | . = ALIGN(4096); 15 | } 16 | .bss : 17 | { 18 | *(.bss) 19 | . = ALIGN(4096); 20 | } 21 | .stab : 22 | { 23 | *(.stab) 24 | . = ALIGN(4096); 25 | } 26 | .stabstr : 27 | { 28 | *(.stabstr) 29 | . = ALIGN(4096); 30 | } 31 | PROVIDE( __kernel_end_addr = . ); 32 | 33 | /DISCARD/ : { *(.comment) *(.eh_frame) } 34 | } 35 | -------------------------------------------------------------------------------- /chapter4/Makefile: -------------------------------------------------------------------------------- 1 | OS_NAME=Osmanthus 2 | KERNEL_NAME=osmanthus 3 | ISO_DIR=isodir 4 | ISO_NAME=${KERNEL_NAME}.iso 5 | 6 | BUILD=build 7 | SCRIPTS=scripts 8 | LIB=lib 9 | BOOT=boot 10 | DRIVER=driver 11 | KERNEL=kernel 12 | INCLUDE=include 13 | 14 | ASM=yasm 15 | CC=gcc 16 | LD=ld 17 | 18 | CFLAGS=-c -m32 -Wextra -Wall \ 19 | -nostdinc -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ 20 | -Xassembler --32 \ 21 | -I${INCLUDE} 22 | 23 | RFLAGS=-DNDEBUG -O0 24 | DFLAGS=-g -ggdb -gstabs+ 25 | 26 | LDFLAGS = -T $(SCRIPTS)/link.ld -m elf_i386 -nostdlib 27 | ASFLAGS = -f elf 28 | 29 | C_SOURCES=${wildcard ${DRIVER}/*.c ${KERNEL}/*.c ${LIB}/*.c } 30 | 31 | C_OBJ=$(addprefix ${BUILD}/,${C_SOURCES:.c=_c.o}) 32 | 33 | ASM_SOURCES=${wildcard ${BOOT}/*.asm} 34 | 35 | ASM_OBJ=$(addprefix ${BUILD}/,${ASM_SOURCES:.asm=_asm.o}) 36 | 37 | .PHONY: all 38 | all : CFLAGS+=${DFLAGS} 39 | all : ${BUILD} ${KERNEL_NAME} 40 | @cp ${BUILD}/${KERNEL_NAME} ${BUILD}/${ISO_DIR}/boot/ 41 | @sed 's,os-name,${OS_NAME},g; s,kernel-name,${KERNEL_NAME},g' \ 42 | ${SCRIPTS}/grub.cfg > ${BUILD}/${ISO_DIR}/boot/grub/grub.cfg 43 | @echo -e "\033[0;31mMakeing Kernel ISO \033[0m" 44 | @grub-mkrescue -o ${BUILD}/${ISO_NAME} ${BUILD}/${ISO_DIR} > /dev/null 2>&1 45 | 46 | ${BUILD}: 47 | @echo -e "\033[0;34mBuilding 'build' directory\033[0m" 48 | @mkdir -p $@/${ISO_DIR}/boot/grub \ 49 | $@/${BOOT} \ 50 | $@/${DRIVER} \ 51 | $@/${KERNEL} \ 52 | $@/${LIB} 53 | 54 | 55 | ${KERNEL_NAME} : ${ASM_OBJ} ${C_OBJ} 56 | @echo -e "\033[0;34mLinking kernel \033[0m" 57 | @${LD} ${LDFLAGS} $^ -o ${BUILD}/$@ 58 | 59 | ${BUILD}/%_asm.o : %.asm 60 | @echo -e "\033[0;32mAssembling module :\t\033[0m" $< 61 | @${ASM} ${ASFLAGS} $< -o $@ 62 | 63 | ${BUILD}/%_c.o : %.c 64 | @echo -e "\033[0;32mCompiling module :\t\033[0m" $< 65 | @${CC} ${CFLAGS} $< -o $@ 66 | 67 | .PHONY: run 68 | run: CFLAGS += ${RFLAGS} 69 | run: 70 | @make CFLAGS="${CFLAGS}" --no-print-directory 71 | @echo -e "\033[0;34mStarting QEMU\033[0m" 72 | @qemu-system-i386 \ 73 | ${BUILD}/${ISO_NAME} > /dev/null 2>&1 74 | 75 | .PHONY: release 76 | release: CFLAGS += ${RFLAGS} 77 | release: 78 | @echo -e "\033[0;34mMaking release version\033[0m" 79 | @make CFLAGS="${CFLAGS}" --no-print-directory 80 | 81 | .PHONY: debug 82 | debug: CFLAGS += ${DFLAGS} 83 | debug: 84 | @echo -e "\033[0;34mMaking debug version\033[0m" 85 | @make CFLAGS="${CFLAGS}" --no-print-directory 86 | 87 | 88 | .PHONY: clean 89 | clean: 90 | @echo -e "\033[0;34mCleaning \033[0m" 91 | @rm -rf \ 92 | build/*/*.o 93 | @echo -e "\033[0;31mFinished\033[0m" 94 | -------------------------------------------------------------------------------- /chapter4/boot/boot.asm: -------------------------------------------------------------------------------- 1 | [bits 32] ;; 以下是32位代码 2 | MULTIBOOT_HEADER_MAGIC equ 0x1badb002 ;; 魔数 3 | MULTIBOOT_PAGE_ALIGN equ 1 << 0 ;; 所有引导模块页(4KB)对齐 4 | MULTIBOOT_MEMORY_INFO equ 1 << 1 ;; 将内存信息写到MultiBoot结构体中 5 | 6 | ;; 将上两行属性结合起来 7 | MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO 8 | 9 | ;; 校验码 10 | MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS) 11 | 12 | ;; 内核临时栈大小 13 | KERNEL_STACK_SIZE equ 0x400 14 | 15 | ;; 内核虚拟起始地址 我们先写在这里 暂时不用管他们的作用 16 | ;; KERNEL_VM_OFFSET equ 0xC0000000 17 | 18 | 19 | ;; section .init.text 这个注释以后可以去掉, 我们暂时用.text去代替 20 | 21 | section .text 22 | 23 | dd MULTIBOOT_HEADER_MAGIC ;; 24 | dd MULTIBOOT_HEADER_FLAGS ;; 将定义好的信息写进文件头 25 | dd MULTIBOOT_CHECKSUM ;; 26 | 27 | [global __start:function] ;; 内核入口 :function是yasm的修饰符 28 | [extern kmain] ;; 内核主函数 29 | 30 | __start: 31 | cli 32 | 33 | mov esp, __kernel_stack_top ;; 设置好内核的临时栈顶 34 | and esp, 0xfffffff0 ;; 按16字节对齐 35 | mov ebp , 0x0 ;; 作为以后backtrace的终止条件 36 | 37 | push ebx ;; Grub将内存信息写到了一块内存中, 将内存的首地址放在了ebx 我们作为参数传给内核主函数 38 | call kmain ;; 调用内核主函数 这里我们假定主函数永远不会返回 如果有强迫症 可以将下边注释去掉 39 | ;; 但是正确性在启用分页之后不保证. 40 | .end 41 | 42 | size __start __start.end - __start ;; 指定函数__start的大小 43 | 44 | ;; section .init.data 同上.init.text 45 | section .data 46 | ; Temporary kernel stack 47 | __kernel_stack_base: 48 | times KERNEL_STACK_SIZE db 0 ; 1KB 内核临时栈空间 49 | __kernel_stack_top: 50 | -------------------------------------------------------------------------------- /chapter4/driver/kport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | void kout(u16 port, u32 data, KDataSize size) 26 | { 27 | if (size == KBYTE) 28 | __asm__ volatile("outb %%al,%%dx" ::"d"(port), "a"(data)); 29 | else if (size == KWORD) 30 | __asm__ volatile("outw %%ax,%%dx" ::"d"(port), "a"(data)); 31 | else if (size == KDWORD) 32 | __asm__ volatile("outl %%eax,%%dx" ::"d"(port), "a"(data)); 33 | } 34 | 35 | u32 kin(u16 port, KDataSize size) 36 | { 37 | u8 db = 0; 38 | u16 dw = 0; 39 | u32 dl = 0; 40 | if (size == KBYTE) { 41 | __asm__ volatile("inb %%dx, %%al" 42 | : "=a"(db) 43 | : "d"(port)); 44 | return db; 45 | } else if (size == KWORD) { 46 | __asm__ volatile("inw %%dx, %%ax" 47 | : "=a"(dw) 48 | : "d"(port)); 49 | return dw; 50 | } else if (size == KDWORD) { 51 | __asm__ volatile("inl %%dx, %%eax" 52 | : "=a"(dl) 53 | : "d"(port)); 54 | return dl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /chapter4/include/karg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KARG_H_ 24 | #define _KARG_H_ 25 | 26 | // Various arguments macro for i386 27 | 28 | #include 29 | 30 | typedef char* kva_list; 31 | 32 | #define kva_start(ap, last) \ 33 | (ap = (kva_list)(((kva_list)&last) + ((sizeof(last) + 3) & ~3))) 34 | 35 | #define kva_arg(ap, type) \ 36 | (*(type*)(ap += ((sizeof(type) + 3) & ~3), \ 37 | ap - ((sizeof(type) + 3) & ~3))) 38 | 39 | #define kva_copy(dst, src) (dst) = (src) 40 | 41 | #define kva_end(ap) (ap = (kva_list)NULL) 42 | 43 | #endif /* ifndef _KARG_H_ */ 44 | -------------------------------------------------------------------------------- /chapter4/include/kdebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KDEBUG_H_ 24 | #define _KDEBUG_H_ 25 | 26 | #ifdef NDEBUG 27 | #define kassert(cond) (void)0 28 | #else 29 | void __kassert(const char* file, int line, const char* func, 30 | const char* expr); 31 | 32 | #define kassert(cond) \ 33 | do { \ 34 | if (!(cond)) { \ 35 | __kassert(__FILE__, __LINE__, __func__, #cond); \ 36 | } \ 37 | } while (0) 38 | #endif 39 | 40 | // Print call stack trace 41 | 42 | void kstack_trace(); 43 | 44 | // Fatal error 45 | void kpanic(const char* msg); 46 | 47 | #endif /* ifndef _KDEBUG_H_ */ 48 | -------------------------------------------------------------------------------- /chapter4/include/kelf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KELF_H_ 24 | #define _KELF_H_ 25 | 26 | #include 27 | #include 28 | 29 | // ELF section header 30 | typedef struct _KELFSectionHeader { 31 | u32 name; 32 | u32 type; 33 | u32 flags; 34 | u32 addr; 35 | u32 offset; 36 | u32 size; 37 | u32 link; 38 | u32 info; 39 | u32 addralign; 40 | u32 entsize; 41 | } __attribute__((packed)) KELFSectionHeader; 42 | 43 | // ELF Symbol 44 | typedef struct _KELFSymbol { 45 | u32 name; 46 | u32 value; 47 | u32 size; 48 | u8 info; 49 | u8 other; 50 | u16 shndx; 51 | } __attribute__((packed)) KELFSymbol; 52 | 53 | // ELF info 54 | typedef struct _KELF { 55 | KELFSymbol* symtab; 56 | u32 symtabsz; 57 | const char* strtab; 58 | u32 strtabsz; 59 | } KELF; 60 | 61 | // Get kernel elf info 62 | KELF kget_kernel_elf_info(const KMultiBoot* mb); 63 | 64 | // Return symbol whose address range includes 'addr' 65 | const char* ksearch_function(u32 addr, const KELF* elf); 66 | 67 | #endif /* ifndef _KELF_H_ */ 68 | -------------------------------------------------------------------------------- /chapter4/include/kio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights 5 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 6 | * copies of the Software, and to permit persons to whom the Software is 7 | * furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in 10 | * all copies or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | #ifndef _KIO_H_ 22 | #define _KIO_H_ 23 | 24 | #include 25 | #include 26 | 27 | // Kernel level I/O functions 28 | 29 | i32 kvsprintf(char *s, const char *fmt, kva_list args); 30 | i32 kprintf(const char *fmt, ...); 31 | i32 kcprintf(VgaTextAtrr bg, VgaTextAtrr fg, const char *fmt, 32 | ...); // With color 33 | i32 kputchar(char ch); 34 | i32 kcputchar(char ch, VgaTextAtrr bg, VgaTextAtrr fg); 35 | i32 kputs(const char *str); 36 | i32 kcputs(VgaTextAtrr bg, VgaTextAtrr fg, const char *str); 37 | 38 | #endif /* ifndef _KIO_H_ */ 39 | -------------------------------------------------------------------------------- /chapter4/include/kmultiboot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KMULTIBOOT_H_ 24 | #define _KMULTIBOOT_H_ 25 | 26 | #include 27 | 28 | typedef struct _KMultiBoot { 29 | u32 flags; 30 | u32 mem_lower; 31 | u32 mem_upper; 32 | 33 | u32 boot_device; 34 | u32 cmdline; 35 | u32 mods_count; 36 | u32 mods_addr; 37 | 38 | u32 num; 39 | u32 size; 40 | u32 addr; 41 | u32 shndx; 42 | 43 | // Memory info 44 | u32 mmap_length; 45 | u32 mmap_addr; 46 | 47 | u32 drives_length; 48 | u32 drives_addr; 49 | u32 config_table; 50 | u32 boot_loader_name; 51 | u32 apm_table; 52 | u32 vbe_control_info; 53 | u32 vbe_mode_info; 54 | u32 vbe_mode; 55 | u32 vbe_interface_seg; 56 | u32 vbe_interface_off; 57 | u32 vbe_interface_len; 58 | } __attribute__((packed)) KMultiBoot; 59 | 60 | typedef struct _KMMapEntry { 61 | u32 size; 62 | u32 base_addr_low; 63 | u32 base_addr_high; 64 | u32 length_low; 65 | u32 length_high; 66 | u32 type; 67 | } __attribute__((packed)) KMMapEntry; 68 | 69 | #define KERNEL_BOOT_INFO (__kernel_multiboot_info) 70 | const KMultiBoot* __kernel_multiboot_info; 71 | 72 | #endif /* ifndef _KMULTIBOOT_H_ */ 73 | -------------------------------------------------------------------------------- /chapter4/include/kport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KPORTS_H_ 24 | #define _KPORTS_H_ 25 | 26 | #include 27 | 28 | /* 29 | * Write 'data' to 'port' while specifying the data size: 'size' 30 | * */ 31 | void kout(u16 port, u32 data, KDataSize size); 32 | 33 | /* 34 | * Read 'size' byte(s) from 'port' 35 | * */ 36 | u32 kin(u16 port, KDataSize size); 37 | 38 | #endif /* ifndef _KPORTS_H_ */ 39 | -------------------------------------------------------------------------------- /chapter4/include/kstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KSTRING_H_ 24 | #define _KSTRING_H_ 25 | 26 | #include 27 | 28 | void* kmemcpy(void* dst, const void* src, u32 n); 29 | 30 | void* kmemset(void* s, u8 c, u32 n); 31 | void* kbzero(void* s, u32 n); 32 | 33 | i32 kstrcmp(const char* s1, const char* s2); 34 | i32 kstrncmp(const char* s1, const char* s2, u32 n); 35 | 36 | char* kstrcpy(char* dst, const char* src); 37 | char* kstrncpy(char* dst, const char* src, u32 n); 38 | 39 | char* kstrcat(char* dest, const char* src); 40 | char* kstrncat(char* dest, const char* src, u32 n); 41 | 42 | u32 kstrlen(const char* s); 43 | 44 | #endif /* ifndef _KSTRING_H_ */ 45 | -------------------------------------------------------------------------------- /chapter4/include/ktypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KTYPES_H_ 25 | #define _KTYPES_H_ 26 | 27 | #ifndef NULL 28 | #define NULL (void *)0 29 | #endif 30 | 31 | #ifndef EOF 32 | #define EOF -1 33 | #endif /* ifndef EOF */ 34 | 35 | /* Some type alias in 32-bit machine */ 36 | typedef unsigned int u32; 37 | typedef int i32; 38 | typedef unsigned short u16; 39 | typedef short i16; 40 | typedef unsigned char u8; 41 | typedef char i8; 42 | 43 | typedef enum _KDataSize { 44 | KBYTE = sizeof(u8), 45 | KWORD = sizeof(u16), 46 | KDWORD = sizeof(u32) 47 | } KDataSize; 48 | 49 | typedef enum _KMemUnit { B, KB, MB, GB } KMemUnit; 50 | 51 | #endif /* ifndef _KTYPES_H_ */ 52 | -------------------------------------------------------------------------------- /chapter4/include/kvga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KVGA_H_ 24 | #define _KVGA_H_ 25 | 26 | #include 27 | 28 | #define TAB_WIDTH 4 29 | 30 | typedef enum _VgaTextAtrr { 31 | VGA_BLACK = 0, 32 | VGA_BLUE, 33 | VGA_GREEN, 34 | VGA_CYAN, 35 | VGA_RED, 36 | VGA_MAGENTA, 37 | VGA_BROWN, 38 | VGA_LIGHT_GREY, 39 | VGA_DARK_GREY, 40 | VGA_LIGHT_BLUE, 41 | VGA_LIGHT_GREEN, 42 | VGA_LIGHT_CYAN, 43 | VGA_LIGHT_RED, 44 | VGA_LIGHT_MAGENTA, 45 | VGA_LIGHT_BROWN, // Yellow 46 | VGA_WHITE 47 | } VgaTextAtrr; 48 | 49 | i32 kvga_cputc(char ch, VgaTextAtrr bg, VgaTextAtrr fg); // With color 50 | 51 | i32 kvga_putc(char ch); 52 | 53 | i32 kvga_cputs(const char* str, VgaTextAtrr bg, VgaTextAtrr fg); // With color 54 | 55 | i32 kvga_puts(const char* str); 56 | 57 | void kvga_scroll(); 58 | 59 | void kvga_clear(); 60 | 61 | #endif /* ifndef _kvga_H_ */ 62 | -------------------------------------------------------------------------------- /chapter4/kernel/kmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void hlt() { 7 | kstack_trace(); 8 | kpanic("Error?!\n"); 9 | while (1) 10 | __asm__ volatile("hlt"); 11 | } 12 | 13 | void kmain(KMultiBoot *mb) { 14 | KERNEL_BOOT_INFO = mb; 15 | hlt(); 16 | } 17 | -------------------------------------------------------------------------------- /chapter4/lib/kdebug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | static KELF kernel_elf; 30 | static const KELF *pkelf = NULL; 31 | 32 | // Define in boot/boot.asm 33 | 34 | static void env_init(); 35 | 36 | void env_init() { 37 | if (pkelf == NULL) { 38 | kernel_elf = kget_kernel_elf_info(KERNEL_BOOT_INFO); 39 | pkelf = &kernel_elf; 40 | } 41 | } 42 | 43 | void kpanic(const char *msg) { 44 | kprintf("****Fatal error eccured****\n" 45 | "****Kernel in panic****\n"); 46 | if (msg) 47 | kprintf("%s\n", msg); 48 | kstack_trace(); 49 | while (1) 50 | ; 51 | } 52 | 53 | void __kassert(const char *file, int line, const char *func, const char *expr) { 54 | kcprintf(VGA_BLACK, VGA_LIGHT_BROWN, 55 | "In file %s: %d function %s asserts '%s' failed\n", file, line, func, 56 | expr); 57 | kpanic(NULL); 58 | } 59 | 60 | void kstack_trace() { 61 | env_init(); 62 | u32 *ebp, *eip; 63 | 64 | // Get %ebp 65 | __asm__ volatile("mov %%ebp,%0" : "=r"(ebp)); 66 | 67 | // %ebp was initiated in boot/boot.asm with 0x0 68 | while (ebp) { 69 | /* 70 | * | -------- | 71 | * | ... | < ---- ebp_prev 72 | * | -------- | 73 | * | . | 74 | * | . | 75 | * | . | 76 | * | -------- | 77 | * | &$ | < ---- call function `x` ($ is the addr of next instruction) 78 | * | -------- | 79 | * | ebp_prev | < ---- push ebp; mov ebp, esp | <= esp , ebp 80 | * | -------- | 81 | */ 82 | eip = ebp + 1; // (void *)eip == (void *)ebp + 4 83 | kprintf("\t[%p]:\t%s\n", *eip - 5, ksearch_function(*eip - 5, pkelf)); 84 | ebp = (u32 *)*ebp; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /chapter4/lib/kelf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #define ELF32_ST_TYPE(i) ((i)&0xf) 27 | 28 | // Get kernel elf info 29 | KELF kget_kernel_elf_info(const KMultiBoot* mb) 30 | { 31 | KELFSectionHeader* begin = (KELFSectionHeader*)(mb->addr); 32 | KELF elf; 33 | 34 | u32 shstrtab = begin[mb->shndx].addr ; // Section name array 35 | // Loop through all sections 36 | 37 | const KELFSectionHeader* end = &begin[mb->num]; 38 | for (const KELFSectionHeader* sh = begin; sh < end; ++sh) { 39 | const char* section_name = (const char*)(shstrtab + sh->name); 40 | 41 | if (kstrcmp(section_name, ".strtab") == 0) { 42 | elf.strtab = (const char*)(sh->addr); 43 | elf.strtabsz = sh->size; 44 | continue; 45 | } else if (kstrcmp(section_name, ".symtab") == 0) { 46 | elf.symtab = (KELFSymbol*)(sh->addr); 47 | elf.symtabsz = sh->size; 48 | } 49 | } 50 | return elf; 51 | } 52 | 53 | // Return the name of the function whose address range includes 'addr' 54 | const char* ksearch_function(u32 addr, const KELF* elf) 55 | { 56 | if (elf) { 57 | const KELFSymbol* end = &elf->symtab[elf->symtabsz / sizeof(KELFSymbol)]; 58 | 59 | for (const KELFSymbol* symbol = elf->symtab; symbol < end; ++symbol) 60 | if (ELF32_ST_TYPE(symbol->info) != 0x2) 61 | continue; 62 | else if (addr >= symbol->value && addr < symbol->value + symbol->size) 63 | return (const char*)(elf->strtab + symbol->name); 64 | } 65 | return NULL; 66 | } 67 | -------------------------------------------------------------------------------- /chapter4/lib/kstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | // For the simplicity, we do not apply loop unrolling 26 | 27 | inline void* kmemcpy(void* dst, const void* src, u32 n) 28 | { 29 | const u8* s = (u8*)src; 30 | u8* t = (u8*)dst; 31 | while (n--) 32 | *t++ = *s++; 33 | return dst; 34 | } 35 | 36 | inline void* kmemset(void* s, u8 c, u32 n) 37 | { 38 | u8* m = (u8*)s; 39 | while (n--) 40 | *m++ = c; 41 | return s; 42 | } 43 | 44 | inline void* kbzero(void* s, u32 n) 45 | { 46 | kmemset(s, '\0', n); 47 | return s; 48 | } 49 | 50 | inline i32 kstrcmp(const char* s1, const char* s2) 51 | { 52 | i32 a = 0, b = 0; 53 | do { 54 | a = *s1++; 55 | b = *s2++; 56 | } while (a && b && a == b); 57 | return a - b; 58 | } 59 | 60 | inline i32 kstrncmp(const char* s1, const char* s2, u32 n) 61 | { 62 | i32 a = 0, b = 0; 63 | for (; n && a == b; --n) { 64 | a = *s1++; 65 | b = *s2++; 66 | } 67 | return a - b; 68 | } 69 | 70 | char* kstrcat(char* dst, const char* src) 71 | { 72 | char* t = dst; 73 | while (*t++) 74 | ; 75 | --t; 76 | while (*src) 77 | *t++ = *src++; 78 | return dst; 79 | } 80 | 81 | char* kstrncat(char* dst, const char* src, u32 n) 82 | { 83 | char* t = dst; 84 | while (*t++) 85 | ; 86 | --t; 87 | while (n--) 88 | *t++ = *src++; 89 | *t = '\0'; 90 | return dst; 91 | } 92 | 93 | char* kstrcpy(char* dst, const char* src) 94 | { 95 | char* t = dst; 96 | while (*src) 97 | *t++ = *src++; 98 | *t = '\0'; 99 | return dst; 100 | } 101 | char* kstrncpy(char* dst, const char* src, u32 n) 102 | { 103 | char* t = dst; 104 | u32 i; 105 | for (i = 0; i < n && *src; ++i) 106 | *t++ = *src++; 107 | for (; i < n; ++i) 108 | *t++ = '\0'; 109 | return dst; 110 | } 111 | 112 | u32 kstrlen(const char* s) 113 | { 114 | u32 l = 0; 115 | while (*s++) 116 | ++l; 117 | return l; 118 | } 119 | -------------------------------------------------------------------------------- /chapter4/scripts/gdbinit: -------------------------------------------------------------------------------- 1 | shell qemu-system-i386 -s -S -cdrom build/osmanthus.iso & 2 | symbol-file build/osmanthus 3 | set arch i386:intel 4 | target remote :1234 5 | b __start 6 | b kmain 7 | -------------------------------------------------------------------------------- /chapter4/scripts/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "os-name" { 2 | multiboot /boot/kernel-name 3 | } 4 | -------------------------------------------------------------------------------- /chapter4/scripts/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(__start) 2 | SECTIONS 3 | { 4 | PROVIDE( __kernel_begin_addr = . ); 5 | . = 0x100000; 6 | .text : 7 | { 8 | *(.text) 9 | . = ALIGN(4096); 10 | } 11 | .data : 12 | { 13 | *(.data) 14 | *(.rodata) 15 | . = ALIGN(4096); 16 | } 17 | .bss : 18 | { 19 | *(.bss) 20 | . = ALIGN(4096); 21 | } 22 | .stab : 23 | { 24 | *(.stab) 25 | . = ALIGN(4096); 26 | } 27 | .stabstr : 28 | { 29 | *(.stabstr) 30 | . = ALIGN(4096); 31 | } 32 | PROVIDE( __kernel_end_addr = . ); 33 | 34 | /DISCARD/ : { *(.comment) *(.eh_frame) } 35 | } 36 | -------------------------------------------------------------------------------- /chapter5/Makefile: -------------------------------------------------------------------------------- 1 | OS_NAME=Osmanthus 2 | KERNEL_NAME=osmanthus 3 | ISO_DIR=isodir 4 | ISO_NAME=${KERNEL_NAME}.iso 5 | 6 | BUILD=build 7 | SCRIPTS=scripts 8 | LIB=lib 9 | INIT=init 10 | BOOT=boot 11 | DRIVER=driver 12 | KERNEL=kernel 13 | INCLUDE=include 14 | 15 | ASM=yasm 16 | CC=gcc 17 | LD=ld 18 | 19 | CFLAGS=-c -m32 -Wextra -Wall \ 20 | -nostdinc -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ 21 | -Xassembler --32 \ 22 | -I${INCLUDE} 23 | 24 | RFLAGS=-DNDEBUG -O0 25 | DFLAGS=-g -ggdb -gstabs+ 26 | 27 | LDFLAGS = -T $(SCRIPTS)/link.ld -m elf_i386 -nostdlib 28 | ASFLAGS = -f elf 29 | 30 | C_SOURCES=${wildcard ${DRIVER}/*.c ${KERNEL}/*.c ${LIB}/*.c ${INIT}/*.c } 31 | 32 | C_OBJ=$(addprefix ${BUILD}/,${C_SOURCES:.c=_c.o}) 33 | 34 | ASM_SOURCES=${wildcard ${BOOT}/*.asm ${INIT}/*.asm} 35 | 36 | ASM_OBJ=$(addprefix ${BUILD}/,${ASM_SOURCES:.asm=_asm.o}) 37 | 38 | .PHONY: all 39 | all : CFLAGS+=${DFLAGS} 40 | all : ${BUILD} ${KERNEL_NAME} 41 | @cp ${BUILD}/${KERNEL_NAME} ${BUILD}/${ISO_DIR}/boot/ 42 | @sed 's,os-name,${OS_NAME},g; s,kernel-name,${KERNEL_NAME},g' \ 43 | ${SCRIPTS}/grub.cfg > ${BUILD}/${ISO_DIR}/boot/grub/grub.cfg 44 | @echo -e "\033[0;31mMakeing Kernel ISO \033[0m" 45 | @grub-mkrescue -o ${BUILD}/${ISO_NAME} ${BUILD}/${ISO_DIR} > /dev/null 2>&1 46 | 47 | ${BUILD}: 48 | @echo -e "\033[0;34mBuilding 'build' directory\033[0m" 49 | @mkdir -p $@/${ISO_DIR}/boot/grub \ 50 | $@/${BOOT} \ 51 | $@/${DRIVER} \ 52 | $@/${KERNEL} \ 53 | $@/${LIB} \ 54 | $@/${INIT} 55 | 56 | 57 | ${KERNEL_NAME} : ${ASM_OBJ} ${C_OBJ} 58 | @echo -e "\033[0;34mLinking kernel \033[0m" 59 | @${LD} ${LDFLAGS} $^ -o ${BUILD}/$@ 60 | 61 | ${BUILD}/%_asm.o : %.asm 62 | @echo -e "\033[0;32mAssembling module :\t\033[0m" $< 63 | @${ASM} ${ASFLAGS} $< -o $@ 64 | 65 | ${BUILD}/%_c.o : %.c 66 | @echo -e "\033[0;32mCompiling module :\t\033[0m" $< 67 | @${CC} ${CFLAGS} $< -o $@ 68 | 69 | .PHONY: run 70 | run: CFLAGS += ${RFLAGS} 71 | run: 72 | @make CFLAGS="${CFLAGS}" --no-print-directory 73 | @echo -e "\033[0;34mStarting QEMU\033[0m" 74 | @qemu-system-i386 \ 75 | ${BUILD}/${ISO_NAME} > /dev/null 2>&1 76 | 77 | .PHONY: release 78 | release: CFLAGS += ${RFLAGS} 79 | release: 80 | @echo -e "\033[0;34mMaking release version\033[0m" 81 | @make CFLAGS="${CFLAGS}" --no-print-directory 82 | 83 | .PHONY: debug 84 | debug: CFLAGS += ${DFLAGS} 85 | debug: 86 | @echo -e "\033[0;34mMaking debug version\033[0m" 87 | @make CFLAGS="${CFLAGS}" --no-print-directory 88 | 89 | 90 | .PHONY: clean 91 | clean: 92 | @echo -e "\033[0;34mCleaning \033[0m" 93 | @rm -rf build 94 | @echo -e "\033[0;31mFinished\033[0m" 95 | -------------------------------------------------------------------------------- /chapter5/boot/boot.asm: -------------------------------------------------------------------------------- 1 | [bits 32] ;; 以下是32位代码 2 | MULTIBOOT_HEADER_MAGIC equ 0x1badb002 ;; 魔数 3 | MULTIBOOT_PAGE_ALIGN equ 1 << 0 ;; 所有引导模块页(4KB)对齐 4 | MULTIBOOT_MEMORY_INFO equ 1 << 1 ;; 将内存信息写到MultiBoot结构体中 5 | 6 | ;; 将上两行属性结合起来 7 | MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO 8 | 9 | ;; 校验码 10 | MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS) 11 | 12 | ;; 内核临时栈大小 13 | KERNEL_STACK_SIZE equ 0x400 14 | 15 | ;; 内核虚拟起始地址 我们先写在这里 暂时不用管他们的作用 16 | ;; KERNEL_VM_OFFSET equ 0xC0000000 17 | 18 | 19 | ;; section .init.text 这个注释以后可以去掉, 我们暂时用.text去代替 20 | 21 | section .text 22 | 23 | dd MULTIBOOT_HEADER_MAGIC ;; 24 | dd MULTIBOOT_HEADER_FLAGS ;; 将定义好的信息写进文件头 25 | dd MULTIBOOT_CHECKSUM ;; 26 | 27 | [global __start:function] ;; 内核入口 :function是yasm的修饰符 28 | [extern kmain] ;; 内核主函数 29 | 30 | __start: 31 | cli 32 | 33 | mov esp, __kernel_stack_top ;; 设置好内核的临时栈顶 34 | and esp, 0xfffffff0 ;; 按16字节对齐 35 | mov ebp , 0x0 ;; 作为以后backtrace的终止条件 36 | 37 | push ebx ;; Grub将内存信息写到了一块内存中, 将内存的首地址放在了ebx 我们作为参数传给内核主函数 38 | call kmain ;; 调用内核主函数 这里我们假定主函数永远不会返回 如果有强迫症 可以将下边注释去掉 39 | ;; 但是正确性在启用分页之后不保证. 40 | .end 41 | 42 | size __start __start.end - __start ;; 指定函数__start的大小 43 | 44 | ;; section .init.data 同上.init.text 45 | section .data 46 | ; Temporary kernel stack 47 | __kernel_stack_base: 48 | times KERNEL_STACK_SIZE db 0 ; 1KB 内核临时栈空间 49 | __kernel_stack_top: 50 | -------------------------------------------------------------------------------- /chapter5/driver/kport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | void kout(u16 port, u32 data, KDataSize size) 26 | { 27 | if (size == KBYTE) 28 | __asm__ volatile("outb %%al,%%dx" ::"d"(port), "a"(data)); 29 | else if (size == KWORD) 30 | __asm__ volatile("outw %%ax,%%dx" ::"d"(port), "a"(data)); 31 | else if (size == KDWORD) 32 | __asm__ volatile("outl %%eax,%%dx" ::"d"(port), "a"(data)); 33 | } 34 | 35 | u32 kin(u16 port, KDataSize size) 36 | { 37 | u8 db = 0; 38 | u16 dw = 0; 39 | u32 dl = 0; 40 | if (size == KBYTE) { 41 | __asm__ volatile("inb %%dx, %%al" 42 | : "=a"(db) 43 | : "d"(port)); 44 | return db; 45 | } else if (size == KWORD) { 46 | __asm__ volatile("inw %%dx, %%ax" 47 | : "=a"(dw) 48 | : "d"(port)); 49 | return dw; 50 | } else if (size == KDWORD) { 51 | __asm__ volatile("inl %%dx, %%eax" 52 | : "=a"(dl) 53 | : "d"(port)); 54 | return dl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /chapter5/include/karg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KARG_H_ 24 | #define _KARG_H_ 25 | 26 | // Various arguments macro for i386 27 | 28 | #include 29 | 30 | typedef char* kva_list; 31 | 32 | #define kva_start(ap, last) \ 33 | (ap = (kva_list)(((kva_list)&last) + ((sizeof(last) + 3) & ~3))) 34 | 35 | #define kva_arg(ap, type) \ 36 | (*(type*)(ap += ((sizeof(type) + 3) & ~3), \ 37 | ap - ((sizeof(type) + 3) & ~3))) 38 | 39 | #define kva_copy(dst, src) (dst) = (src) 40 | 41 | #define kva_end(ap) (ap = (kva_list)NULL) 42 | 43 | #endif /* ifndef _KARG_H_ */ 44 | -------------------------------------------------------------------------------- /chapter5/include/kdebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KDEBUG_H_ 24 | #define _KDEBUG_H_ 25 | 26 | #ifdef NDEBUG 27 | #define kassert(cond) (void)0 28 | #else 29 | void __kassert(const char* file, int line, const char* func, 30 | const char* expr); 31 | 32 | #define kassert(cond) \ 33 | do { \ 34 | if (!(cond)) { \ 35 | __kassert(__FILE__, __LINE__, __func__, #cond); \ 36 | } \ 37 | } while (0) 38 | #endif 39 | 40 | // Print call stack trace 41 | 42 | void kstack_trace(); 43 | 44 | // Fatal error 45 | void kpanic(const char* msg); 46 | 47 | #endif /* ifndef _KDEBUG_H_ */ 48 | -------------------------------------------------------------------------------- /chapter5/include/kelf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KELF_H_ 24 | #define _KELF_H_ 25 | 26 | #include 27 | #include 28 | 29 | // ELF section header 30 | typedef struct _KELFSectionHeader { 31 | u32 name; 32 | u32 type; 33 | u32 flags; 34 | u32 addr; 35 | u32 offset; 36 | u32 size; 37 | u32 link; 38 | u32 info; 39 | u32 addralign; 40 | u32 entsize; 41 | } __attribute__((packed)) KELFSectionHeader; 42 | 43 | // ELF Symbol 44 | typedef struct _KELFSymbol { 45 | u32 name; 46 | u32 value; 47 | u32 size; 48 | u8 info; 49 | u8 other; 50 | u16 shndx; 51 | } __attribute__((packed)) KELFSymbol; 52 | 53 | // ELF info 54 | typedef struct _KELF { 55 | KELFSymbol* symtab; 56 | u32 symtabsz; 57 | const char* strtab; 58 | u32 strtabsz; 59 | } KELF; 60 | 61 | // Get kernel elf info 62 | KELF kget_kernel_elf_info(const KMultiBoot* mb); 63 | 64 | // Return symbol whose address range includes 'addr' 65 | const char* ksearch_function(u32 addr, const KELF* elf); 66 | 67 | #endif /* ifndef _KELF_H_ */ 68 | -------------------------------------------------------------------------------- /chapter5/include/kgdt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KGDT_H_ 24 | #define _KGDT_H_ 25 | #include 26 | 27 | #define GDT_ENTRY_CNT 5 28 | #define GDT_ENTRY_SIZE 8 29 | 30 | #define NULL_SEG_INDEX 0 31 | #define CODE_SEG_INDEX 1 32 | #define DATA_SEG_INDEX 2 33 | #define USER_CODE_SEG_INDEX 3 34 | #define USER_DATA_SEG_INDEX 4 35 | 36 | #define GDT_CODE_SELECTOR (GDT_ENTRY_SIZE * CODE_SEG_INDEX) 37 | #define GDT_DATA_SELECTOR (GDT_ENTRY_SIZE * DATA_SEG_INDEX) 38 | #define GDT_USER_CODE_SELECTOR (GDT_ENTRY_SIZE * USER_CODE_SEG_INDEX) 39 | #define GDT_USER_DATA_SELECTOR (GDT_ENTRY_SIZE * USER_DATA_SEG_INDEX) 40 | 41 | typedef struct _KSegmentDescritor { 42 | u16 limit_low; 43 | u16 base_low; 44 | u8 base_mid; 45 | u8 access; 46 | u8 granularity; 47 | u8 base_high; 48 | } __attribute__((packed)) KSegmentDescritor; 49 | 50 | typedef struct _KGDTPtr { 51 | u16 limit; // GDT actual size - 1 52 | u32 addr; // GDT begin addr 53 | } __attribute__((packed)) KGDTPtr; 54 | 55 | KGDTPtr kinit_gdt(); 56 | void kload_gdt(const KGDTPtr* gdt_ptr); 57 | 58 | #endif /* ifndef _KGDT_H_ */ 59 | -------------------------------------------------------------------------------- /chapter5/include/kio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights 5 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 6 | * copies of the Software, and to permit persons to whom the Software is 7 | * furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in 10 | * all copies or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | #ifndef _KIO_H_ 22 | #define _KIO_H_ 23 | 24 | #include 25 | #include 26 | 27 | // Kernel level I/O functions 28 | 29 | i32 kvsprintf(char *s, const char *fmt, kva_list args); 30 | i32 kprintf(const char *fmt, ...); 31 | i32 kcprintf(VgaTextAtrr bg, VgaTextAtrr fg, const char *fmt, 32 | ...); // With color 33 | i32 kputchar(char ch); 34 | i32 kcputchar(char ch, VgaTextAtrr bg, VgaTextAtrr fg); 35 | i32 kputs(const char *str); 36 | i32 kcputs(VgaTextAtrr bg, VgaTextAtrr fg, const char *str); 37 | 38 | #endif /* ifndef _KIO_H_ */ 39 | -------------------------------------------------------------------------------- /chapter5/include/kmultiboot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KMULTIBOOT_H_ 24 | #define _KMULTIBOOT_H_ 25 | 26 | #include 27 | 28 | typedef struct _KMultiBoot { 29 | u32 flags; 30 | u32 mem_lower; 31 | u32 mem_upper; 32 | 33 | u32 boot_device; 34 | u32 cmdline; 35 | u32 mods_count; 36 | u32 mods_addr; 37 | 38 | u32 num; 39 | u32 size; 40 | u32 addr; 41 | u32 shndx; 42 | 43 | // Memory info 44 | u32 mmap_length; 45 | u32 mmap_addr; 46 | 47 | u32 drives_length; 48 | u32 drives_addr; 49 | u32 config_table; 50 | u32 boot_loader_name; 51 | u32 apm_table; 52 | u32 vbe_control_info; 53 | u32 vbe_mode_info; 54 | u32 vbe_mode; 55 | u32 vbe_interface_seg; 56 | u32 vbe_interface_off; 57 | u32 vbe_interface_len; 58 | } __attribute__((packed)) KMultiBoot; 59 | 60 | typedef struct _KMMapEntry { 61 | u32 size; 62 | u32 base_addr_low; 63 | u32 base_addr_high; 64 | u32 length_low; 65 | u32 length_high; 66 | u32 type; 67 | } __attribute__((packed)) KMMapEntry; 68 | 69 | #define KERNEL_BOOT_INFO (__kernel_multiboot_info) 70 | const KMultiBoot* __kernel_multiboot_info; 71 | 72 | #endif /* ifndef _KMULTIBOOT_H_ */ 73 | -------------------------------------------------------------------------------- /chapter5/include/kport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KPORTS_H_ 24 | #define _KPORTS_H_ 25 | 26 | #include 27 | 28 | /* 29 | * Write 'data' to 'port' while specifying the data size: 'size' 30 | * */ 31 | void kout(u16 port, u32 data, KDataSize size); 32 | 33 | /* 34 | * Read 'size' byte(s) from 'port' 35 | * */ 36 | u32 kin(u16 port, KDataSize size); 37 | 38 | #endif /* ifndef _KPORTS_H_ */ 39 | -------------------------------------------------------------------------------- /chapter5/include/kstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KSTRING_H_ 24 | #define _KSTRING_H_ 25 | 26 | #include 27 | 28 | void* kmemcpy(void* dst, const void* src, u32 n); 29 | 30 | void* kmemset(void* s, u8 c, u32 n); 31 | void* kbzero(void* s, u32 n); 32 | 33 | i32 kstrcmp(const char* s1, const char* s2); 34 | i32 kstrncmp(const char* s1, const char* s2, u32 n); 35 | 36 | char* kstrcpy(char* dst, const char* src); 37 | char* kstrncpy(char* dst, const char* src, u32 n); 38 | 39 | char* kstrcat(char* dest, const char* src); 40 | char* kstrncat(char* dest, const char* src, u32 n); 41 | 42 | u32 kstrlen(const char* s); 43 | 44 | #endif /* ifndef _KSTRING_H_ */ 45 | -------------------------------------------------------------------------------- /chapter5/include/ktypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KTYPES_H_ 25 | #define _KTYPES_H_ 26 | 27 | #ifndef NULL 28 | #define NULL (void *)0 29 | #endif 30 | 31 | #ifndef EOF 32 | #define EOF -1 33 | #endif /* ifndef EOF */ 34 | 35 | /* Some type alias in 32-bit machine */ 36 | typedef unsigned int u32; 37 | typedef int i32; 38 | typedef unsigned short u16; 39 | typedef short i16; 40 | typedef unsigned char u8; 41 | typedef char i8; 42 | 43 | typedef enum _KDataSize { 44 | KBYTE = sizeof(u8), 45 | KWORD = sizeof(u16), 46 | KDWORD = sizeof(u32) 47 | } KDataSize; 48 | 49 | typedef enum _KMemUnit { B, KB, MB, GB } KMemUnit; 50 | 51 | #endif /* ifndef _KTYPES_H_ */ 52 | -------------------------------------------------------------------------------- /chapter5/include/kvga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KVGA_H_ 24 | #define _KVGA_H_ 25 | 26 | #include 27 | 28 | #define TAB_WIDTH 4 29 | 30 | typedef enum _VgaTextAtrr { 31 | VGA_BLACK = 0, 32 | VGA_BLUE, 33 | VGA_GREEN, 34 | VGA_CYAN, 35 | VGA_RED, 36 | VGA_MAGENTA, 37 | VGA_BROWN, 38 | VGA_LIGHT_GREY, 39 | VGA_DARK_GREY, 40 | VGA_LIGHT_BLUE, 41 | VGA_LIGHT_GREEN, 42 | VGA_LIGHT_CYAN, 43 | VGA_LIGHT_RED, 44 | VGA_LIGHT_MAGENTA, 45 | VGA_LIGHT_BROWN, // Yellow 46 | VGA_WHITE 47 | } VgaTextAtrr; 48 | 49 | i32 kvga_cputc(char ch, VgaTextAtrr bg, VgaTextAtrr fg); // With color 50 | 51 | i32 kvga_putc(char ch); 52 | 53 | i32 kvga_cputs(const char* str, VgaTextAtrr bg, VgaTextAtrr fg); // With color 54 | 55 | i32 kvga_puts(const char* str); 56 | 57 | void kvga_scroll(); 58 | 59 | void kvga_clear(); 60 | 61 | #endif /* ifndef _kvga_H_ */ 62 | -------------------------------------------------------------------------------- /chapter5/init/kgdt.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2018 Liming,Deng 2 | ;Author: Liming Deng 3 | ; 4 | ;Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | ;this software and associated documentation files (the "Software"), to deal in 6 | ;the Software without restriction, including without limitation the rights to 7 | ;use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | ;the Software, and to permit persons to whom the Software is furnished to do so, 9 | ;subject to the following conditions: 10 | ; 11 | ;The above copyright notice and this permission notice shall be included in all 12 | ;copies or substantial portions of the Software. 13 | ; 14 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | ;FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | ;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | ;IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | ;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | 22 | [global kload_gdt:function] 23 | kload_gdt: 24 | mov eax, [esp + 4] 25 | lgdt [eax] 26 | 27 | mov ax, 0x10 28 | mov ds, ax 29 | mov es, ax 30 | mov fs, ax 31 | mov gs, ax 32 | mov ss, ax 33 | 34 | jmp 0x08:__long_jmp 35 | 36 | __long_jmp: 37 | ret 38 | .end 39 | size kload_gdt __long_jmp.end - kload_gdt 40 | -------------------------------------------------------------------------------- /chapter5/init/kgdt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | 28 | static KSegmentDescritor gdt[GDT_ENTRY_CNT]; 29 | 30 | static void set_segment_descriptor( KSegmentDescritor *sd, u32 base, u32 limit, 31 | u8 access, u8 granularity ); 32 | 33 | void set_segment_descriptor( KSegmentDescritor *sd, u32 base, u32 limit, 34 | u8 access, u8 granularity ) 35 | { 36 | sd->limit_low = limit & 0xffff; 37 | sd->base_low = base & 0xffff; 38 | sd->base_mid = ( base >> 16 ) & 0xff; 39 | sd->access = access; 40 | sd->granularity = ( granularity & 0xf0 ) | ( ( limit >> 16 ) & 0xf ); 41 | sd->base_high = base >> 24; 42 | } 43 | 44 | KGDTPtr kinit_gdt() 45 | { 46 | KGDTPtr gdt_ptr; 47 | gdt_ptr.addr = (u32)gdt; 48 | gdt_ptr.limit = sizeof( gdt ) - 1; 49 | 50 | // Null descritor 51 | set_segment_descriptor( &gdt[NULL_SEG_INDEX], 0x00000000, 0x00000000, 0x00, 52 | 0x00 ); 53 | 54 | // Code segment descritor 55 | set_segment_descriptor( &gdt[CODE_SEG_INDEX], 0x00000000, 0xffffffff, 0x9a, 56 | 0xcf ); 57 | 58 | // Data segment descritor 59 | set_segment_descriptor( &gdt[DATA_SEG_INDEX], 0x00000000, 0xffffffff, 0x92, 60 | 0xcf ); 61 | 62 | // User code segment descritor 63 | set_segment_descriptor( &gdt[USER_CODE_SEG_INDEX], 0x00000000, 0xffffffff, 64 | 0xfa, 0xcf ); 65 | 66 | // User data segment descritor 67 | set_segment_descriptor( &gdt[USER_DATA_SEG_INDEX], 0x00000000, 0xffffffff, 68 | 0xf2, 0xcf ); 69 | 70 | return gdt_ptr; 71 | } 72 | -------------------------------------------------------------------------------- /chapter5/kernel/kmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void hlt() { 8 | while (1) 9 | __asm__ volatile("hlt"); 10 | } 11 | 12 | void kmain(KMultiBoot *mb) { 13 | KERNEL_BOOT_INFO = mb; 14 | 15 | KGDTPtr gdt_ptr = kinit_gdt(); 16 | kload_gdt(&gdt_ptr); 17 | 18 | kprintf("hello world?\n"); 19 | 20 | hlt(); 21 | } 22 | -------------------------------------------------------------------------------- /chapter5/lib/kdebug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | static KELF kernel_elf; 30 | static const KELF *pkelf = NULL; 31 | 32 | // Define in boot/boot.asm 33 | 34 | static void env_init(); 35 | 36 | void env_init() { 37 | if (pkelf == NULL) { 38 | kernel_elf = kget_kernel_elf_info(KERNEL_BOOT_INFO); 39 | pkelf = &kernel_elf; 40 | } 41 | } 42 | 43 | void kpanic(const char *msg) { 44 | kprintf("****Fatal error eccured****\n" 45 | "****Kernel in panic****\n"); 46 | if (msg) 47 | kprintf("%s\n", msg); 48 | kstack_trace(); 49 | while (1) 50 | ; 51 | } 52 | 53 | void __kassert(const char *file, int line, const char *func, const char *expr) { 54 | kcprintf(VGA_BLACK, VGA_LIGHT_BROWN, 55 | "In file %s: %d function %s asserts '%s' failed\n", file, line, func, 56 | expr); 57 | kpanic(NULL); 58 | } 59 | 60 | void kstack_trace() { 61 | env_init(); 62 | u32 *ebp, *eip; 63 | 64 | // Get %ebp 65 | __asm__ volatile("mov %%ebp,%0" : "=r"(ebp)); 66 | 67 | // %ebp was initiated in boot/boot.asm with 0x0 68 | while (ebp) { 69 | /* 70 | * | -------- | 71 | * | ... | < ---- ebp_prev 72 | * | -------- | 73 | * | . | 74 | * | . | 75 | * | . | 76 | * | -------- | 77 | * | &$ | < ---- call function `x` ($ is the addr of next instruction) 78 | * | -------- | 79 | * | ebp_prev | < ---- push ebp; mov ebp, esp | <= esp , ebp 80 | * | -------- | 81 | */ 82 | eip = ebp + 1; // (void *)eip == (void *)ebp + 4 83 | kprintf("\t[%p]:\t%s\n", *eip - 5, ksearch_function(*eip - 5, pkelf)); 84 | ebp = (u32 *)*ebp; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /chapter5/lib/kelf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #define ELF32_ST_TYPE(i) ((i)&0xf) 27 | 28 | // Get kernel elf info 29 | KELF kget_kernel_elf_info(const KMultiBoot* mb) 30 | { 31 | KELFSectionHeader* begin = (KELFSectionHeader*)(mb->addr); 32 | KELF elf; 33 | 34 | u32 shstrtab = begin[mb->shndx].addr ; // Section name array 35 | // Loop through all sections 36 | 37 | const KELFSectionHeader* end = &begin[mb->num]; 38 | for (const KELFSectionHeader* sh = begin; sh < end; ++sh) { 39 | const char* section_name = (const char*)(shstrtab + sh->name); 40 | 41 | if (kstrcmp(section_name, ".strtab") == 0) { 42 | elf.strtab = (const char*)(sh->addr); 43 | elf.strtabsz = sh->size; 44 | continue; 45 | } else if (kstrcmp(section_name, ".symtab") == 0) { 46 | elf.symtab = (KELFSymbol*)(sh->addr); 47 | elf.symtabsz = sh->size; 48 | } 49 | } 50 | return elf; 51 | } 52 | 53 | // Return the name of the function whose address range includes 'addr' 54 | const char* ksearch_function(u32 addr, const KELF* elf) 55 | { 56 | if (elf) { 57 | const KELFSymbol* end = &elf->symtab[elf->symtabsz / sizeof(KELFSymbol)]; 58 | 59 | for (const KELFSymbol* symbol = elf->symtab; symbol < end; ++symbol) 60 | if (ELF32_ST_TYPE(symbol->info) != 0x2) 61 | continue; 62 | else if (addr >= symbol->value && addr < symbol->value + symbol->size) 63 | return (const char*)(elf->strtab + symbol->name); 64 | } 65 | return NULL; 66 | } 67 | -------------------------------------------------------------------------------- /chapter5/lib/kstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | // For the simplicity, we do not apply loop unrolling 26 | 27 | inline void* kmemcpy(void* dst, const void* src, u32 n) 28 | { 29 | const u8* s = (u8*)src; 30 | u8* t = (u8*)dst; 31 | while (n--) 32 | *t++ = *s++; 33 | return dst; 34 | } 35 | 36 | inline void* kmemset(void* s, u8 c, u32 n) 37 | { 38 | u8* m = (u8*)s; 39 | while (n--) 40 | *m++ = c; 41 | return s; 42 | } 43 | 44 | inline void* kbzero(void* s, u32 n) 45 | { 46 | kmemset(s, '\0', n); 47 | return s; 48 | } 49 | 50 | inline i32 kstrcmp(const char* s1, const char* s2) 51 | { 52 | i32 a = 0, b = 0; 53 | do { 54 | a = *s1++; 55 | b = *s2++; 56 | } while (a && b && a == b); 57 | return a - b; 58 | } 59 | 60 | inline i32 kstrncmp(const char* s1, const char* s2, u32 n) 61 | { 62 | i32 a = 0, b = 0; 63 | for (; n && a == b; --n) { 64 | a = *s1++; 65 | b = *s2++; 66 | } 67 | return a - b; 68 | } 69 | 70 | char* kstrcat(char* dst, const char* src) 71 | { 72 | char* t = dst; 73 | while (*t++) 74 | ; 75 | --t; 76 | while (*src) 77 | *t++ = *src++; 78 | return dst; 79 | } 80 | 81 | char* kstrncat(char* dst, const char* src, u32 n) 82 | { 83 | char* t = dst; 84 | while (*t++) 85 | ; 86 | --t; 87 | while (n--) 88 | *t++ = *src++; 89 | *t = '\0'; 90 | return dst; 91 | } 92 | 93 | char* kstrcpy(char* dst, const char* src) 94 | { 95 | char* t = dst; 96 | while (*src) 97 | *t++ = *src++; 98 | *t = '\0'; 99 | return dst; 100 | } 101 | char* kstrncpy(char* dst, const char* src, u32 n) 102 | { 103 | char* t = dst; 104 | u32 i; 105 | for (i = 0; i < n && *src; ++i) 106 | *t++ = *src++; 107 | for (; i < n; ++i) 108 | *t++ = '\0'; 109 | return dst; 110 | } 111 | 112 | u32 kstrlen(const char* s) 113 | { 114 | u32 l = 0; 115 | while (*s++) 116 | ++l; 117 | return l; 118 | } 119 | -------------------------------------------------------------------------------- /chapter5/scripts/gdbinit: -------------------------------------------------------------------------------- 1 | shell qemu-system-i386 -s -S -cdrom build/osmanthus.iso & 2 | symbol-file build/osmanthus 3 | set arch i386:intel 4 | target remote :1234 5 | b __start 6 | b kmain 7 | -------------------------------------------------------------------------------- /chapter5/scripts/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "os-name" { 2 | multiboot /boot/kernel-name 3 | } 4 | -------------------------------------------------------------------------------- /chapter5/scripts/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(__start) 2 | SECTIONS 3 | { 4 | PROVIDE( __kernel_begin_addr = . ); 5 | . = 0x100000; 6 | .text : 7 | { 8 | *(.text) 9 | . = ALIGN(4096); 10 | } 11 | .data : 12 | { 13 | *(.data) 14 | *(.rodata) 15 | . = ALIGN(4096); 16 | } 17 | .bss : 18 | { 19 | *(.bss) 20 | . = ALIGN(4096); 21 | } 22 | .stab : 23 | { 24 | *(.stab) 25 | . = ALIGN(4096); 26 | } 27 | .stabstr : 28 | { 29 | *(.stabstr) 30 | . = ALIGN(4096); 31 | } 32 | PROVIDE( __kernel_end_addr = . ); 33 | 34 | /DISCARD/ : { *(.comment) *(.eh_frame) } 35 | } 36 | -------------------------------------------------------------------------------- /chapter6/Makefile: -------------------------------------------------------------------------------- 1 | OS_NAME=Osmanthus 2 | KERNEL_NAME=osmanthus 3 | ISO_DIR=isodir 4 | ISO_NAME=${KERNEL_NAME}.iso 5 | 6 | BUILD=build 7 | SCRIPTS=scripts 8 | LIB=lib 9 | INIT=init 10 | BOOT=boot 11 | DRIVER=driver 12 | KERNEL=kernel 13 | INCLUDE=include 14 | 15 | ASM=yasm 16 | CC=gcc 17 | LD=ld 18 | 19 | CFLAGS=-c -m32 -Wextra -Wall \ 20 | -nostdinc -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ 21 | -Xassembler --32 \ 22 | -I${INCLUDE} 23 | 24 | RFLAGS=-DNDEBUG -O0 25 | DFLAGS=-g -ggdb -gstabs+ 26 | 27 | LDFLAGS = -T $(SCRIPTS)/link.ld -m elf_i386 -nostdlib 28 | ASFLAGS = -f elf 29 | 30 | C_SOURCES=${wildcard ${DRIVER}/*.c ${KERNEL}/*.c ${LIB}/*.c ${INIT}/*.c } 31 | 32 | C_OBJ=$(addprefix ${BUILD}/,${C_SOURCES:.c=_c.o}) 33 | 34 | ASM_SOURCES=${wildcard ${BOOT}/*.asm ${INIT}/*.asm} 35 | 36 | ASM_OBJ=$(addprefix ${BUILD}/,${ASM_SOURCES:.asm=_asm.o}) 37 | 38 | .PHONY: all 39 | all : CFLAGS+=${DFLAGS} 40 | all : ${BUILD} ${KERNEL_NAME} 41 | @cp ${BUILD}/${KERNEL_NAME} ${BUILD}/${ISO_DIR}/boot/ 42 | @sed 's,os-name,${OS_NAME},g; s,kernel-name,${KERNEL_NAME},g' \ 43 | ${SCRIPTS}/grub.cfg > ${BUILD}/${ISO_DIR}/boot/grub/grub.cfg 44 | @echo -e "\033[0;31mMakeing Kernel ISO \033[0m" 45 | @grub-mkrescue -o ${BUILD}/${ISO_NAME} ${BUILD}/${ISO_DIR} > /dev/null 2>&1 46 | 47 | ${BUILD}: 48 | @echo -e "\033[0;34mBuilding 'build' directory\033[0m" 49 | @mkdir -p $@/${ISO_DIR}/boot/grub \ 50 | $@/${BOOT} \ 51 | $@/${DRIVER} \ 52 | $@/${KERNEL} \ 53 | $@/${LIB} \ 54 | $@/${INIT} 55 | 56 | 57 | ${KERNEL_NAME} : ${ASM_OBJ} ${C_OBJ} 58 | @echo -e "\033[0;34mLinking kernel \033[0m" 59 | @${LD} ${LDFLAGS} $^ -o ${BUILD}/$@ 60 | 61 | ${BUILD}/%_asm.o : %.asm 62 | @echo -e "\033[0;32mAssembling module :\t\033[0m" $< 63 | @${ASM} ${ASFLAGS} $< -o $@ 64 | 65 | ${BUILD}/%_c.o : %.c 66 | @echo -e "\033[0;32mCompiling module :\t\033[0m" $< 67 | @${CC} ${CFLAGS} $< -o $@ 68 | 69 | .PHONY: run 70 | run: CFLAGS += ${RFLAGS} 71 | run: 72 | @make CFLAGS="${CFLAGS}" --no-print-directory 73 | @echo -e "\033[0;34mStarting QEMU\033[0m" 74 | @qemu-system-i386 \ 75 | ${BUILD}/${ISO_NAME} > /dev/null 2>&1 76 | 77 | .PHONY: release 78 | release: CFLAGS += ${RFLAGS} 79 | release: 80 | @echo -e "\033[0;34mMaking release version\033[0m" 81 | @make CFLAGS="${CFLAGS}" --no-print-directory 82 | 83 | .PHONY: debug 84 | debug: CFLAGS += ${DFLAGS} 85 | debug: 86 | @echo -e "\033[0;34mMaking debug version\033[0m" 87 | @make CFLAGS="${CFLAGS}" --no-print-directory 88 | 89 | 90 | .PHONY: clean 91 | clean: 92 | @echo -e "\033[0;34mCleaning \033[0m" 93 | @rm -rf build 94 | @echo -e "\033[0;31mFinished\033[0m" 95 | -------------------------------------------------------------------------------- /chapter6/boot/boot.asm: -------------------------------------------------------------------------------- 1 | [bits 32] ;; 以下是32位代码 2 | MULTIBOOT_HEADER_MAGIC equ 0x1badb002 ;; 魔数 3 | MULTIBOOT_PAGE_ALIGN equ 1 << 0 ;; 所有引导模块页(4KB)对齐 4 | MULTIBOOT_MEMORY_INFO equ 1 << 1 ;; 将内存信息写到MultiBoot结构体中 5 | 6 | ;; 将上两行属性结合起来 7 | MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO 8 | 9 | ;; 校验码 10 | MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS) 11 | 12 | ;; 内核临时栈大小 13 | KERNEL_STACK_SIZE equ 0x400 14 | 15 | ;; 内核虚拟起始地址 我们先写在这里 暂时不用管他们的作用 16 | ;; KERNEL_VM_OFFSET equ 0xC0000000 17 | 18 | 19 | ;; section .init.text 这个注释以后可以去掉, 我们暂时用.text去代替 20 | 21 | section .text 22 | 23 | dd MULTIBOOT_HEADER_MAGIC ;; 24 | dd MULTIBOOT_HEADER_FLAGS ;; 将定义好的信息写进文件头 25 | dd MULTIBOOT_CHECKSUM ;; 26 | 27 | [global __start:function] ;; 内核入口 :function是yasm的修饰符 28 | [extern kmain] ;; 内核主函数 29 | 30 | __start: 31 | cli 32 | 33 | mov esp, __kernel_stack_top ;; 设置好内核的临时栈顶 34 | and esp, 0xfffffff0 ;; 按16字节对齐 35 | mov ebp , 0x0 ;; 作为以后backtrace的终止条件 36 | 37 | push ebx ;; Grub将内存信息写到了一块内存中, 将内存的首地址放在了ebx 我们作为参数传给内核主函数 38 | call kmain ;; 调用内核主函数 这里我们假定主函数永远不会返回 如果有强迫症 可以将下边注释去掉 39 | ;; 但是正确性在启用分页之后不保证. 40 | .end 41 | 42 | size __start __start.end - __start ;; 指定函数__start的大小 43 | 44 | ;; section .init.data 同上.init.text 45 | section .data 46 | ; Temporary kernel stack 47 | __kernel_stack_base: 48 | times KERNEL_STACK_SIZE db 0 ; 1KB 内核临时栈空间 49 | __kernel_stack_top: 50 | -------------------------------------------------------------------------------- /chapter6/driver/kport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | void kout(u16 port, u32 data, KDataSize size) 26 | { 27 | if (size == KBYTE) 28 | __asm__ volatile("outb %%al,%%dx" ::"d"(port), "a"(data)); 29 | else if (size == KWORD) 30 | __asm__ volatile("outw %%ax,%%dx" ::"d"(port), "a"(data)); 31 | else if (size == KDWORD) 32 | __asm__ volatile("outl %%eax,%%dx" ::"d"(port), "a"(data)); 33 | } 34 | 35 | u32 kin(u16 port, KDataSize size) 36 | { 37 | u8 db = 0; 38 | u16 dw = 0; 39 | u32 dl = 0; 40 | if (size == KBYTE) { 41 | __asm__ volatile("inb %%dx, %%al" 42 | : "=a"(db) 43 | : "d"(port)); 44 | return db; 45 | } else if (size == KWORD) { 46 | __asm__ volatile("inw %%dx, %%ax" 47 | : "=a"(dw) 48 | : "d"(port)); 49 | return dw; 50 | } else if (size == KDWORD) { 51 | __asm__ volatile("inl %%dx, %%eax" 52 | : "=a"(dl) 53 | : "d"(port)); 54 | return dl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /chapter6/include/karg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KARG_H_ 24 | #define _KARG_H_ 25 | 26 | // Various arguments macro for i386 27 | 28 | #include 29 | 30 | typedef char* kva_list; 31 | 32 | #define kva_start(ap, last) \ 33 | (ap = (kva_list)(((kva_list)&last) + ((sizeof(last) + 3) & ~3))) 34 | 35 | #define kva_arg(ap, type) \ 36 | (*(type*)(ap += ((sizeof(type) + 3) & ~3), \ 37 | ap - ((sizeof(type) + 3) & ~3))) 38 | 39 | #define kva_copy(dst, src) (dst) = (src) 40 | 41 | #define kva_end(ap) (ap = (kva_list)NULL) 42 | 43 | #endif /* ifndef _KARG_H_ */ 44 | -------------------------------------------------------------------------------- /chapter6/include/kdebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KDEBUG_H_ 24 | #define _KDEBUG_H_ 25 | 26 | #ifdef NDEBUG 27 | #define kassert(cond) (void)0 28 | #else 29 | void __kassert(const char* file, int line, const char* func, 30 | const char* expr); 31 | 32 | #define kassert(cond) \ 33 | do { \ 34 | if (!(cond)) { \ 35 | __kassert(__FILE__, __LINE__, __func__, #cond); \ 36 | } \ 37 | } while (0) 38 | #endif 39 | 40 | // Print call stack trace 41 | 42 | void kstack_trace(); 43 | 44 | // Fatal error 45 | void kpanic(const char* msg); 46 | 47 | #endif /* ifndef _KDEBUG_H_ */ 48 | -------------------------------------------------------------------------------- /chapter6/include/kelf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KELF_H_ 24 | #define _KELF_H_ 25 | 26 | #include 27 | #include 28 | 29 | // ELF section header 30 | typedef struct _KELFSectionHeader { 31 | u32 name; 32 | u32 type; 33 | u32 flags; 34 | u32 addr; 35 | u32 offset; 36 | u32 size; 37 | u32 link; 38 | u32 info; 39 | u32 addralign; 40 | u32 entsize; 41 | } __attribute__((packed)) KELFSectionHeader; 42 | 43 | // ELF Symbol 44 | typedef struct _KELFSymbol { 45 | u32 name; 46 | u32 value; 47 | u32 size; 48 | u8 info; 49 | u8 other; 50 | u16 shndx; 51 | } __attribute__((packed)) KELFSymbol; 52 | 53 | // ELF info 54 | typedef struct _KELF { 55 | KELFSymbol* symtab; 56 | u32 symtabsz; 57 | const char* strtab; 58 | u32 strtabsz; 59 | } KELF; 60 | 61 | // Get kernel elf info 62 | KELF kget_kernel_elf_info(const KMultiBoot* mb); 63 | 64 | // Return symbol whose address range includes 'addr' 65 | const char* ksearch_function(u32 addr, const KELF* elf); 66 | 67 | #endif /* ifndef _KELF_H_ */ 68 | -------------------------------------------------------------------------------- /chapter6/include/kgdt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KGDT_H_ 24 | #define _KGDT_H_ 25 | #include 26 | 27 | #define GDT_ENTRY_CNT 5 28 | #define GDT_ENTRY_SIZE 8 29 | 30 | #define NULL_SEG_INDEX 0 31 | #define CODE_SEG_INDEX 1 32 | #define DATA_SEG_INDEX 2 33 | #define USER_CODE_SEG_INDEX 3 34 | #define USER_DATA_SEG_INDEX 4 35 | 36 | #define GDT_CODE_SELECTOR (GDT_ENTRY_SIZE * CODE_SEG_INDEX) 37 | #define GDT_DATA_SELECTOR (GDT_ENTRY_SIZE * DATA_SEG_INDEX) 38 | #define GDT_USER_CODE_SELECTOR (GDT_ENTRY_SIZE * USER_CODE_SEG_INDEX) 39 | #define GDT_USER_DATA_SELECTOR (GDT_ENTRY_SIZE * USER_DATA_SEG_INDEX) 40 | 41 | typedef struct _KSegmentDescritor { 42 | u16 limit_low; 43 | u16 base_low; 44 | u8 base_mid; 45 | u8 access; 46 | u8 granularity; 47 | u8 base_high; 48 | } __attribute__((packed)) KSegmentDescritor; 49 | 50 | typedef struct _KGDTPtr { 51 | u16 limit; // GDT actual size - 1 52 | u32 addr; // GDT begin addr 53 | } __attribute__((packed)) KGDTPtr; 54 | 55 | KGDTPtr kinit_gdt(); 56 | void kload_gdt(const KGDTPtr* gdt_ptr); 57 | 58 | #endif /* ifndef _KGDT_H_ */ 59 | -------------------------------------------------------------------------------- /chapter6/include/kidt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KIDT_H_ 25 | #define _KIDT_H_ 26 | 27 | #include 28 | 29 | typedef struct _KInterrputGate { 30 | u16 base_low; 31 | u16 segment_selector; // Segment selector 32 | u8 reserve; // High 4 bits are all 0s 33 | u8 flags; 34 | u16 base_high; 35 | } __attribute__((packed)) KInterrputGate; 36 | 37 | typedef struct _KIDTPtr { 38 | u16 limit; 39 | u32 base; 40 | } __attribute__((packed)) KIDTPtr; 41 | 42 | // Initialize IDT 43 | KIDTPtr kinit_idt(); 44 | 45 | // Load idt 46 | void kload_idt(const KIDTPtr *idt_ptr); 47 | 48 | #endif /* ifndef _KIDT_H_ */ 49 | -------------------------------------------------------------------------------- /chapter6/include/kio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights 5 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 6 | * copies of the Software, and to permit persons to whom the Software is 7 | * furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in 10 | * all copies or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | #ifndef _KIO_H_ 22 | #define _KIO_H_ 23 | 24 | #include 25 | #include 26 | 27 | // Kernel level I/O functions 28 | 29 | i32 kvsprintf(char *s, const char *fmt, kva_list args); 30 | i32 kprintf(const char *fmt, ...); 31 | i32 kcprintf(VgaTextAtrr bg, VgaTextAtrr fg, const char *fmt, 32 | ...); // With color 33 | i32 kputchar(char ch); 34 | i32 kcputchar(char ch, VgaTextAtrr bg, VgaTextAtrr fg); 35 | i32 kputs(const char *str); 36 | i32 kcputs(VgaTextAtrr bg, VgaTextAtrr fg, const char *str); 37 | 38 | #endif /* ifndef _KIO_H_ */ 39 | -------------------------------------------------------------------------------- /chapter6/include/kisr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KINT_H_ 25 | #define _KINT_H_ 26 | 27 | #include 28 | 29 | #define IDT_ENTRY_CNT 256 30 | 31 | typedef enum _IRQ { 32 | IRQ0 = 32, 33 | IRQ1, 34 | IRQ2, 35 | IRQ3, 36 | IRQ4, 37 | IRQ5, 38 | IRQ6, 39 | IRQ7, 40 | IRQ8, 41 | IRQ9, 42 | IRQ10, 43 | IRQ11, 44 | IRQ12, 45 | IRQ13, 46 | IRQ14, 47 | IRQ15 48 | } IRQ; 49 | 50 | typedef struct _KPTRegs { 51 | u32 ds; // Save previous data segment 52 | 53 | u32 edi; // From edi to eax, all pushed by instruction: pusha 54 | u32 esi; 55 | u32 ebp; 56 | u32 esp; 57 | u32 ebx; 58 | u32 edx; 59 | u32 ecx; 60 | u32 eax; 61 | 62 | u32 int_id; // Interrupt id 63 | u32 error_code; // Push by CPU 64 | 65 | /* ---- pushed by CPU ---- */ 66 | u32 eip; 67 | u32 cs; 68 | u32 eflags; 69 | u32 useresp; 70 | u32 ss; 71 | } KPTRegs; 72 | 73 | typedef void (*KInterruptHandler)(KPTRegs *); 74 | 75 | // Register an interrupt handler function 76 | void kreg_int_handler(u32 int_id, KInterruptHandler handler); 77 | 78 | void kisr_handler(KPTRegs *pt_regs); 79 | void kirq_handler(KPTRegs *pt_regs); 80 | 81 | void isr0(); 82 | void isr1(); 83 | void isr2(); 84 | void isr3(); 85 | void isr4(); 86 | void isr5(); 87 | void isr6(); 88 | void isr7(); 89 | void isr8(); 90 | void isr9(); 91 | void isr10(); 92 | void isr11(); 93 | void isr12(); 94 | void isr13(); 95 | void isr14(); 96 | void isr15(); 97 | void isr16(); 98 | void isr17(); 99 | void isr18(); 100 | void isr19(); 101 | void isr20(); 102 | void isr21(); 103 | void isr22(); 104 | void isr23(); 105 | void isr24(); 106 | void isr25(); 107 | void isr26(); 108 | void isr27(); 109 | void isr28(); 110 | void isr29(); 111 | void isr30(); 112 | void isr31(); 113 | 114 | void irq0(); 115 | void irq1(); 116 | void irq2(); 117 | void irq3(); 118 | void irq4(); 119 | void irq5(); 120 | void irq6(); 121 | void irq7(); 122 | void irq8(); 123 | void irq9(); 124 | void irq10(); 125 | void irq11(); 126 | void irq12(); 127 | void irq13(); 128 | void irq14(); 129 | void irq15(); 130 | 131 | // System call 132 | void isr255(); 133 | 134 | void kcli(); 135 | void ksti(); 136 | 137 | #endif /* ifndef _KINT_H_ */ 138 | -------------------------------------------------------------------------------- /chapter6/include/kmultiboot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KMULTIBOOT_H_ 24 | #define _KMULTIBOOT_H_ 25 | 26 | #include 27 | 28 | typedef struct _KMultiBoot { 29 | u32 flags; 30 | u32 mem_lower; 31 | u32 mem_upper; 32 | 33 | u32 boot_device; 34 | u32 cmdline; 35 | u32 mods_count; 36 | u32 mods_addr; 37 | 38 | u32 num; 39 | u32 size; 40 | u32 addr; 41 | u32 shndx; 42 | 43 | // Memory info 44 | u32 mmap_length; 45 | u32 mmap_addr; 46 | 47 | u32 drives_length; 48 | u32 drives_addr; 49 | u32 config_table; 50 | u32 boot_loader_name; 51 | u32 apm_table; 52 | u32 vbe_control_info; 53 | u32 vbe_mode_info; 54 | u32 vbe_mode; 55 | u32 vbe_interface_seg; 56 | u32 vbe_interface_off; 57 | u32 vbe_interface_len; 58 | } __attribute__((packed)) KMultiBoot; 59 | 60 | typedef struct _KMMapEntry { 61 | u32 size; 62 | u32 base_addr_low; 63 | u32 base_addr_high; 64 | u32 length_low; 65 | u32 length_high; 66 | u32 type; 67 | } __attribute__((packed)) KMMapEntry; 68 | 69 | #define KERNEL_BOOT_INFO (__kernel_multiboot_info) 70 | const KMultiBoot* __kernel_multiboot_info; 71 | 72 | #endif /* ifndef _KMULTIBOOT_H_ */ 73 | -------------------------------------------------------------------------------- /chapter6/include/kport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KPORTS_H_ 24 | #define _KPORTS_H_ 25 | 26 | #include 27 | 28 | /* 29 | * Write 'data' to 'port' while specifying the data size: 'size' 30 | * */ 31 | void kout(u16 port, u32 data, KDataSize size); 32 | 33 | /* 34 | * Read 'size' byte(s) from 'port' 35 | * */ 36 | u32 kin(u16 port, KDataSize size); 37 | 38 | #endif /* ifndef _KPORTS_H_ */ 39 | -------------------------------------------------------------------------------- /chapter6/include/kstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KSTRING_H_ 24 | #define _KSTRING_H_ 25 | 26 | #include 27 | 28 | void* kmemcpy(void* dst, const void* src, u32 n); 29 | 30 | void* kmemset(void* s, u8 c, u32 n); 31 | void* kbzero(void* s, u32 n); 32 | 33 | i32 kstrcmp(const char* s1, const char* s2); 34 | i32 kstrncmp(const char* s1, const char* s2, u32 n); 35 | 36 | char* kstrcpy(char* dst, const char* src); 37 | char* kstrncpy(char* dst, const char* src, u32 n); 38 | 39 | char* kstrcat(char* dest, const char* src); 40 | char* kstrncat(char* dest, const char* src, u32 n); 41 | 42 | u32 kstrlen(const char* s); 43 | 44 | #endif /* ifndef _KSTRING_H_ */ 45 | -------------------------------------------------------------------------------- /chapter6/include/ktypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KTYPES_H_ 25 | #define _KTYPES_H_ 26 | 27 | #ifndef NULL 28 | #define NULL (void *)0 29 | #endif 30 | 31 | #ifndef EOF 32 | #define EOF -1 33 | #endif /* ifndef EOF */ 34 | 35 | /* Some type alias in 32-bit machine */ 36 | typedef unsigned int u32; 37 | typedef int i32; 38 | typedef unsigned short u16; 39 | typedef short i16; 40 | typedef unsigned char u8; 41 | typedef char i8; 42 | 43 | typedef enum _KDataSize { 44 | KBYTE = sizeof(u8), 45 | KWORD = sizeof(u16), 46 | KDWORD = sizeof(u32) 47 | } KDataSize; 48 | 49 | typedef enum _KMemUnit { B, KB, MB, GB } KMemUnit; 50 | 51 | #endif /* ifndef _KTYPES_H_ */ 52 | -------------------------------------------------------------------------------- /chapter6/include/kvga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KVGA_H_ 24 | #define _KVGA_H_ 25 | 26 | #include 27 | 28 | #define TAB_WIDTH 4 29 | 30 | typedef enum _VgaTextAtrr { 31 | VGA_BLACK = 0, 32 | VGA_BLUE, 33 | VGA_GREEN, 34 | VGA_CYAN, 35 | VGA_RED, 36 | VGA_MAGENTA, 37 | VGA_BROWN, 38 | VGA_LIGHT_GREY, 39 | VGA_DARK_GREY, 40 | VGA_LIGHT_BLUE, 41 | VGA_LIGHT_GREEN, 42 | VGA_LIGHT_CYAN, 43 | VGA_LIGHT_RED, 44 | VGA_LIGHT_MAGENTA, 45 | VGA_LIGHT_BROWN, // Yellow 46 | VGA_WHITE 47 | } VgaTextAtrr; 48 | 49 | i32 kvga_cputc(char ch, VgaTextAtrr bg, VgaTextAtrr fg); // With color 50 | 51 | i32 kvga_putc(char ch); 52 | 53 | i32 kvga_cputs(const char* str, VgaTextAtrr bg, VgaTextAtrr fg); // With color 54 | 55 | i32 kvga_puts(const char* str); 56 | 57 | void kvga_scroll(); 58 | 59 | void kvga_clear(); 60 | 61 | #endif /* ifndef _kvga_H_ */ 62 | -------------------------------------------------------------------------------- /chapter6/init/kgdt.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2018 Liming,Deng 2 | ;Author: Liming Deng 3 | ; 4 | ;Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | ;this software and associated documentation files (the "Software"), to deal in 6 | ;the Software without restriction, including without limitation the rights to 7 | ;use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | ;the Software, and to permit persons to whom the Software is furnished to do so, 9 | ;subject to the following conditions: 10 | ; 11 | ;The above copyright notice and this permission notice shall be included in all 12 | ;copies or substantial portions of the Software. 13 | ; 14 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | ;FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | ;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | ;IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | ;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | 22 | [global kload_gdt:function] 23 | kload_gdt: 24 | mov eax, [esp + 4] 25 | lgdt [eax] 26 | 27 | mov ax, 0x10 28 | mov ds, ax 29 | mov es, ax 30 | mov fs, ax 31 | mov gs, ax 32 | mov ss, ax 33 | 34 | jmp 0x08:__long_jmp 35 | 36 | __long_jmp: 37 | ret 38 | .end 39 | size kload_gdt __long_jmp.end - kload_gdt 40 | -------------------------------------------------------------------------------- /chapter6/init/kgdt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | 28 | static KSegmentDescritor gdt[GDT_ENTRY_CNT]; 29 | 30 | static void set_segment_descriptor( KSegmentDescritor *sd, u32 base, u32 limit, 31 | u8 access, u8 granularity ); 32 | 33 | void set_segment_descriptor( KSegmentDescritor *sd, u32 base, u32 limit, 34 | u8 access, u8 granularity ) 35 | { 36 | sd->limit_low = limit & 0xffff; 37 | sd->base_low = base & 0xffff; 38 | sd->base_mid = ( base >> 16 ) & 0xff; 39 | sd->access = access; 40 | sd->granularity = ( granularity & 0xf0 ) | ( ( limit >> 16 ) & 0xf ); 41 | sd->base_high = base >> 24; 42 | } 43 | 44 | KGDTPtr kinit_gdt() 45 | { 46 | KGDTPtr gdt_ptr; 47 | gdt_ptr.addr = (u32)gdt; 48 | gdt_ptr.limit = sizeof( gdt ) - 1; 49 | 50 | // Null descritor 51 | set_segment_descriptor( &gdt[NULL_SEG_INDEX], 0x00000000, 0x00000000, 0x00, 52 | 0x00 ); 53 | 54 | // Code segment descritor 55 | set_segment_descriptor( &gdt[CODE_SEG_INDEX], 0x00000000, 0xffffffff, 0x9a, 56 | 0xcf ); 57 | 58 | // Data segment descritor 59 | set_segment_descriptor( &gdt[DATA_SEG_INDEX], 0x00000000, 0xffffffff, 0x92, 60 | 0xcf ); 61 | 62 | // User code segment descritor 63 | set_segment_descriptor( &gdt[USER_CODE_SEG_INDEX], 0x00000000, 0xffffffff, 64 | 0xfa, 0xcf ); 65 | 66 | // User data segment descritor 67 | set_segment_descriptor( &gdt[USER_DATA_SEG_INDEX], 0x00000000, 0xffffffff, 68 | 0xf2, 0xcf ); 69 | 70 | return gdt_ptr; 71 | } 72 | -------------------------------------------------------------------------------- /chapter6/init/kidt.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2018 Liming,Deng 2 | ;Author: Liming Deng 3 | 4 | ;Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | ;this software and associated documentation files (the "Software"), to deal in 6 | ;the Software without restriction, including without limitation the rights to 7 | ;use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | ;the Software, and to permit persons to whom the Software is furnished to do so, 9 | ;subject to the following conditions: 10 | 11 | ;The above copyright notice and this permission notice shall be included in all 12 | ;copies or substantial portions of the Software. 13 | 14 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | ;FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | ;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | ;IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | ;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | [global kload_idt:function] 22 | kload_idt: 23 | cli 24 | mov eax, [esp+4] 25 | lidt [eax] 26 | ret 27 | .end 28 | 29 | size kload_idt kload_idt.end - kload_idt 30 | -------------------------------------------------------------------------------- /chapter6/init/kidt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define ISR_INIT(id) \ 30 | do { \ 31 | set_interrupt_gate(&idt[(id)], (u32)isr##id, GDT_CODE_SELECTOR, 0x8e); \ 32 | } while (0); 33 | 34 | #define IRQ_INIT(id) \ 35 | do { \ 36 | set_interrupt_gate(&idt[(id + 32)], (u32)irq##id, GDT_CODE_SELECTOR, \ 37 | 0x8e); \ 38 | } while (0); 39 | 40 | static KInterrputGate idt[IDT_ENTRY_CNT]; 41 | static int idt_init; 42 | 43 | static void set_interrupt_gate(KInterrputGate *intgt, u32 base, 44 | u16 segment_selector, u8 flags); 45 | 46 | void set_interrupt_gate(KInterrputGate *intgt, u32 base, u16 segment_selector, 47 | u8 flags) { 48 | intgt->base_low = base & 0xffff; 49 | intgt->segment_selector = segment_selector; 50 | intgt->reserve = 0x0; 51 | intgt->flags = flags; // 10001110b 52 | intgt->base_high = (base >> 16) & 0xffff; 53 | } 54 | 55 | KIDTPtr kinit_idt() { 56 | static KIDTPtr idt_ptr; 57 | if (!idt_init) { 58 | idt_ptr.base = (u32)&idt; 59 | idt_ptr.limit = sizeof(idt) - 1; 60 | idt_init = 1; 61 | 62 | // Remap the irq table. 63 | kout(0x20, 0x11, KBYTE); 64 | kout(0xA0, 0x11, KBYTE); 65 | kout(0x21, 0x20, KBYTE); 66 | kout(0xA1, 0x28, KBYTE); 67 | kout(0x21, 0x04, KBYTE); 68 | kout(0xA1, 0x02, KBYTE); 69 | kout(0x21, 0x01, KBYTE); 70 | kout(0xA1, 0x01, KBYTE); 71 | kout(0x21, 0x0, KBYTE); 72 | kout(0xA1, 0x0, KBYTE); 73 | 74 | ISR_INIT(0); 75 | ISR_INIT(1); 76 | ISR_INIT(2); 77 | ISR_INIT(3); 78 | ISR_INIT(4); 79 | ISR_INIT(5); 80 | ISR_INIT(6); 81 | ISR_INIT(7); 82 | ISR_INIT(8); 83 | ISR_INIT(9); 84 | ISR_INIT(10); 85 | ISR_INIT(11); 86 | ISR_INIT(12); 87 | ISR_INIT(13); 88 | ISR_INIT(14); 89 | ISR_INIT(15); 90 | ISR_INIT(16); 91 | ISR_INIT(17); 92 | ISR_INIT(18); 93 | ISR_INIT(19); 94 | ISR_INIT(20); 95 | ISR_INIT(21); 96 | ISR_INIT(22); 97 | ISR_INIT(23); 98 | ISR_INIT(24); 99 | ISR_INIT(25); 100 | ISR_INIT(26); 101 | ISR_INIT(27); 102 | ISR_INIT(28); 103 | ISR_INIT(29); 104 | ISR_INIT(30); 105 | ISR_INIT(31); 106 | 107 | IRQ_INIT(0); 108 | IRQ_INIT(1); 109 | IRQ_INIT(2); 110 | IRQ_INIT(3); 111 | IRQ_INIT(4); 112 | IRQ_INIT(5); 113 | IRQ_INIT(6); 114 | IRQ_INIT(7); 115 | IRQ_INIT(8); 116 | IRQ_INIT(9); 117 | IRQ_INIT(10); 118 | IRQ_INIT(11); 119 | IRQ_INIT(12); 120 | IRQ_INIT(13); 121 | IRQ_INIT(14); 122 | IRQ_INIT(15); 123 | 124 | // System call 125 | ISR_INIT(255); 126 | } 127 | return idt_ptr; 128 | } 129 | -------------------------------------------------------------------------------- /chapter6/init/kisr.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2018 Liming,Deng 2 | 3 | 4 | 5 | ;Author: Liming Deng 6 | ; 7 | ;Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | ;this software and associated documentation files (the "Software"), to deal in 9 | ;the Software without restriction, including without limitation the rights to 10 | ;use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | ;the Software, and to permit persons to whom the Software is furnished to do so, 12 | ;subject to the following conditions: 13 | ; 14 | ;The above copyright notice and this permission notice shall be included in all 15 | ;copies or substantial portions of the Software. 16 | ; 17 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | ;FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | ;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | ;IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | ;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | 25 | %macro ISR_ERRCODE 1 26 | [global isr%1:function] 27 | isr%1: 28 | cli 29 | push dword %1 ; Interrupt id 30 | jmp kisr_common_stub 31 | .end 32 | size isr%1 isr%1.end - isr%1 33 | %endmacro 34 | 35 | %macro ISR_NOERRCODE 1 36 | [global isr%1:function] 37 | isr%1: 38 | cli 39 | push dword 0 ; Dummy error code 40 | push dword %1 41 | jmp kisr_common_stub 42 | .end 43 | size isr%1 isr%1.end - isr%1 44 | %endmacro 45 | 46 | %macro IRQ 2 47 | [global irq%1:function] 48 | irq%1: 49 | cli 50 | push dword 0 ; dummy error code 51 | push dword %2 ; push interrupt id 52 | jmp kirq_common_stub 53 | .end 54 | size irq%1 irq%1.end - irq%1 55 | %endmacro 56 | 57 | ISR_NOERRCODE 0 58 | ISR_NOERRCODE 1 59 | ISR_NOERRCODE 2 60 | ISR_NOERRCODE 3 61 | ISR_NOERRCODE 4 62 | ISR_NOERRCODE 5 63 | ISR_NOERRCODE 6 64 | ISR_NOERRCODE 7 65 | 66 | ISR_ERRCODE 8 67 | 68 | ISR_NOERRCODE 9 69 | 70 | ISR_ERRCODE 10 71 | ISR_ERRCODE 11 72 | ISR_ERRCODE 12 73 | ISR_ERRCODE 13 74 | ISR_ERRCODE 14 75 | 76 | ISR_NOERRCODE 15 77 | ISR_NOERRCODE 16 78 | 79 | ISR_ERRCODE 17 80 | 81 | ISR_NOERRCODE 18 82 | ISR_NOERRCODE 19 83 | ISR_NOERRCODE 20 84 | ISR_NOERRCODE 21 85 | ISR_NOERRCODE 22 86 | ISR_NOERRCODE 23 87 | ISR_NOERRCODE 24 88 | ISR_NOERRCODE 25 89 | ISR_NOERRCODE 26 90 | ISR_NOERRCODE 27 91 | ISR_NOERRCODE 28 92 | ISR_NOERRCODE 29 93 | ISR_NOERRCODE 30 94 | ISR_NOERRCODE 31 95 | 96 | ; System call 97 | ISR_NOERRCODE 255 98 | 99 | IRQ 0, 32 100 | IRQ 1, 33 101 | IRQ 2, 34 102 | IRQ 3, 35 103 | IRQ 4, 36 104 | IRQ 5, 37 105 | IRQ 6, 38 106 | IRQ 7, 39 107 | IRQ 8, 40 108 | IRQ 9, 41 109 | IRQ 10, 42 110 | IRQ 11, 43 111 | IRQ 12, 44 112 | IRQ 13, 45 113 | IRQ 14, 46 114 | IRQ 15, 47 115 | 116 | [extern kisr_handler] 117 | kisr_common_stub: 118 | pusha 119 | 120 | mov ax, ds 121 | 122 | push eax 123 | 124 | mov ax, 0x10 ; Kernel data segment selector 125 | mov ds, ax 126 | mov es, ax 127 | mov fs, ax 128 | mov gs, ax 129 | mov ss, ax 130 | 131 | push esp 132 | call kisr_handler 133 | add esp, 4 134 | 135 | pop ebx 136 | mov ds, bx 137 | mov es, bx 138 | mov fs, bx 139 | mov gs, bx 140 | mov ss, bx 141 | 142 | 143 | popa 144 | add esp, 8 145 | iret 146 | 147 | [extern kirq_handler] 148 | kirq_common_stub: 149 | pusha 150 | 151 | mov ax, ds 152 | 153 | push eax 154 | 155 | mov ax, 0x10 ; Kernel data segment selector 156 | mov ds, ax 157 | mov es, ax 158 | mov fs, ax 159 | mov gs, ax 160 | mov ss, ax 161 | 162 | push esp 163 | call kirq_handler 164 | add esp, 4 165 | 166 | pop ebx 167 | mov ds, bx 168 | mov es, bx 169 | mov fs, bx 170 | mov gs, bx 171 | mov ss, bx 172 | 173 | 174 | popa 175 | add esp, 8 176 | iret 177 | -------------------------------------------------------------------------------- /chapter6/init/kisr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | static KInterruptHandler int_handler_pool[IDT_ENTRY_CNT] = {NULL}; 31 | 32 | // Register an interrupt handler function 33 | void kreg_int_handler(u32 int_id, KInterruptHandler handler) 34 | { 35 | int_handler_pool[int_id] = handler; 36 | } 37 | 38 | void kisr_handler(KPTRegs *pt_regs) 39 | { 40 | // If registered 41 | KInterruptHandler handler = int_handler_pool[pt_regs->int_id]; 42 | if (handler) 43 | handler(pt_regs); 44 | else 45 | kcprintf(VGA_BLACK, VGA_RED, "Unhandled interrupt: %d\n", 46 | pt_regs->int_id); 47 | } 48 | 49 | 50 | void kirq_handler(KPTRegs *pt_regs) 51 | { 52 | // Send an EOI (end of interrupt) signal to the PICs. 53 | // If this interrupt involved the slave. 54 | if (pt_regs->int_id >= 40) 55 | kout(0xA0, 0x20, KBYTE); 56 | 57 | // Reset master 58 | kout(0x20, 0x20, KBYTE); 59 | 60 | kisr_handler(pt_regs); 61 | } 62 | 63 | void kcli() 64 | { 65 | __asm__ volatile("cli"); 66 | } 67 | 68 | void ksti() 69 | { 70 | __asm__ volatile("sti"); 71 | } 72 | -------------------------------------------------------------------------------- /chapter6/kernel/kmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void hlt() { 10 | while (1) 11 | __asm__ volatile("hlt"); 12 | } 13 | 14 | void kmain(KMultiBoot *mb) { 15 | KERNEL_BOOT_INFO = mb; 16 | 17 | KGDTPtr gdt_ptr = kinit_gdt(); 18 | kload_gdt(&gdt_ptr); 19 | 20 | KIDTPtr idt_ptr = kinit_idt(); 21 | kload_idt(&idt_ptr); 22 | 23 | __asm__ volatile("sti"); 24 | kprintf("hello world?\n"); 25 | 26 | hlt(); 27 | } 28 | -------------------------------------------------------------------------------- /chapter6/lib/kdebug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | static KELF kernel_elf; 30 | static const KELF *pkelf = NULL; 31 | 32 | // Define in boot/boot.asm 33 | 34 | static void env_init(); 35 | 36 | void env_init() { 37 | if (pkelf == NULL) { 38 | kernel_elf = kget_kernel_elf_info(KERNEL_BOOT_INFO); 39 | pkelf = &kernel_elf; 40 | } 41 | } 42 | 43 | void kpanic(const char *msg) { 44 | kprintf("****Fatal error eccured****\n" 45 | "****Kernel in panic****\n"); 46 | if (msg) 47 | kprintf("%s\n", msg); 48 | kstack_trace(); 49 | while (1) 50 | ; 51 | } 52 | 53 | void __kassert(const char *file, int line, const char *func, const char *expr) { 54 | kcprintf(VGA_BLACK, VGA_LIGHT_BROWN, 55 | "In file %s: %d function %s asserts '%s' failed\n", file, line, func, 56 | expr); 57 | kpanic(NULL); 58 | } 59 | 60 | void kstack_trace() { 61 | env_init(); 62 | u32 *ebp, *eip; 63 | 64 | // Get %ebp 65 | __asm__ volatile("mov %%ebp,%0" : "=r"(ebp)); 66 | 67 | // %ebp was initiated in boot/boot.asm with 0x0 68 | while (ebp) { 69 | /* 70 | * | -------- | 71 | * | ... | < ---- ebp_prev 72 | * | -------- | 73 | * | . | 74 | * | . | 75 | * | . | 76 | * | -------- | 77 | * | &$ | < ---- call function `x` ($ is the addr of next instruction) 78 | * | -------- | 79 | * | ebp_prev | < ---- push ebp; mov ebp, esp | <= esp , ebp 80 | * | -------- | 81 | */ 82 | eip = ebp + 1; // (void *)eip == (void *)ebp + 4 83 | kprintf("\t[%p]:\t%s\n", *eip - 5, ksearch_function(*eip - 5, pkelf)); 84 | ebp = (u32 *)*ebp; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /chapter6/lib/kelf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #define ELF32_ST_TYPE(i) ((i)&0xf) 27 | 28 | // Get kernel elf info 29 | KELF kget_kernel_elf_info(const KMultiBoot* mb) 30 | { 31 | KELFSectionHeader* begin = (KELFSectionHeader*)(mb->addr); 32 | KELF elf; 33 | 34 | u32 shstrtab = begin[mb->shndx].addr ; // Section name array 35 | // Loop through all sections 36 | 37 | const KELFSectionHeader* end = &begin[mb->num]; 38 | for (const KELFSectionHeader* sh = begin; sh < end; ++sh) { 39 | const char* section_name = (const char*)(shstrtab + sh->name); 40 | 41 | if (kstrcmp(section_name, ".strtab") == 0) { 42 | elf.strtab = (const char*)(sh->addr); 43 | elf.strtabsz = sh->size; 44 | continue; 45 | } else if (kstrcmp(section_name, ".symtab") == 0) { 46 | elf.symtab = (KELFSymbol*)(sh->addr); 47 | elf.symtabsz = sh->size; 48 | } 49 | } 50 | return elf; 51 | } 52 | 53 | // Return the name of the function whose address range includes 'addr' 54 | const char* ksearch_function(u32 addr, const KELF* elf) 55 | { 56 | if (elf) { 57 | const KELFSymbol* end = &elf->symtab[elf->symtabsz / sizeof(KELFSymbol)]; 58 | 59 | for (const KELFSymbol* symbol = elf->symtab; symbol < end; ++symbol) 60 | if (ELF32_ST_TYPE(symbol->info) != 0x2) 61 | continue; 62 | else if (addr >= symbol->value && addr < symbol->value + symbol->size) 63 | return (const char*)(elf->strtab + symbol->name); 64 | } 65 | return NULL; 66 | } 67 | -------------------------------------------------------------------------------- /chapter6/lib/kstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | // For the simplicity, we do not apply loop unrolling 26 | 27 | inline void* kmemcpy(void* dst, const void* src, u32 n) 28 | { 29 | const u8* s = (u8*)src; 30 | u8* t = (u8*)dst; 31 | while (n--) 32 | *t++ = *s++; 33 | return dst; 34 | } 35 | 36 | inline void* kmemset(void* s, u8 c, u32 n) 37 | { 38 | u8* m = (u8*)s; 39 | while (n--) 40 | *m++ = c; 41 | return s; 42 | } 43 | 44 | inline void* kbzero(void* s, u32 n) 45 | { 46 | kmemset(s, '\0', n); 47 | return s; 48 | } 49 | 50 | inline i32 kstrcmp(const char* s1, const char* s2) 51 | { 52 | i32 a = 0, b = 0; 53 | do { 54 | a = *s1++; 55 | b = *s2++; 56 | } while (a && b && a == b); 57 | return a - b; 58 | } 59 | 60 | inline i32 kstrncmp(const char* s1, const char* s2, u32 n) 61 | { 62 | i32 a = 0, b = 0; 63 | for (; n && a == b; --n) { 64 | a = *s1++; 65 | b = *s2++; 66 | } 67 | return a - b; 68 | } 69 | 70 | char* kstrcat(char* dst, const char* src) 71 | { 72 | char* t = dst; 73 | while (*t++) 74 | ; 75 | --t; 76 | while (*src) 77 | *t++ = *src++; 78 | return dst; 79 | } 80 | 81 | char* kstrncat(char* dst, const char* src, u32 n) 82 | { 83 | char* t = dst; 84 | while (*t++) 85 | ; 86 | --t; 87 | while (n--) 88 | *t++ = *src++; 89 | *t = '\0'; 90 | return dst; 91 | } 92 | 93 | char* kstrcpy(char* dst, const char* src) 94 | { 95 | char* t = dst; 96 | while (*src) 97 | *t++ = *src++; 98 | *t = '\0'; 99 | return dst; 100 | } 101 | char* kstrncpy(char* dst, const char* src, u32 n) 102 | { 103 | char* t = dst; 104 | u32 i; 105 | for (i = 0; i < n && *src; ++i) 106 | *t++ = *src++; 107 | for (; i < n; ++i) 108 | *t++ = '\0'; 109 | return dst; 110 | } 111 | 112 | u32 kstrlen(const char* s) 113 | { 114 | u32 l = 0; 115 | while (*s++) 116 | ++l; 117 | return l; 118 | } 119 | -------------------------------------------------------------------------------- /chapter6/scripts/gdbinit: -------------------------------------------------------------------------------- 1 | shell qemu-system-i386 -s -S -cdrom build/osmanthus.iso & 2 | symbol-file build/osmanthus 3 | set arch i386:intel 4 | target remote :1234 5 | b __start 6 | b kmain 7 | -------------------------------------------------------------------------------- /chapter6/scripts/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "os-name" { 2 | multiboot /boot/kernel-name 3 | } 4 | -------------------------------------------------------------------------------- /chapter6/scripts/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(__start) 2 | SECTIONS 3 | { 4 | PROVIDE( __kernel_begin_addr = . ); 5 | . = 0x100000; 6 | .text : 7 | { 8 | *(.text) 9 | . = ALIGN(4096); 10 | } 11 | .data : 12 | { 13 | *(.data) 14 | *(.rodata) 15 | . = ALIGN(4096); 16 | } 17 | .bss : 18 | { 19 | *(.bss) 20 | . = ALIGN(4096); 21 | } 22 | .stab : 23 | { 24 | *(.stab) 25 | . = ALIGN(4096); 26 | } 27 | .stabstr : 28 | { 29 | *(.stabstr) 30 | . = ALIGN(4096); 31 | } 32 | PROVIDE( __kernel_end_addr = . ); 33 | 34 | /DISCARD/ : { *(.comment) *(.eh_frame) } 35 | } 36 | -------------------------------------------------------------------------------- /chapter7/Makefile: -------------------------------------------------------------------------------- 1 | OS_NAME=Osmanthus 2 | KERNEL_NAME=osmanthus 3 | ISO_DIR=isodir 4 | ISO_NAME=${KERNEL_NAME}.iso 5 | 6 | BUILD=build 7 | SCRIPTS=scripts 8 | LIB=lib 9 | INIT=init 10 | BOOT=boot 11 | DRIVER=driver 12 | KERNEL=kernel 13 | INCLUDE=include 14 | 15 | ASM=yasm 16 | CC=gcc 17 | LD=ld 18 | 19 | CFLAGS=-c -m32 -Wextra -Wall \ 20 | -nostdinc -ffreestanding -fno-builtin -fno-stack-protector -fno-pie \ 21 | -Xassembler --32 \ 22 | -I${INCLUDE} 23 | 24 | RFLAGS=-DNDEBUG -O0 25 | DFLAGS=-g -ggdb -gstabs+ 26 | 27 | LDFLAGS = -T $(SCRIPTS)/link.ld -m elf_i386 -nostdlib 28 | ASFLAGS = -f elf 29 | 30 | C_SOURCES=${wildcard ${DRIVER}/*.c ${KERNEL}/*.c ${LIB}/*.c ${INIT}/*.c } 31 | 32 | C_OBJ=$(addprefix ${BUILD}/,${C_SOURCES:.c=_c.o}) 33 | 34 | ASM_SOURCES=${wildcard ${BOOT}/*.asm ${INIT}/*.asm} 35 | 36 | ASM_OBJ=$(addprefix ${BUILD}/,${ASM_SOURCES:.asm=_asm.o}) 37 | 38 | .PHONY: all 39 | all : CFLAGS+=${DFLAGS} 40 | all : ${BUILD} ${KERNEL_NAME} 41 | @cp ${BUILD}/${KERNEL_NAME} ${BUILD}/${ISO_DIR}/boot/ 42 | @sed 's,os-name,${OS_NAME},g; s,kernel-name,${KERNEL_NAME},g' \ 43 | ${SCRIPTS}/grub.cfg > ${BUILD}/${ISO_DIR}/boot/grub/grub.cfg 44 | @echo -e "\033[0;31mMakeing Kernel ISO \033[0m" 45 | @grub-mkrescue -o ${BUILD}/${ISO_NAME} ${BUILD}/${ISO_DIR} > /dev/null 2>&1 46 | 47 | ${BUILD}: 48 | @echo -e "\033[0;34mBuilding 'build' directory\033[0m" 49 | @mkdir -p $@/${ISO_DIR}/boot/grub \ 50 | $@/${BOOT} \ 51 | $@/${DRIVER} \ 52 | $@/${KERNEL} \ 53 | $@/${LIB} \ 54 | $@/${INIT} 55 | 56 | 57 | ${KERNEL_NAME} : ${ASM_OBJ} ${C_OBJ} 58 | @echo -e "\033[0;34mLinking kernel \033[0m" 59 | @${LD} ${LDFLAGS} $^ -o ${BUILD}/$@ 60 | 61 | ${BUILD}/%_asm.o : %.asm 62 | @echo -e "\033[0;32mAssembling module :\t\033[0m" $< 63 | @${ASM} ${ASFLAGS} $< -o $@ 64 | 65 | ${BUILD}/%_c.o : %.c 66 | @echo -e "\033[0;32mCompiling module :\t\033[0m" $< 67 | @${CC} ${CFLAGS} $< -o $@ 68 | 69 | .PHONY: run 70 | run: CFLAGS += ${RFLAGS} 71 | run: 72 | @make CFLAGS="${CFLAGS}" --no-print-directory 73 | @echo -e "\033[0;34mStarting QEMU\033[0m" 74 | @qemu-system-i386 \ 75 | ${BUILD}/${ISO_NAME} > /dev/null 2>&1 76 | 77 | .PHONY: release 78 | release: CFLAGS += ${RFLAGS} 79 | release: 80 | @echo -e "\033[0;34mMaking release version\033[0m" 81 | @make CFLAGS="${CFLAGS}" --no-print-directory 82 | 83 | .PHONY: debug 84 | debug: CFLAGS += ${DFLAGS} 85 | debug: 86 | @echo -e "\033[0;34mMaking debug version\033[0m" 87 | @make CFLAGS="${CFLAGS}" --no-print-directory 88 | 89 | 90 | .PHONY: clean 91 | clean: 92 | @echo -e "\033[0;34mCleaning \033[0m" 93 | @rm -rf build 94 | @echo -e "\033[0;31mFinished\033[0m" 95 | -------------------------------------------------------------------------------- /chapter7/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 7 -- 定时器编程 2 | 3 | 定时器中断是一个周期性的中断, 每隔一段时间, 一个定时器中断就会到来, 定时器中断在任务调度上非常关键, 所以我们要设计出对其设置的接口. 4 | 5 | 具体硬件的知识我就不讲了, 我们把它当作黑匣子 6 | 7 | ```c 8 | #define INPUT_FREQ 0x1234dc 9 | 10 | void init_timer( u32 frequency, KInterruptHandler handler ) 11 | { 12 | kreg_int_handler( IRQ0, handler ); 13 | 14 | u32 divisor = INPUT_FREQ / frequency; 15 | kout( 0x43, 0x36, KBYTE ); 16 | 17 | u8 l = divisor & 0xff; 18 | u8 h = ( divisor >> 8 ) & 0xff; 19 | 20 | kout( 0x40, l, KBYTE ); 21 | kout( 0x40, h, KBYTE ); 22 | } 23 | ``` 24 | 25 | 通过上边的函数, 我们就能够让定时器工作在指定的频率上, 并且注册`handler`, 让其变成定时器中断的处理函数. 26 | 27 | 也就是说每个时间周期我们都会执行一次中断处理函数, 注意如果中断处理函数执行的时间过长, 也会被下一个定时器中断中断. 28 | 29 | 我们这里先不介绍锁的概念, 我们这里可以用较为简单的函数, 并且通过降低定时器工作频率的方法来实现测试. 30 | 31 | ```c 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | void hlt() { 42 | while (1) 43 | __asm__ volatile("hlt"); 44 | } 45 | 46 | void timer_handler(KPTRegs *pt_regs) { 47 | static u32 tick_tock = 0; 48 | kcprintf(VGA_BLACK, VGA_LIGHT_BROWN, "tick: %u\n", tick_tock++); // 每5ms打印一次 49 | } 50 | 51 | void kmain(KMultiBoot *mb) { 52 | KERNEL_BOOT_INFO = mb; 53 | 54 | KGDTPtr gdt_ptr = kinit_gdt(); 55 | kload_gdt(&gdt_ptr); 56 | 57 | KIDTPtr idt_ptr = kinit_idt(); 58 | kload_idt(&idt_ptr); 59 | 60 | kinit_timer(200, timer_handler); 61 | 62 | __asm__ volatile("sti"); 63 | 64 | kprintf("hello world?\n"); 65 | 66 | hlt(); 67 | } 68 | ``` 69 | 70 | 运行结果: 71 | 72 | ![](https://github.com/iosmanthus/Osmanthus-tutorial/blob/master/etc/Screenshot%20from%202018-04-22%2016-48-51.png) -------------------------------------------------------------------------------- /chapter7/boot/boot.asm: -------------------------------------------------------------------------------- 1 | [bits 32] ;; 以下是32位代码 2 | MULTIBOOT_HEADER_MAGIC equ 0x1badb002 ;; 魔数 3 | MULTIBOOT_PAGE_ALIGN equ 1 << 0 ;; 所有引导模块页(4KB)对齐 4 | MULTIBOOT_MEMORY_INFO equ 1 << 1 ;; 将内存信息写到MultiBoot结构体中 5 | 6 | ;; 将上两行属性结合起来 7 | MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO 8 | 9 | ;; 校验码 10 | MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC+MULTIBOOT_HEADER_FLAGS) 11 | 12 | ;; 内核临时栈大小 13 | KERNEL_STACK_SIZE equ 0x400 14 | 15 | ;; 内核虚拟起始地址 我们先写在这里 暂时不用管他们的作用 16 | ;; KERNEL_VM_OFFSET equ 0xC0000000 17 | 18 | 19 | ;; section .init.text 这个注释以后可以去掉, 我们暂时用.text去代替 20 | 21 | section .text 22 | 23 | dd MULTIBOOT_HEADER_MAGIC ;; 24 | dd MULTIBOOT_HEADER_FLAGS ;; 将定义好的信息写进文件头 25 | dd MULTIBOOT_CHECKSUM ;; 26 | 27 | [global __start:function] ;; 内核入口 :function是yasm的修饰符 28 | [extern kmain] ;; 内核主函数 29 | 30 | __start: 31 | cli 32 | 33 | mov esp, __kernel_stack_top ;; 设置好内核的临时栈顶 34 | and esp, 0xfffffff0 ;; 按16字节对齐 35 | mov ebp , 0x0 ;; 作为以后backtrace的终止条件 36 | 37 | push ebx ;; Grub将内存信息写到了一块内存中, 将内存的首地址放在了ebx 我们作为参数传给内核主函数 38 | call kmain ;; 调用内核主函数 这里我们假定主函数永远不会返回 如果有强迫症 可以将下边注释去掉 39 | ;; 但是正确性在启用分页之后不保证. 40 | .end 41 | 42 | size __start __start.end - __start ;; 指定函数__start的大小 43 | 44 | ;; section .init.data 同上.init.text 45 | section .data 46 | ; Temporary kernel stack 47 | __kernel_stack_base: 48 | times KERNEL_STACK_SIZE db 0 ; 1KB 内核临时栈空间 49 | __kernel_stack_top: 50 | -------------------------------------------------------------------------------- /chapter7/driver/kport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | void kout(u16 port, u32 data, KDataSize size) 26 | { 27 | if (size == KBYTE) 28 | __asm__ volatile("outb %%al,%%dx" ::"d"(port), "a"(data)); 29 | else if (size == KWORD) 30 | __asm__ volatile("outw %%ax,%%dx" ::"d"(port), "a"(data)); 31 | else if (size == KDWORD) 32 | __asm__ volatile("outl %%eax,%%dx" ::"d"(port), "a"(data)); 33 | } 34 | 35 | u32 kin(u16 port, KDataSize size) 36 | { 37 | u8 db = 0; 38 | u16 dw = 0; 39 | u32 dl = 0; 40 | if (size == KBYTE) { 41 | __asm__ volatile("inb %%dx, %%al" 42 | : "=a"(db) 43 | : "d"(port)); 44 | return db; 45 | } else if (size == KWORD) { 46 | __asm__ volatile("inw %%dx, %%ax" 47 | : "=a"(dw) 48 | : "d"(port)); 49 | return dw; 50 | } else if (size == KDWORD) { 51 | __asm__ volatile("inl %%dx, %%eax" 52 | : "=a"(dl) 53 | : "d"(port)); 54 | return dl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /chapter7/include/karg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KARG_H_ 24 | #define _KARG_H_ 25 | 26 | // Various arguments macro for i386 27 | 28 | #include 29 | 30 | typedef char* kva_list; 31 | 32 | #define kva_start(ap, last) \ 33 | (ap = (kva_list)(((kva_list)&last) + ((sizeof(last) + 3) & ~3))) 34 | 35 | #define kva_arg(ap, type) \ 36 | (*(type*)(ap += ((sizeof(type) + 3) & ~3), \ 37 | ap - ((sizeof(type) + 3) & ~3))) 38 | 39 | #define kva_copy(dst, src) (dst) = (src) 40 | 41 | #define kva_end(ap) (ap = (kva_list)NULL) 42 | 43 | #endif /* ifndef _KARG_H_ */ 44 | -------------------------------------------------------------------------------- /chapter7/include/kdebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KDEBUG_H_ 24 | #define _KDEBUG_H_ 25 | 26 | #ifdef NDEBUG 27 | #define kassert(cond) (void)0 28 | #else 29 | void __kassert(const char* file, int line, const char* func, 30 | const char* expr); 31 | 32 | #define kassert(cond) \ 33 | do { \ 34 | if (!(cond)) { \ 35 | __kassert(__FILE__, __LINE__, __func__, #cond); \ 36 | } \ 37 | } while (0) 38 | #endif 39 | 40 | // Print call stack trace 41 | 42 | void kstack_trace(); 43 | 44 | // Fatal error 45 | void kpanic(const char* msg); 46 | 47 | #endif /* ifndef _KDEBUG_H_ */ 48 | -------------------------------------------------------------------------------- /chapter7/include/kelf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KELF_H_ 24 | #define _KELF_H_ 25 | 26 | #include 27 | #include 28 | 29 | // ELF section header 30 | typedef struct _KELFSectionHeader { 31 | u32 name; 32 | u32 type; 33 | u32 flags; 34 | u32 addr; 35 | u32 offset; 36 | u32 size; 37 | u32 link; 38 | u32 info; 39 | u32 addralign; 40 | u32 entsize; 41 | } __attribute__((packed)) KELFSectionHeader; 42 | 43 | // ELF Symbol 44 | typedef struct _KELFSymbol { 45 | u32 name; 46 | u32 value; 47 | u32 size; 48 | u8 info; 49 | u8 other; 50 | u16 shndx; 51 | } __attribute__((packed)) KELFSymbol; 52 | 53 | // ELF info 54 | typedef struct _KELF { 55 | KELFSymbol* symtab; 56 | u32 symtabsz; 57 | const char* strtab; 58 | u32 strtabsz; 59 | } KELF; 60 | 61 | // Get kernel elf info 62 | KELF kget_kernel_elf_info(const KMultiBoot* mb); 63 | 64 | // Return symbol whose address range includes 'addr' 65 | const char* ksearch_function(u32 addr, const KELF* elf); 66 | 67 | #endif /* ifndef _KELF_H_ */ 68 | -------------------------------------------------------------------------------- /chapter7/include/kgdt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KGDT_H_ 24 | #define _KGDT_H_ 25 | #include 26 | 27 | #define GDT_ENTRY_CNT 5 28 | #define GDT_ENTRY_SIZE 8 29 | 30 | #define NULL_SEG_INDEX 0 31 | #define CODE_SEG_INDEX 1 32 | #define DATA_SEG_INDEX 2 33 | #define USER_CODE_SEG_INDEX 3 34 | #define USER_DATA_SEG_INDEX 4 35 | 36 | #define GDT_CODE_SELECTOR (GDT_ENTRY_SIZE * CODE_SEG_INDEX) 37 | #define GDT_DATA_SELECTOR (GDT_ENTRY_SIZE * DATA_SEG_INDEX) 38 | #define GDT_USER_CODE_SELECTOR (GDT_ENTRY_SIZE * USER_CODE_SEG_INDEX) 39 | #define GDT_USER_DATA_SELECTOR (GDT_ENTRY_SIZE * USER_DATA_SEG_INDEX) 40 | 41 | typedef struct _KSegmentDescritor { 42 | u16 limit_low; 43 | u16 base_low; 44 | u8 base_mid; 45 | u8 access; 46 | u8 granularity; 47 | u8 base_high; 48 | } __attribute__((packed)) KSegmentDescritor; 49 | 50 | typedef struct _KGDTPtr { 51 | u16 limit; // GDT actual size - 1 52 | u32 addr; // GDT begin addr 53 | } __attribute__((packed)) KGDTPtr; 54 | 55 | KGDTPtr kinit_gdt(); 56 | void kload_gdt(const KGDTPtr* gdt_ptr); 57 | 58 | #endif /* ifndef _KGDT_H_ */ 59 | -------------------------------------------------------------------------------- /chapter7/include/kidt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KIDT_H_ 25 | #define _KIDT_H_ 26 | 27 | #include 28 | 29 | typedef struct _KInterrputGate { 30 | u16 base_low; 31 | u16 segment_selector; // Segment selector 32 | u8 reserve; // High 4 bits are all 0s 33 | u8 flags; 34 | u16 base_high; 35 | } __attribute__((packed)) KInterrputGate; 36 | 37 | typedef struct _KIDTPtr { 38 | u16 limit; 39 | u32 base; 40 | } __attribute__((packed)) KIDTPtr; 41 | 42 | // Initialize IDT 43 | KIDTPtr kinit_idt(); 44 | 45 | // Load idt 46 | void kload_idt(const KIDTPtr *idt_ptr); 47 | 48 | #endif /* ifndef _KIDT_H_ */ 49 | -------------------------------------------------------------------------------- /chapter7/include/kio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights 5 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 6 | * copies of the Software, and to permit persons to whom the Software is 7 | * furnished to do so, subject to the following conditions: 8 | * 9 | * The above copyright notice and this permission notice shall be included in 10 | * all copies or substantial portions of the Software. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | #ifndef _KIO_H_ 22 | #define _KIO_H_ 23 | 24 | #include 25 | #include 26 | 27 | // Kernel level I/O functions 28 | 29 | i32 kvsprintf(char *s, const char *fmt, kva_list args); 30 | i32 kprintf(const char *fmt, ...); 31 | i32 kcprintf(VgaTextAtrr bg, VgaTextAtrr fg, const char *fmt, 32 | ...); // With color 33 | i32 kputchar(char ch); 34 | i32 kcputchar(char ch, VgaTextAtrr bg, VgaTextAtrr fg); 35 | i32 kputs(const char *str); 36 | i32 kcputs(VgaTextAtrr bg, VgaTextAtrr fg, const char *str); 37 | 38 | #endif /* ifndef _KIO_H_ */ 39 | -------------------------------------------------------------------------------- /chapter7/include/kisr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KINT_H_ 25 | #define _KINT_H_ 26 | 27 | #include 28 | 29 | #define IDT_ENTRY_CNT 256 30 | 31 | typedef enum _IRQ { 32 | IRQ0 = 32, 33 | IRQ1, 34 | IRQ2, 35 | IRQ3, 36 | IRQ4, 37 | IRQ5, 38 | IRQ6, 39 | IRQ7, 40 | IRQ8, 41 | IRQ9, 42 | IRQ10, 43 | IRQ11, 44 | IRQ12, 45 | IRQ13, 46 | IRQ14, 47 | IRQ15 48 | } IRQ; 49 | 50 | typedef struct _KPTRegs { 51 | u32 ds; // Save previous data segment 52 | 53 | u32 edi; // From edi to eax, all pushed by instruction: pusha 54 | u32 esi; 55 | u32 ebp; 56 | u32 esp; 57 | u32 ebx; 58 | u32 edx; 59 | u32 ecx; 60 | u32 eax; 61 | 62 | u32 int_id; // Interrupt id 63 | u32 error_code; // Push by CPU 64 | 65 | /* ---- pushed by CPU ---- */ 66 | u32 eip; 67 | u32 cs; 68 | u32 eflags; 69 | u32 useresp; 70 | u32 ss; 71 | } KPTRegs; 72 | 73 | typedef void (*KInterruptHandler)(KPTRegs *); 74 | 75 | // Register an interrupt handler function 76 | void kreg_int_handler(u32 int_id, KInterruptHandler handler); 77 | 78 | void kisr_handler(KPTRegs *pt_regs); 79 | void kirq_handler(KPTRegs *pt_regs); 80 | 81 | void isr0(); 82 | void isr1(); 83 | void isr2(); 84 | void isr3(); 85 | void isr4(); 86 | void isr5(); 87 | void isr6(); 88 | void isr7(); 89 | void isr8(); 90 | void isr9(); 91 | void isr10(); 92 | void isr11(); 93 | void isr12(); 94 | void isr13(); 95 | void isr14(); 96 | void isr15(); 97 | void isr16(); 98 | void isr17(); 99 | void isr18(); 100 | void isr19(); 101 | void isr20(); 102 | void isr21(); 103 | void isr22(); 104 | void isr23(); 105 | void isr24(); 106 | void isr25(); 107 | void isr26(); 108 | void isr27(); 109 | void isr28(); 110 | void isr29(); 111 | void isr30(); 112 | void isr31(); 113 | 114 | void irq0(); 115 | void irq1(); 116 | void irq2(); 117 | void irq3(); 118 | void irq4(); 119 | void irq5(); 120 | void irq6(); 121 | void irq7(); 122 | void irq8(); 123 | void irq9(); 124 | void irq10(); 125 | void irq11(); 126 | void irq12(); 127 | void irq13(); 128 | void irq14(); 129 | void irq15(); 130 | 131 | // System call 132 | void isr255(); 133 | 134 | void kcli(); 135 | void ksti(); 136 | 137 | #endif /* ifndef _KINT_H_ */ 138 | -------------------------------------------------------------------------------- /chapter7/include/kmultiboot.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KMULTIBOOT_H_ 24 | #define _KMULTIBOOT_H_ 25 | 26 | #include 27 | 28 | typedef struct _KMultiBoot { 29 | u32 flags; 30 | u32 mem_lower; 31 | u32 mem_upper; 32 | 33 | u32 boot_device; 34 | u32 cmdline; 35 | u32 mods_count; 36 | u32 mods_addr; 37 | 38 | u32 num; 39 | u32 size; 40 | u32 addr; 41 | u32 shndx; 42 | 43 | // Memory info 44 | u32 mmap_length; 45 | u32 mmap_addr; 46 | 47 | u32 drives_length; 48 | u32 drives_addr; 49 | u32 config_table; 50 | u32 boot_loader_name; 51 | u32 apm_table; 52 | u32 vbe_control_info; 53 | u32 vbe_mode_info; 54 | u32 vbe_mode; 55 | u32 vbe_interface_seg; 56 | u32 vbe_interface_off; 57 | u32 vbe_interface_len; 58 | } __attribute__((packed)) KMultiBoot; 59 | 60 | typedef struct _KMMapEntry { 61 | u32 size; 62 | u32 base_addr_low; 63 | u32 base_addr_high; 64 | u32 length_low; 65 | u32 length_high; 66 | u32 type; 67 | } __attribute__((packed)) KMMapEntry; 68 | 69 | #define KERNEL_BOOT_INFO (__kernel_multiboot_info) 70 | const KMultiBoot* __kernel_multiboot_info; 71 | 72 | #endif /* ifndef _KMULTIBOOT_H_ */ 73 | -------------------------------------------------------------------------------- /chapter7/include/kpit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KPIT_H_ 25 | #define _KPIT_H_ 26 | 27 | #include 28 | #include 29 | 30 | void kinit_timer(u32 frequency, KInterruptHandler handler); 31 | 32 | #endif /* ifndef _KPIT_H_ */ 33 | -------------------------------------------------------------------------------- /chapter7/include/kport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KPORTS_H_ 24 | #define _KPORTS_H_ 25 | 26 | #include 27 | 28 | /* 29 | * Write 'data' to 'port' while specifying the data size: 'size' 30 | * */ 31 | void kout(u16 port, u32 data, KDataSize size); 32 | 33 | /* 34 | * Read 'size' byte(s) from 'port' 35 | * */ 36 | u32 kin(u16 port, KDataSize size); 37 | 38 | #endif /* ifndef _KPORTS_H_ */ 39 | -------------------------------------------------------------------------------- /chapter7/include/kstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KSTRING_H_ 24 | #define _KSTRING_H_ 25 | 26 | #include 27 | 28 | void* kmemcpy(void* dst, const void* src, u32 n); 29 | 30 | void* kmemset(void* s, u8 c, u32 n); 31 | void* kbzero(void* s, u32 n); 32 | 33 | i32 kstrcmp(const char* s1, const char* s2); 34 | i32 kstrncmp(const char* s1, const char* s2, u32 n); 35 | 36 | char* kstrcpy(char* dst, const char* src); 37 | char* kstrncpy(char* dst, const char* src, u32 n); 38 | 39 | char* kstrcat(char* dest, const char* src); 40 | char* kstrncat(char* dest, const char* src, u32 n); 41 | 42 | u32 kstrlen(const char* s); 43 | 44 | #endif /* ifndef _KSTRING_H_ */ 45 | -------------------------------------------------------------------------------- /chapter7/include/ktypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #ifndef _KTYPES_H_ 25 | #define _KTYPES_H_ 26 | 27 | #ifndef NULL 28 | #define NULL (void *)0 29 | #endif 30 | 31 | #ifndef EOF 32 | #define EOF -1 33 | #endif /* ifndef EOF */ 34 | 35 | /* Some type alias in 32-bit machine */ 36 | typedef unsigned int u32; 37 | typedef int i32; 38 | typedef unsigned short u16; 39 | typedef short i16; 40 | typedef unsigned char u8; 41 | typedef char i8; 42 | 43 | typedef enum _KDataSize { 44 | KBYTE = sizeof(u8), 45 | KWORD = sizeof(u16), 46 | KDWORD = sizeof(u32) 47 | } KDataSize; 48 | 49 | typedef enum _KMemUnit { B, KB, MB, GB } KMemUnit; 50 | 51 | #endif /* ifndef _KTYPES_H_ */ 52 | -------------------------------------------------------------------------------- /chapter7/include/kvga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _KVGA_H_ 24 | #define _KVGA_H_ 25 | 26 | #include 27 | 28 | #define TAB_WIDTH 4 29 | 30 | typedef enum _VgaTextAtrr { 31 | VGA_BLACK = 0, 32 | VGA_BLUE, 33 | VGA_GREEN, 34 | VGA_CYAN, 35 | VGA_RED, 36 | VGA_MAGENTA, 37 | VGA_BROWN, 38 | VGA_LIGHT_GREY, 39 | VGA_DARK_GREY, 40 | VGA_LIGHT_BLUE, 41 | VGA_LIGHT_GREEN, 42 | VGA_LIGHT_CYAN, 43 | VGA_LIGHT_RED, 44 | VGA_LIGHT_MAGENTA, 45 | VGA_LIGHT_BROWN, // Yellow 46 | VGA_WHITE 47 | } VgaTextAtrr; 48 | 49 | i32 kvga_cputc(char ch, VgaTextAtrr bg, VgaTextAtrr fg); // With color 50 | 51 | i32 kvga_putc(char ch); 52 | 53 | i32 kvga_cputs(const char* str, VgaTextAtrr bg, VgaTextAtrr fg); // With color 54 | 55 | i32 kvga_puts(const char* str); 56 | 57 | void kvga_scroll(); 58 | 59 | void kvga_clear(); 60 | 61 | #endif /* ifndef _kvga_H_ */ 62 | -------------------------------------------------------------------------------- /chapter7/init/kgdt.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2018 Liming,Deng 2 | ;Author: Liming Deng 3 | ; 4 | ;Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | ;this software and associated documentation files (the "Software"), to deal in 6 | ;the Software without restriction, including without limitation the rights to 7 | ;use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | ;the Software, and to permit persons to whom the Software is furnished to do so, 9 | ;subject to the following conditions: 10 | ; 11 | ;The above copyright notice and this permission notice shall be included in all 12 | ;copies or substantial portions of the Software. 13 | ; 14 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | ;FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | ;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | ;IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | ;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | 22 | [global kload_gdt:function] 23 | kload_gdt: 24 | mov eax, [esp + 4] 25 | lgdt [eax] 26 | 27 | mov ax, 0x10 28 | mov ds, ax 29 | mov es, ax 30 | mov fs, ax 31 | mov gs, ax 32 | mov ss, ax 33 | 34 | jmp 0x08:__long_jmp 35 | 36 | __long_jmp: 37 | ret 38 | .end 39 | size kload_gdt __long_jmp.end - kload_gdt 40 | -------------------------------------------------------------------------------- /chapter7/init/kgdt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | 28 | static KSegmentDescritor gdt[GDT_ENTRY_CNT]; 29 | 30 | static void set_segment_descriptor( KSegmentDescritor *sd, u32 base, u32 limit, 31 | u8 access, u8 granularity ); 32 | 33 | void set_segment_descriptor( KSegmentDescritor *sd, u32 base, u32 limit, 34 | u8 access, u8 granularity ) 35 | { 36 | sd->limit_low = limit & 0xffff; 37 | sd->base_low = base & 0xffff; 38 | sd->base_mid = ( base >> 16 ) & 0xff; 39 | sd->access = access; 40 | sd->granularity = ( granularity & 0xf0 ) | ( ( limit >> 16 ) & 0xf ); 41 | sd->base_high = base >> 24; 42 | } 43 | 44 | KGDTPtr kinit_gdt() 45 | { 46 | KGDTPtr gdt_ptr; 47 | gdt_ptr.addr = (u32)gdt; 48 | gdt_ptr.limit = sizeof( gdt ) - 1; 49 | 50 | // Null descritor 51 | set_segment_descriptor( &gdt[NULL_SEG_INDEX], 0x00000000, 0x00000000, 0x00, 52 | 0x00 ); 53 | 54 | // Code segment descritor 55 | set_segment_descriptor( &gdt[CODE_SEG_INDEX], 0x00000000, 0xffffffff, 0x9a, 56 | 0xcf ); 57 | 58 | // Data segment descritor 59 | set_segment_descriptor( &gdt[DATA_SEG_INDEX], 0x00000000, 0xffffffff, 0x92, 60 | 0xcf ); 61 | 62 | // User code segment descritor 63 | set_segment_descriptor( &gdt[USER_CODE_SEG_INDEX], 0x00000000, 0xffffffff, 64 | 0xfa, 0xcf ); 65 | 66 | // User data segment descritor 67 | set_segment_descriptor( &gdt[USER_DATA_SEG_INDEX], 0x00000000, 0xffffffff, 68 | 0xf2, 0xcf ); 69 | 70 | return gdt_ptr; 71 | } 72 | -------------------------------------------------------------------------------- /chapter7/init/kidt.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2018 Liming,Deng 2 | ;Author: Liming Deng 3 | 4 | ;Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | ;this software and associated documentation files (the "Software"), to deal in 6 | ;the Software without restriction, including without limitation the rights to 7 | ;use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | ;the Software, and to permit persons to whom the Software is furnished to do so, 9 | ;subject to the following conditions: 10 | 11 | ;The above copyright notice and this permission notice shall be included in all 12 | ;copies or substantial portions of the Software. 13 | 14 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | ;FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | ;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | ;IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | ;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | [global kload_idt:function] 22 | kload_idt: 23 | cli 24 | mov eax, [esp+4] 25 | lidt [eax] 26 | ret 27 | .end 28 | 29 | size kload_idt kload_idt.end - kload_idt 30 | -------------------------------------------------------------------------------- /chapter7/init/kidt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define ISR_INIT(id) \ 30 | do { \ 31 | set_interrupt_gate(&idt[(id)], (u32)isr##id, GDT_CODE_SELECTOR, 0x8e); \ 32 | } while (0); 33 | 34 | #define IRQ_INIT(id) \ 35 | do { \ 36 | set_interrupt_gate(&idt[(id + 32)], (u32)irq##id, GDT_CODE_SELECTOR, \ 37 | 0x8e); \ 38 | } while (0); 39 | 40 | static KInterrputGate idt[IDT_ENTRY_CNT]; 41 | static int idt_init; 42 | 43 | static void set_interrupt_gate(KInterrputGate *intgt, u32 base, 44 | u16 segment_selector, u8 flags); 45 | 46 | void set_interrupt_gate(KInterrputGate *intgt, u32 base, u16 segment_selector, 47 | u8 flags) { 48 | intgt->base_low = base & 0xffff; 49 | intgt->segment_selector = segment_selector; 50 | intgt->reserve = 0x0; 51 | intgt->flags = flags; // 10001110b 52 | intgt->base_high = (base >> 16) & 0xffff; 53 | } 54 | 55 | KIDTPtr kinit_idt() { 56 | static KIDTPtr idt_ptr; 57 | if (!idt_init) { 58 | idt_ptr.base = (u32)&idt; 59 | idt_ptr.limit = sizeof(idt) - 1; 60 | idt_init = 1; 61 | 62 | // Remap the irq table. 63 | kout(0x20, 0x11, KBYTE); 64 | kout(0xA0, 0x11, KBYTE); 65 | kout(0x21, 0x20, KBYTE); 66 | kout(0xA1, 0x28, KBYTE); 67 | kout(0x21, 0x04, KBYTE); 68 | kout(0xA1, 0x02, KBYTE); 69 | kout(0x21, 0x01, KBYTE); 70 | kout(0xA1, 0x01, KBYTE); 71 | kout(0x21, 0x0, KBYTE); 72 | kout(0xA1, 0x0, KBYTE); 73 | 74 | ISR_INIT(0); 75 | ISR_INIT(1); 76 | ISR_INIT(2); 77 | ISR_INIT(3); 78 | ISR_INIT(4); 79 | ISR_INIT(5); 80 | ISR_INIT(6); 81 | ISR_INIT(7); 82 | ISR_INIT(8); 83 | ISR_INIT(9); 84 | ISR_INIT(10); 85 | ISR_INIT(11); 86 | ISR_INIT(12); 87 | ISR_INIT(13); 88 | ISR_INIT(14); 89 | ISR_INIT(15); 90 | ISR_INIT(16); 91 | ISR_INIT(17); 92 | ISR_INIT(18); 93 | ISR_INIT(19); 94 | ISR_INIT(20); 95 | ISR_INIT(21); 96 | ISR_INIT(22); 97 | ISR_INIT(23); 98 | ISR_INIT(24); 99 | ISR_INIT(25); 100 | ISR_INIT(26); 101 | ISR_INIT(27); 102 | ISR_INIT(28); 103 | ISR_INIT(29); 104 | ISR_INIT(30); 105 | ISR_INIT(31); 106 | 107 | IRQ_INIT(0); 108 | IRQ_INIT(1); 109 | IRQ_INIT(2); 110 | IRQ_INIT(3); 111 | IRQ_INIT(4); 112 | IRQ_INIT(5); 113 | IRQ_INIT(6); 114 | IRQ_INIT(7); 115 | IRQ_INIT(8); 116 | IRQ_INIT(9); 117 | IRQ_INIT(10); 118 | IRQ_INIT(11); 119 | IRQ_INIT(12); 120 | IRQ_INIT(13); 121 | IRQ_INIT(14); 122 | IRQ_INIT(15); 123 | 124 | // System call 125 | ISR_INIT(255); 126 | } 127 | return idt_ptr; 128 | } 129 | -------------------------------------------------------------------------------- /chapter7/init/kisr.asm: -------------------------------------------------------------------------------- 1 | ;Copyright (c) 2018 Liming,Deng 2 | 3 | 4 | 5 | ;Author: Liming Deng 6 | ; 7 | ;Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | ;this software and associated documentation files (the "Software"), to deal in 9 | ;the Software without restriction, including without limitation the rights to 10 | ;use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | ;the Software, and to permit persons to whom the Software is furnished to do so, 12 | ;subject to the following conditions: 13 | ; 14 | ;The above copyright notice and this permission notice shall be included in all 15 | ;copies or substantial portions of the Software. 16 | ; 17 | ;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | ;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | ;FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | ;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | ;IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | ;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | 25 | %macro ISR_ERRCODE 1 26 | [global isr%1:function] 27 | isr%1: 28 | cli 29 | push dword %1 ; Interrupt id 30 | jmp kisr_common_stub 31 | .end 32 | size isr%1 isr%1.end - isr%1 33 | %endmacro 34 | 35 | %macro ISR_NOERRCODE 1 36 | [global isr%1:function] 37 | isr%1: 38 | cli 39 | push dword 0 ; Dummy error code 40 | push dword %1 41 | jmp kisr_common_stub 42 | .end 43 | size isr%1 isr%1.end - isr%1 44 | %endmacro 45 | 46 | %macro IRQ 2 47 | [global irq%1:function] 48 | irq%1: 49 | cli 50 | push dword 0 ; dummy error code 51 | push dword %2 ; push interrupt id 52 | jmp kirq_common_stub 53 | .end 54 | size irq%1 irq%1.end - irq%1 55 | %endmacro 56 | 57 | ISR_NOERRCODE 0 58 | ISR_NOERRCODE 1 59 | ISR_NOERRCODE 2 60 | ISR_NOERRCODE 3 61 | ISR_NOERRCODE 4 62 | ISR_NOERRCODE 5 63 | ISR_NOERRCODE 6 64 | ISR_NOERRCODE 7 65 | 66 | ISR_ERRCODE 8 67 | 68 | ISR_NOERRCODE 9 69 | 70 | ISR_ERRCODE 10 71 | ISR_ERRCODE 11 72 | ISR_ERRCODE 12 73 | ISR_ERRCODE 13 74 | ISR_ERRCODE 14 75 | 76 | ISR_NOERRCODE 15 77 | ISR_NOERRCODE 16 78 | 79 | ISR_ERRCODE 17 80 | 81 | ISR_NOERRCODE 18 82 | ISR_NOERRCODE 19 83 | ISR_NOERRCODE 20 84 | ISR_NOERRCODE 21 85 | ISR_NOERRCODE 22 86 | ISR_NOERRCODE 23 87 | ISR_NOERRCODE 24 88 | ISR_NOERRCODE 25 89 | ISR_NOERRCODE 26 90 | ISR_NOERRCODE 27 91 | ISR_NOERRCODE 28 92 | ISR_NOERRCODE 29 93 | ISR_NOERRCODE 30 94 | ISR_NOERRCODE 31 95 | 96 | ; System call 97 | ISR_NOERRCODE 255 98 | 99 | IRQ 0, 32 100 | IRQ 1, 33 101 | IRQ 2, 34 102 | IRQ 3, 35 103 | IRQ 4, 36 104 | IRQ 5, 37 105 | IRQ 6, 38 106 | IRQ 7, 39 107 | IRQ 8, 40 108 | IRQ 9, 41 109 | IRQ 10, 42 110 | IRQ 11, 43 111 | IRQ 12, 44 112 | IRQ 13, 45 113 | IRQ 14, 46 114 | IRQ 15, 47 115 | 116 | [extern kisr_handler] 117 | kisr_common_stub: 118 | pusha 119 | 120 | mov ax, ds 121 | 122 | push eax 123 | 124 | mov ax, 0x10 ; Kernel data segment selector 125 | mov ds, ax 126 | mov es, ax 127 | mov fs, ax 128 | mov gs, ax 129 | mov ss, ax 130 | 131 | push esp 132 | call kisr_handler 133 | add esp, 4 134 | 135 | pop ebx 136 | mov ds, bx 137 | mov es, bx 138 | mov fs, bx 139 | mov gs, bx 140 | mov ss, bx 141 | 142 | 143 | popa 144 | add esp, 8 145 | iret 146 | 147 | [extern kirq_handler] 148 | kirq_common_stub: 149 | pusha 150 | 151 | mov ax, ds 152 | 153 | push eax 154 | 155 | mov ax, 0x10 ; Kernel data segment selector 156 | mov ds, ax 157 | mov es, ax 158 | mov fs, ax 159 | mov gs, ax 160 | mov ss, ax 161 | 162 | push esp 163 | call kirq_handler 164 | add esp, 4 165 | 166 | pop ebx 167 | mov ds, bx 168 | mov es, bx 169 | mov fs, bx 170 | mov gs, bx 171 | mov ss, bx 172 | 173 | 174 | popa 175 | add esp, 8 176 | iret 177 | -------------------------------------------------------------------------------- /chapter7/init/kisr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | static KInterruptHandler int_handler_pool[IDT_ENTRY_CNT] = {NULL}; 31 | 32 | // Register an interrupt handler function 33 | void kreg_int_handler(u32 int_id, KInterruptHandler handler) 34 | { 35 | int_handler_pool[int_id] = handler; 36 | } 37 | 38 | void kisr_handler(KPTRegs *pt_regs) 39 | { 40 | // If registered 41 | KInterruptHandler handler = int_handler_pool[pt_regs->int_id]; 42 | if (handler) 43 | handler(pt_regs); 44 | else 45 | kcprintf(VGA_BLACK, VGA_RED, "Unhandled interrupt: %d\n", 46 | pt_regs->int_id); 47 | } 48 | 49 | 50 | void kirq_handler(KPTRegs *pt_regs) 51 | { 52 | // Send an EOI (end of interrupt) signal to the PICs. 53 | // If this interrupt involved the slave. 54 | if (pt_regs->int_id >= 40) 55 | kout(0xA0, 0x20, KBYTE); 56 | 57 | // Reset master 58 | kout(0x20, 0x20, KBYTE); 59 | 60 | kisr_handler(pt_regs); 61 | } 62 | 63 | void kcli() 64 | { 65 | __asm__ volatile("cli"); 66 | } 67 | 68 | void ksti() 69 | { 70 | __asm__ volatile("sti"); 71 | } 72 | -------------------------------------------------------------------------------- /chapter7/init/kpit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | #define INPUT_FREQ 0x1234dc 28 | 29 | void kinit_timer(u32 frequency, KInterruptHandler handler) { 30 | kreg_int_handler(IRQ0, handler); 31 | 32 | u32 divisor = INPUT_FREQ / frequency; 33 | kout(0x43, 0x36, KBYTE); 34 | 35 | u8 l = divisor & 0xff; 36 | u8 h = (divisor >> 8) & 0xff; 37 | 38 | kout(0x40, l, KBYTE); 39 | kout(0x40, h, KBYTE); 40 | } 41 | -------------------------------------------------------------------------------- /chapter7/kernel/kmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void hlt() { 11 | while (1) 12 | __asm__ volatile("hlt"); 13 | } 14 | 15 | void timer_handler(KPTRegs *pt_regs) { 16 | static u32 tick_tock = 0; 17 | kcprintf(VGA_BLACK, VGA_LIGHT_BROWN, "tick: %u\n", tick_tock++); 18 | } 19 | 20 | void kmain(KMultiBoot *mb) { 21 | KERNEL_BOOT_INFO = mb; 22 | 23 | KGDTPtr gdt_ptr = kinit_gdt(); 24 | kload_gdt(&gdt_ptr); 25 | 26 | KIDTPtr idt_ptr = kinit_idt(); 27 | kload_idt(&idt_ptr); 28 | 29 | kinit_timer(200, timer_handler); 30 | 31 | __asm__ volatile("sti"); 32 | 33 | kprintf("hello world?\n"); 34 | 35 | hlt(); 36 | } 37 | -------------------------------------------------------------------------------- /chapter7/lib/kdebug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | static KELF kernel_elf; 30 | static const KELF *pkelf = NULL; 31 | 32 | // Define in boot/boot.asm 33 | 34 | static void env_init(); 35 | 36 | void env_init() { 37 | if (pkelf == NULL) { 38 | kernel_elf = kget_kernel_elf_info(KERNEL_BOOT_INFO); 39 | pkelf = &kernel_elf; 40 | } 41 | } 42 | 43 | void kpanic(const char *msg) { 44 | kprintf("****Fatal error eccured****\n" 45 | "****Kernel in panic****\n"); 46 | if (msg) 47 | kprintf("%s\n", msg); 48 | kstack_trace(); 49 | while (1) 50 | ; 51 | } 52 | 53 | void __kassert(const char *file, int line, const char *func, const char *expr) { 54 | kcprintf(VGA_BLACK, VGA_LIGHT_BROWN, 55 | "In file %s: %d function %s asserts '%s' failed\n", file, line, func, 56 | expr); 57 | kpanic(NULL); 58 | } 59 | 60 | void kstack_trace() { 61 | env_init(); 62 | u32 *ebp, *eip; 63 | 64 | // Get %ebp 65 | __asm__ volatile("mov %%ebp,%0" : "=r"(ebp)); 66 | 67 | // %ebp was initiated in boot/boot.asm with 0x0 68 | while (ebp) { 69 | /* 70 | * | -------- | 71 | * | ... | < ---- ebp_prev 72 | * | -------- | 73 | * | . | 74 | * | . | 75 | * | . | 76 | * | -------- | 77 | * | &$ | < ---- call function `x` ($ is the addr of next instruction) 78 | * | -------- | 79 | * | ebp_prev | < ---- push ebp; mov ebp, esp | <= esp , ebp 80 | * | -------- | 81 | */ 82 | eip = ebp + 1; // (void *)eip == (void *)ebp + 4 83 | kprintf("\t[%p]:\t%s\n", *eip - 5, ksearch_function(*eip - 5, pkelf)); 84 | ebp = (u32 *)*ebp; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /chapter7/lib/kelf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | 26 | #define ELF32_ST_TYPE(i) ((i)&0xf) 27 | 28 | // Get kernel elf info 29 | KELF kget_kernel_elf_info(const KMultiBoot* mb) 30 | { 31 | KELFSectionHeader* begin = (KELFSectionHeader*)(mb->addr); 32 | KELF elf; 33 | 34 | u32 shstrtab = begin[mb->shndx].addr ; // Section name array 35 | // Loop through all sections 36 | 37 | const KELFSectionHeader* end = &begin[mb->num]; 38 | for (const KELFSectionHeader* sh = begin; sh < end; ++sh) { 39 | const char* section_name = (const char*)(shstrtab + sh->name); 40 | 41 | if (kstrcmp(section_name, ".strtab") == 0) { 42 | elf.strtab = (const char*)(sh->addr); 43 | elf.strtabsz = sh->size; 44 | continue; 45 | } else if (kstrcmp(section_name, ".symtab") == 0) { 46 | elf.symtab = (KELFSymbol*)(sh->addr); 47 | elf.symtabsz = sh->size; 48 | } 49 | } 50 | return elf; 51 | } 52 | 53 | // Return the name of the function whose address range includes 'addr' 54 | const char* ksearch_function(u32 addr, const KELF* elf) 55 | { 56 | if (elf) { 57 | const KELFSymbol* end = &elf->symtab[elf->symtabsz / sizeof(KELFSymbol)]; 58 | 59 | for (const KELFSymbol* symbol = elf->symtab; symbol < end; ++symbol) 60 | if (ELF32_ST_TYPE(symbol->info) != 0x2) 61 | continue; 62 | else if (addr >= symbol->value && addr < symbol->value + symbol->size) 63 | return (const char*)(elf->strtab + symbol->name); 64 | } 65 | return NULL; 66 | } 67 | -------------------------------------------------------------------------------- /chapter7/lib/kstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Liming,Deng 3 | * Author: Liming Deng 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | 25 | // For the simplicity, we do not apply loop unrolling 26 | 27 | inline void* kmemcpy(void* dst, const void* src, u32 n) 28 | { 29 | const u8* s = (u8*)src; 30 | u8* t = (u8*)dst; 31 | while (n--) 32 | *t++ = *s++; 33 | return dst; 34 | } 35 | 36 | inline void* kmemset(void* s, u8 c, u32 n) 37 | { 38 | u8* m = (u8*)s; 39 | while (n--) 40 | *m++ = c; 41 | return s; 42 | } 43 | 44 | inline void* kbzero(void* s, u32 n) 45 | { 46 | kmemset(s, '\0', n); 47 | return s; 48 | } 49 | 50 | inline i32 kstrcmp(const char* s1, const char* s2) 51 | { 52 | i32 a = 0, b = 0; 53 | do { 54 | a = *s1++; 55 | b = *s2++; 56 | } while (a && b && a == b); 57 | return a - b; 58 | } 59 | 60 | inline i32 kstrncmp(const char* s1, const char* s2, u32 n) 61 | { 62 | i32 a = 0, b = 0; 63 | for (; n && a == b; --n) { 64 | a = *s1++; 65 | b = *s2++; 66 | } 67 | return a - b; 68 | } 69 | 70 | char* kstrcat(char* dst, const char* src) 71 | { 72 | char* t = dst; 73 | while (*t++) 74 | ; 75 | --t; 76 | while (*src) 77 | *t++ = *src++; 78 | return dst; 79 | } 80 | 81 | char* kstrncat(char* dst, const char* src, u32 n) 82 | { 83 | char* t = dst; 84 | while (*t++) 85 | ; 86 | --t; 87 | while (n--) 88 | *t++ = *src++; 89 | *t = '\0'; 90 | return dst; 91 | } 92 | 93 | char* kstrcpy(char* dst, const char* src) 94 | { 95 | char* t = dst; 96 | while (*src) 97 | *t++ = *src++; 98 | *t = '\0'; 99 | return dst; 100 | } 101 | char* kstrncpy(char* dst, const char* src, u32 n) 102 | { 103 | char* t = dst; 104 | u32 i; 105 | for (i = 0; i < n && *src; ++i) 106 | *t++ = *src++; 107 | for (; i < n; ++i) 108 | *t++ = '\0'; 109 | return dst; 110 | } 111 | 112 | u32 kstrlen(const char* s) 113 | { 114 | u32 l = 0; 115 | while (*s++) 116 | ++l; 117 | return l; 118 | } 119 | -------------------------------------------------------------------------------- /chapter7/scripts/gdbinit: -------------------------------------------------------------------------------- 1 | shell qemu-system-i386 -s -S -cdrom build/osmanthus.iso & 2 | symbol-file build/osmanthus 3 | set arch i386:intel 4 | target remote :1234 5 | b __start 6 | b kmain 7 | -------------------------------------------------------------------------------- /chapter7/scripts/grub.cfg: -------------------------------------------------------------------------------- 1 | menuentry "os-name" { 2 | multiboot /boot/kernel-name 3 | } 4 | -------------------------------------------------------------------------------- /chapter7/scripts/link.ld: -------------------------------------------------------------------------------- 1 | ENTRY(__start) 2 | SECTIONS 3 | { 4 | PROVIDE( __kernel_begin_addr = . ); 5 | . = 0x100000; 6 | .text : 7 | { 8 | *(.text) 9 | . = ALIGN(4096); 10 | } 11 | .data : 12 | { 13 | *(.data) 14 | *(.rodata) 15 | . = ALIGN(4096); 16 | } 17 | .bss : 18 | { 19 | *(.bss) 20 | . = ALIGN(4096); 21 | } 22 | .stab : 23 | { 24 | *(.stab) 25 | . = ALIGN(4096); 26 | } 27 | .stabstr : 28 | { 29 | *(.stabstr) 30 | . = ALIGN(4096); 31 | } 32 | PROVIDE( __kernel_end_addr = . ); 33 | 34 | /DISCARD/ : { *(.comment) *(.eh_frame) } 35 | } 36 | -------------------------------------------------------------------------------- /etc/Screenshot from 2018-04-18 09-27-34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iosmanthus/Osmanthus-tutorial/211bdb7eb3d09c67e25b5f75cee3b787c7742be0/etc/Screenshot from 2018-04-18 09-27-34.png -------------------------------------------------------------------------------- /etc/Screenshot from 2018-04-18 11-39-42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iosmanthus/Osmanthus-tutorial/211bdb7eb3d09c67e25b5f75cee3b787c7742be0/etc/Screenshot from 2018-04-18 11-39-42.png -------------------------------------------------------------------------------- /etc/Screenshot from 2018-04-20 09-33-54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iosmanthus/Osmanthus-tutorial/211bdb7eb3d09c67e25b5f75cee3b787c7742be0/etc/Screenshot from 2018-04-20 09-33-54.png -------------------------------------------------------------------------------- /etc/Screenshot from 2018-04-21 09-15-08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iosmanthus/Osmanthus-tutorial/211bdb7eb3d09c67e25b5f75cee3b787c7742be0/etc/Screenshot from 2018-04-21 09-15-08.png -------------------------------------------------------------------------------- /etc/Screenshot from 2018-04-22 12-53-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iosmanthus/Osmanthus-tutorial/211bdb7eb3d09c67e25b5f75cee3b787c7742be0/etc/Screenshot from 2018-04-22 12-53-01.png -------------------------------------------------------------------------------- /etc/Screenshot from 2018-04-22 16-48-51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iosmanthus/Osmanthus-tutorial/211bdb7eb3d09c67e25b5f75cee3b787c7742be0/etc/Screenshot from 2018-04-22 16-48-51.png --------------------------------------------------------------------------------