Переглянути джерело

添加 makefile 配置, make 编译

simon 1 рік тому
батько
коміт
b48c5ce031
11 змінених файлів з 237 додано та 105 видалено
  1. 51 1
      README.md
  2. 0 87
      build.sh
  3. 0 4
      clean.sh
  4. 27 0
      kernel/debug.c
  5. 25 0
      kernel/debug.h
  6. 1 1
      kernel/init.c
  7. 1 1
      kernel/init.h
  8. 46 0
      kernel/interrupt.c
  9. 0 9
      kernel/interrupt.h
  10. 5 2
      kernel/main.c
  11. 81 0
      makefile

+ 51 - 1
README.md

@@ -1,3 +1,53 @@
 # os_kernel
 
-An OS kernel for study
+An OS kernel for study
+
+make 编译过程
+
+`make all` `make run` `make clean`
+
+```sh
+(base) ➜  os_kernel git:(master) ✗ make mk_dir
+(base) ➜  os_kernel git:(master) ✗ make mbr
+nasm -I boot/include/ boot/mbr.S -o Build/bin/mbr.bin
+(base) ➜  os_kernel git:(master) ✗ make loader
+nasm -I boot/include/ boot/loader.S -o Build/bin/loader.bin
+(base) ➜  os_kernel git:(master) ✗ make kernel
+i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/main.c -o Build/main.o
+i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/init.c -o Build/init.o
+i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/interrupt.c -o Build/interrupt.o
+i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes device/timer.c -o Build/timer.o
+nasm -f elf kernel/kernel.S -o Build/kernel.o
+nasm -f elf lib/kernel/print.S -o Build/print.o
+i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/debug.c -o Build/debug.o
+i386-elf-ld -Ttext 0xc0001500 -e main Build/main.o Build/init.o Build/interrupt.o Build/timer.o Build/kernel.o Build/print.o Build/debug.o -o Build/bin/kernel.bin
+(base) ➜  os_kernel git:(master) ✗ make create_img
+bximage -q -func=create -hd=30M ./hd30M.img
+========================================================================
+                                bximage
+  Disk Image Creation / Conversion / Resize and Commit Tool for Bochs
+                                  $Id$
+========================================================================
+
+The disk image './hd30M.img' already exists.  Are you sure you want to replace it?
+Please type yes or no. [no] yes
+
+Creating hard disk image './hd30M.img' with CHS=60/16/63 (sector size = 512)
+
+The following line should appear in your bochsrc:
+  ata0-master: type=disk, path="./hd30M.img", mode=flat
+(base) ➜  os_kernel git:(master) ✗ make hd
+dd if=./Build/bin/mbr.bin of=./hd30M.img bs=512 count=1 conv=notrunc
+1+0 records in
+1+0 records out
+512 bytes transferred in 0.001023 secs (500462 bytes/sec)
+dd if=./Build/bin/loader.bin of=./hd30M.img bs=512 count=4 seek=2 conv=notrunc
+2+1 records in
+2+1 records out
+1462 bytes transferred in 0.002619 secs (558222 bytes/sec)
+dd if=./Build/bin/kernel.bin of=./hd30M.img bs=512 count=200 seek=9 conv=notrunc
+16+1 records in
+16+1 records out
+8418 bytes transferred in 0.000408 secs (20635682 bytes/sec)
+(base) ➜  os_kernel git:(master) ✗ make run
+```

+ 0 - 87
build.sh

@@ -1,87 +0,0 @@
-#!/bin/sh
-
-directory="build/bin"
-if [ ! -d "$directory" ]; then
-    mkdir -p $directory
-fi
-
-echo "Compiling mbr..."
-nasm -I boot/include/ -o $directory/mbr.bin boot/mbr.S
-if [ $? -eq 0 ]; then
-    echo "MBR compiled successfully."
-else
-    echo "MBR compiled failed."
-    exit
-fi
-echo "Compiling loader..."
-nasm -I boot/include/ -o $directory/loader.bin boot/loader.S
-if [ $? -eq 0 ]; then
-    echo "Bootloader compiled successfully."
-else
-    echo "Bootloader compiled failed."
-    exit
-fi
-echo "Compiling kernel..."
-directory="build"
-if [ ! -d "$directory" ]; then
-    mkdir $directory
-fi
-i386-elf-gcc -I lib/ -I lib/kernel/ -c -fno-builtin -o build/timer.o device/timer.c
-i386-elf-gcc -I ./lib/ -I lib/kernel/ -I kernel/ -c -fno-builtin -o build/main.o kernel/main.c
-nasm -f elf -o build/print.o lib/kernel/print.S
-nasm -f elf -o build/kernel.o kernel/kernel.S
-
-i386-elf-gcc -I lib/kernel/ -I ./lib/ -I kernel/ -c -fno-builtin -o build/interrupt.o kernel/interrupt.c
-i386-elf-gcc -I lib/kernel/ -I ./lib/ -I kernel/ -c -fno-builtin -o build/init.o kernel/init.c
-
-directory="build/bin"
-if [ ! -d "$directory" ]; then
-    mkdir $directory
-fi
-i386-elf-ld -Ttext 0xc0001500 -e main -o $directory/kernel.bin build/main.o build/init.o build/interrupt.o build/print.o build/kernel.o build/timer.o
-
-if [ $? -eq 0 ]; then
-    echo "Kernel compiled successfully."
-else
-    echo "Kernel compiled failed."
-    exit
-fi
-
-echo "Creating disk image..."
-bximage -q -func=create -hd=30M hd30M.img
-if [ $? -eq 0 ]; then
-    echo "Disk image created successfully."
-else
-    echo "Disk image created failed."
-    exit
-fi
-
-echo "Installing to disk image..."
-echo " 0. Writing mbr to disk..."
-dd if=$directory/mbr.bin of=hd30M.img bs=512 count=1 conv=notrunc
-if [ $? -eq 0 ]; then
-    echo "Install mbr to disk image successfully."
-else
-    echo "Install mbr to disk image failed."
-    exit
-fi
-echo " 1. Writing loader to disk..."
-dd if=$directory/loader.bin of=hd30M.img bs=512 count=4 seek=2 conv=notrunc
-if [ $? -eq 0 ]; then
-    echo "Install loader to disk image successfully."
-else
-    echo "Install loader to disk image failed."
-    exit
-fi
-echo " 2. Writing kernel to disk..."
-dd if=$directory/kernel.bin of=hd30M.img bs=512 count=200 seek=9 conv=notrunc
-
-if [ $? -eq 0 ]; then
-    echo "Install kernel to disk image successfully."
-else
-    echo "Install kernel to disk image failed."
-    exit
-fi
-
-# echo "Now starting bochs ..."
-# bochs -f bochsrc -q

+ 0 - 4
clean.sh

@@ -1,4 +0,0 @@
-#!/bin/sh
-
-rm -rf bochs_log.txt hd30M.img *.bin
-rm -rf build

+ 27 - 0
kernel/debug.c

@@ -0,0 +1,27 @@
+#include "debug.h"
+#include "interrupt.h"
+#include "../lib/kernel/print.h"
+
+// 打印文件名、行号、函数名、条件并使程序悬停
+void panic_spin(char *filename, int line, const char *func, const char *condition)
+{
+    intr_disable(); // 关中断
+
+    put_str("\n\n\n!!! error !!!\n");
+    put_str("Kernel panic at :\n");
+    put_str("filename: ");
+    put_str(filename);
+    put_str("\n");
+    put_str("line: 0x");
+    put_int(line);
+    put_str("\n");
+    put_str("function: ");
+    put_str((char *)func);
+    put_str("\n");
+    put_str("condition: ");
+    put_str((char *)condition);
+    put_str("\n");
+    put_str("Halting...\n");
+    while (1)
+        ;
+}

+ 25 - 0
kernel/debug.h

@@ -0,0 +1,25 @@
+#ifndef __KERNEL_DEBUG_H
+#define __KERNEL_DEBUG_H
+void panic_spin(char *filename, int line, const char *func, const char *condition);
+
+/**
+ * @brief  panic 是一个宏,__VA_ARGS__ 表示可变参数,即 ...,用于传递参数
+ * __VA_ARGS__ 是预处理器所支持的专用标识符。代表所有与省略号相对应的参数
+ * “...” 表示定义的宏其参数可变
+ */
+#define PANIC(...) panic_spin(__FILE__, __LINE__, __func__, __VA_ARGS__)
+
+#ifdef NDEBUG
+#define ASSERT(CONDITION) ((void)0)
+#else
+#define ASSERT(CONDITION)  \
+    if (CONDITION)         \
+    {                      \
+    }                      \
+    else                   \
+    {                      \
+        PANIC(#CONDITION); \
+    }
+#endif // NDEBUG
+
+#endif // __KERNEL_DEBUG_H

+ 1 - 1
kernel/init.c

@@ -3,7 +3,7 @@
 #include "interrupt.h"
 #include "../device/timer.h"
 
-void init_all()
+void init_all(void)
 {
     put_str("init_all\n");
     itd_init();   // 初始化中断

+ 1 - 1
kernel/init.h

@@ -1,6 +1,6 @@
 #ifndef __KERNEL_INIT_H
 #define __KERNEL_INIT_H
 
-void init_all();
+void init_all(void);
 
 #endif // __KERNEL_INIT_H

+ 46 - 0
kernel/interrupt.c

@@ -7,6 +7,11 @@
 char *intr_name[IDT_DESC_CNT];        // 用于保存异常的名字
 intr_handler idt_table[IDT_DESC_CNT]; // 中断处理函数数组
 
+#define EFLAGS_IF 0x200 // eflags寄存器中的if位为1
+#define GET_EFLAGS(EFLAG_VAR) asm volatile("pushfl; popl %0" : "=g"(EFLAG_VAR))
+
+static gate_desc idt[IDT_DESC_CNT]; // 中断描述符表,本质上就是个中断门描述符数组
+
 /*创建中断门描述符*/
 static void make_idt_desc(gate_desc *p_gdesc, uint8_t attr, intr_handler function)
 {
@@ -106,4 +111,45 @@ void itd_init(void)
     uint64_t idt_operand = ((sizeof(idt) - 1) | ((uint64_t)((uint32_t)idt << 16)));
     asm volatile("lidt %0" ::"m"(idt_operand));
     put_str("itd_init done\n");
+}
+
+enum intr_status intr_get_status(void)
+{
+    uint32_t eflags = 0;
+    GET_EFLAGS(eflags);
+    return (EFLAGS_IF & eflags) ? INTR_ON : INTR_OFF;
+}
+enum intr_status intr_set_status(enum intr_status status)
+{
+    return status & INTR_ON ? intr_enable() : intr_disable();
+}
+enum intr_status intr_enable(void)
+{
+    enum intr_status old_status;
+    if (INTR_ON == intr_get_status())
+    {
+        old_status = INTR_ON;
+        return old_status;
+    }
+    else
+    {
+        old_status = INTR_OFF;
+        asm volatile("sti"); // 开中断, sti 指令将IF位置1
+        return old_status;
+    }
+}
+enum intr_status intr_disable(void)
+{
+    enum intr_status old_status;
+    if (INTR_ON == intr_get_status())
+    {
+        old_status = INTR_ON;
+        asm volatile("cli" : : : "memory"); // 关中断, cli 指令将IF位置0
+        return old_status;
+    }
+    else
+    {
+        old_status = INTR_OFF;
+        return old_status;
+    }
 }

+ 0 - 9
kernel/interrupt.h

@@ -40,16 +40,7 @@ typedef struct
     uint16_t offset_high; // 16 位 偏移量的高 16 位 (16..31)
 } __attribute__((packed)) gate_desc;
 
-static void make_idt_desc(gate_desc *p_gdesc, uint8_t attr, intr_handler function);
-static void itd_desc_init(void);
-
-static gate_desc idt[IDT_DESC_CNT]; // 中断描述符表,本质上就是个中断门描述符数组
 // 定义中断处理程序数组.在 kernel.S 中定义的intrXXentry只是中断处理程序的入口,最终调用的是ide_table中的处理程序
 extern intr_handler intr_entry_table[IDT_DESC_CNT];
 
-// 通用的中断处理函数,一般用在异常出现时的处理
-static void general_intr_handler(uint8_t vec_nr);
-// 完成一般中断处理函数注册及异常名称注册
-static void exception_init(void);
-
 #endif // __KERNEL_INTERRUPT_H

+ 5 - 2
kernel/main.c

@@ -1,11 +1,14 @@
-#include "print.h"
+#include "../lib/kernel/print.h"
+#include "debug.h"
 #include "init.h"
 
 int main(void)
 {
     put_str("I am kernel\n");
     init_all();
-    asm volatile("sti"); // 使能中断
+    // asm volatile("sti"); // 使能中断
+    ASSERT(1 == 2);
+
     while (1)
         ;
     return 0;

+ 81 - 0
makefile

@@ -0,0 +1,81 @@
+BUID_O_DIR = ./build
+BUILD_BIN_DIR = $(BUID_O_DIR)/bin
+ENTRY_POINT = 0xc0001500
+DIS_IMG = ./hd30M.img
+AS = nasm
+CC = i386-elf-gcc
+LD = i386-elf-ld
+LIB = -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/
+BOOTLIB = -I boot/include/
+ASFLAGS = -f elf
+CFLAGS = -Wall $(LIB) -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes
+LDFLAGS = -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_BIN_DIR)/kernel.map
+OBJS = $(BUID_O_DIR)/main.o $(BUID_O_DIR)/init.o $(BUID_O_DIR)/interrupt.o  \
+	$(BUID_O_DIR)/timer.o $(BUID_O_DIR)/kernel.o $(BUID_O_DIR)/print.o   \
+	$(BUID_O_DIR)/debug.o
+
+################################ C 代码编译 ################################
+$(BUID_O_DIR)/main.o: kernel/main.c lib/kernel/print.h lib/stdint.h kernel/init.h
+	$(CC) $(CFLAGS) $< -o $@
+
+$(BUID_O_DIR)/init.o: kernel/init.c kernel/init.h lib/kernel/print.h lib/stdint.h kernel/interrupt.h device/timer.h
+	$(CC) $(CFLAGS) $< -o $@
+
+$(BUID_O_DIR)/interrupt.o: kernel/interrupt.c lib/stdint.h kernel/interrupt.h kernel/global.h lib/kernel/print.h
+	$(CC) $(CFLAGS) $< -o $@
+
+$(BUID_O_DIR)/timer.o: device/timer.c lib/stdint.h device/timer.h kernel/interrupt.h lib/kernel/io.h lib/kernel/print.h
+	$(CC) $(CFLAGS) $< -o $@
+
+$(BUID_O_DIR)/debug.o: kernel/debug.c kernel/debug.h lib/kernel/print.h lib/stdint.h kernel/interrupt.h
+	$(CC) $(CFLAGS) $< -o $@
+
+################################ 汇编代码编译 ################################
+$(BUID_O_DIR)/kernel.o: kernel/kernel.S
+	$(AS) $(ASFLAGS) $< -o $@
+
+$(BUID_O_DIR)/print.o: lib/kernel/print.S
+	$(AS) $(ASFLAGS) $< -o $@
+
+$(BUILD_BIN_DIR)/mbr.bin: boot/mbr.S
+	$(AS) $(BOOTLIB) $< -o $@
+
+$(BUILD_BIN_DIR)/loader.bin: boot/loader.S
+	$(AS) $(BOOTLIB) $< -o $@
+
+################################ 链接所有目标文件 ################################
+$(BUILD_BIN_DIR)/kernel.bin: $(OBJS)
+	$(LD) $(LDFLAGS) $^ -o $@
+
+
+.PHONY:clean mk_dir mbr loader kernel create_img hd run all
+
+mk_dir:
+	@if [ ! -d $(BUID_O_DIR) ]; then mkdir $(BUID_O_DIR); fi
+	@if [ ! -d $(BUILD_BIN_DIR) ]; then mkdir $(BUILD_BIN_DIR); fi
+
+################################ 创建 DIS_IMG ################################
+create_img:
+	bximage -q -func=create -hd=30M $(DIS_IMG)
+
+hd:
+	dd if=$(BUILD_BIN_DIR)/mbr.bin of=$(DIS_IMG) bs=512 count=1 conv=notrunc
+	dd if=$(BUILD_BIN_DIR)/loader.bin of=$(DIS_IMG) bs=512 count=4 seek=2 conv=notrunc
+	dd if=$(BUILD_BIN_DIR)/kernel.bin of=$(DIS_IMG) bs=512 count=200 seek=9 conv=notrunc
+
+clean:
+	cd $(BUID_O_DIR) && rm -rf ./*
+	rm -rf $(BUID_O_DIR)
+	rm -rf $(DIS_IMG)
+	rm -rf bochs_log.txt
+
+kernel: $(BUILD_BIN_DIR)/kernel.bin
+
+mbr: $(BUILD_BIN_DIR)/mbr.bin
+
+loader: $(BUILD_BIN_DIR)/loader.bin
+
+run:
+	bochs -f bochsrc -q
+
+all: mk_dir create_img mbr loader kernel hd