Hello I'm trying to make a simple os, and I'm currently trying to do double buffering.
I have two arrays in the size of the screen and a function that copy the array that currently is being used to the memory of the screen and then swap the being used array to the second one.
And there is a function that clear the screen and set it to a specific color.

screen.c

static u8 *BUFFER = (u8*) 0xA0000;

u8 buffers[2][SCREEN_SIZE];
u8 current_buffer = 0;

#define CURRENT     (buffers[current_buffer])
#define SWAP()      (current_buffer = 1 - current_buffer)

void screen_swap(){
    memcpy(BUFFER, CURRENT, SCREEN_SIZE);
    SWAP();
}

void clear_screen(u8 color){                  // set all the memory of the screen to one color
    memset(&CURRENT, color, SCREEN_SIZE);    
}

memory.c

void memset(void* src, u8 val, u32 len){
    u8* ptr = (u8*)src;
    while(len--){
        *ptr++ = val;
    }
}

void* memcpy(void* dst, void* src, u32 len){
    u8 *d = (u8*)dst;
    const u8 *s = (const u8*)src;
    
    while (len-- > 0){
        *d++ = *s++;
    }
    return dst;
}

当我try 运行这些功能时,系统一直在重新启动.例如:

    clear_screen(COLOR(0,0,255));
    screen_swap();

链接到我的github repo更多的背景

推荐答案

TL;DR的意思是你正在炸毁你的程序堆栈.

我使用宏添加了一些调试printf调用:dbgprt

  1. 堆栈地址是0x7be8(在进入内核main时)
  2. &buffers[0][0]是0x5f60
  3. SCREEN_SIZE是0xfa00
  4. buffers的地址范围为0x5f60-0x1f960
  5. 当我们在buffers上做memset时,我们写的远远超出堆栈的地址.

所讨论的堆栈地址(即0x7be8)是 bootstrap 过程中使用的堆栈地址.在main.asm中,这是通过以下方式设置的:

    mov sp, 0x7C00              ; stack grows downwards from where we are loaded in memory

值为jmpToKernel时,我们需要将esp寄存器设置为不与任何内容冲突的值(例如:

    mov esp,0x90000

以下是make run份报告的[编辑]结果:

# qemu-system-i386 -serial file:serial.log -fda build/os-image.img
###qemu-system-i386 -serial stdio -fda build/os-image.img
qemu-system-i386 -serial stdio -fda build/os-image.img
WARNING: Image format was not specified for 'build/os-image.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Unhandled IRQ 0

set_pallette: ENTER
set_pallette: EXIT
SCREEN_SIZE=fa00
STACK=7be8
screen_swap: ENTER
screen_swap: BUFFER=0xa0000 current_buffer=0/0x5f60/0x15960
screen_swap: EXIT
clear_screen: ENTER color=0x1c
clear_screen: BUFFER=0xa0000 current_buffer=1/0x15960/0x25360
clear_screen: EXIT
screen_swap: ENTER
screen_swap: BUFFER=0xa0000 current_buffer=1/0x15960/0x25360
screen_swap: EXIT
clear_screen: ENTER color=0x1c
clear_screen: BUFFER=0xa0000 current_buffer=0/0x5f60/0x15960
qemu-system-i386: Trying to execute code outside RAM or ROM at 0x1c1c1c1c
This usually means one of the following happened:

(1) You told QEMU to execute a kernel for the wrong machine type, and it crashed on startup (eg trying to run a raspberry pi kernel on a versatilepb QEMU machine)
(2) You didn't give QEMU a kernel or BIOS filename at all, and QEMU executed a ROM full of no-op instructions until it fell off the end
(3) Your guest kernel has a bug and crashed by jumping off into nowhere

This is almost always one of the first two, so check your command line and that you are using the right type of kernel for this machine.
If you think option (3) is likely then you can try debugging your guest with the -d debug options; in particular -d guest_errors will cause the log to include a dump of the guest register state at this point.

Execution cannot continue; stopping here.

make: *** [Makefile:37: run] Error 1

以下是我改变的git diff分:

Edit:%的人为了空间而删除了这个.请参阅下面的更新.


UPDATE:

我添加了mov esp, 0x90000,现在我只能写入第二个缓冲区->;buffers[1].在内存中是否有不同的位置可以放置堆栈,或者如何存储不在堆栈中的缓冲区? 内塔·科恩

当然了.我只是从我的另一个"构建你自己的操作系统"的答案中得到了这个答案:How can I fix my VBE implementation for my OS?

这是一种黑客行为[以及原著作者正在做的事情].

起初,我打算使用make过程来定义boot.asm的地址.然后,我意识到一个更好的方法是让_startkernel_entry.asm设置它.

  1. 通常的方法是探测内存并获取其大小.然后,将堆栈指针指向RAM中的最后一个可用字.
  2. 但是,以这种方式探测并捕获保护异常或总线错误在此阶段实现起来有点棘手.
  3. 因此,使用在kernel_entry.asm中定义的静态数组是最简单的方法.

在这样做的过程中,我仍然有一些麻烦,所以我更改了一些不相关的东西来改进调试:

  1. 更改了类似printf的函数以允许(例如%d%ld%lld)支持int/long/long long个数字(这样我就可以打印计时器值).
  2. printf更改为使用stdarg.h
  3. 将"debounce "代码添加到main,这样它只会在初始按键时更改背景 colored颜色 (例如,上升沿).

以下是代码的"无崩溃"版本:

diff --git a/Makefile b/Makefile
index 193cb35..e4cb5fa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,24 @@
+# tetos/Makefile -- make file for tetos
+#
+# SO: osdev double buffering rebooting system
+# SITE: stackoverflow.com
+# SO: 77524100
+include ./common.mk
 ASM=nasm
-CC=/home/neta/opt/cross/bin/i386-elf-gcc
-LD=/home/neta/opt/cross/i386-elf/bin/ld
 RM=rm
 OBJCOPY=objcopy
-
 SRC=src
-BUILD=build
+export BUILD=build
+
+IMGCOUNT = 2880
+KNLCOUNT = 2048

+all: $(BUILD)/os-image.img

 $(BUILD)/os-image.img: boot kernel
-   dd if=/dev/zero of=$@ bs=512 count=2880
+   dd if=/dev/zero of=$@ bs=512 count=$(IMGCOUNT)
    dd if=$(BUILD)/boot.bin of=$@ conv=notrunc bs=512 count=1 seek=0
-   dd if=$(BUILD)/kernel.bin of=$@ conv=notrunc bs=512 count=2048 seek=1
+   dd if=$(BUILD)/kernel.bin of=$@ conv=notrunc bs=512 count=$(KNLCOUNT) seek=1

 boot: $(BUILD)/boot.bin
@@ -31,6 +38,7 @@ always:

 run: $(BUILD)/os-image.img
    # qemu-system-i386 -serial file:serial.log -fda $<
+   ###qemu-system-i386 -serial stdio -fda $<
    qemu-system-i386 -serial stdio -fda $<

 debug: $(BUILD)/os-image.img
@@ -38,6 +46,7 @@ debug: $(BUILD)/os-image.img
    # for logs -- log: bochslog.txt

 clean:
-   @$(MAKE) -C $(SRC)/boot BUILD=$(abspath $(BUILD)) clean
-   @$(MAKE) -C $(SRC)/kernel BUILD=$(abspath $(BUILD)) clean
+   rm -fr $(BUILD)
+   @###$(MAKE) -C $(SRC)/boot BUILD=$(abspath $(BUILD)) clean
+   @###$(MAKE) -C $(SRC)/kernel BUILD=$(abspath $(BUILD)) clean

diff --git a/common.mk b/common.mk
new file mode 100644
index 0000000..f0f2b8b
--- /dev/null
+++ b/common.mk
@@ -0,0 +1,18 @@
+# common.mk -- common definitions for make
+
+CC:=/home/neta/opt/cross/bin/i386-elf-gcc
+LD:=/home/neta/opt/cross/i386-elf/bin/ld
+
+ifeq ($(wildcard $(CC)*),)
+  CC:=gcc -m32
+  LD:=ld -melf_i386
+endif
+
+export CC
+export LD
+
+IMGCOUNT = 2880
+KNLCOUNT = 2048
+
+###OBJ := obj
+OBJ := o
diff --git a/src/boot/Makefile b/src/boot/Makefile
index 4c9a266..c6d6f8d 100644
--- a/src/boot/Makefile
+++ b/src/boot/Makefile
@@ -1,12 +1,15 @@
+include ../../common.mk
 BUILD?=build/
 ASM?=nasm

+###AFLAGS += -DKSTACK_SECTOR=$(KNLCOUNT)
+
 .PHONY: all clean

 all: $(BUILD)/boot.bin

 $(BUILD)/boot.bin: main.asm
-   $(ASM) main.asm -f bin -o $(BUILD)/boot.bin
+   $(ASM) main.asm -f bin -o $(BUILD)/boot.bin -l $(BUILD)/boot.lst $(AFLAGS)

 clean:
    rm -f $(BUILD)/boot.bin
diff --git a/src/boot/main.asm b/src/boot/main.asm
index 9a37335..8cc8d06 100644
--- a/src/boot/main.asm
+++ b/src/boot/main.asm
@@ -51,8 +51,7 @@ jmpToKernel:
     mov ds, ax
     mov ss, ax

-    call KERNEL_OFFSET
-    hlt
+    jmp KERNEL_OFFSET

 bits 16
 EnableA20:
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index 7bf9326..1e1f7a4 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -1,38 +1,43 @@
+include ../../common.mk
 BUILD?=build/
 ASM?=nasm
 ASMFLAGS?=-f elf
-CC?=/home/neta/opt/cross/bin/i386-elf-gcc
-LD=/home/neta/opt/cross/bin/i386-elf-ld
-LGCC=/home/neta/opt/cross/lib/gcc/i386-elf/13.1.0
+###CC?=/home/neta/opt/cross/bin/i386-elf-gcc
+###LD=/home/neta/opt/cross/bin/i386-elf-ld
+###LGCC=-L /home/neta/opt/cross/lib/gcc/i386-elf/13.1.0
 # CCFLAGS= -ffreestanding -nostdlib -c
-CCFLAGS=-m32 -std=c11 -O2 -g -Wall -Wextra -Wpedantic -Wstrict-aliasing
+CCFLAGS+=-m32 -std=c11 -O2 -g -Wall -Wextra
+CCFLAGS+=-Werror
+###CCFLAGS+=-Wpedantic -Wstrict-aliasing
 CCFLAGS+=-Wno-pointer-arith -Wno-unused-parameter
-CCFLAGS+=-nostdlib -nostdinc -ffreestanding -fno-pie -fno-stack-protector
+CCFLAGS+=-nostdlib -ffreestanding -fno-pie -fno-stack-protector
+###CCFLAGS+=-nostdinc
 CCFLAGS+=-fno-builtin-function -fno-builtin -c -mgeneral-regs-only
-LDFLAGS=-ffreestanding -O2 -nostdlib -m32 -L $(LGCC) -lgcc
+LDFLAGS=-ffreestanding -O2 -nostdlib -m32 $(LGCC) -lgcc

 SOURCES_C=$(wildcard *.c)
 SOURCES_ASM=$(wildcard *.asm)
-OBJECTS_C=$(patsubst %.c,$(BUILD)/kernel/c/%.obj,$(SOURCES_C))
-OBJECTS_ASM=$(patsubst %.asm,$(BUILD)/kernel/asm/%.obj,$(SOURCES_ASM))
+OBJECTS_C=$(patsubst %.c,$(BUILD)/kernel/c/%.$(OBJ),$(SOURCES_C))
+OBJECTS_ASM=$(patsubst %.asm,$(BUILD)/kernel/asm/%.$(OBJ),$(SOURCES_ASM))

 .PHONY: all clean always

-all: kernel.bin
+all: always kernel.bin

 kernel.bin: $(OBJECTS_ASM) $(OBJECTS_C)
-   $(CC) -T link.ld -o $(BUILD)/kernel.bin $^ $(LDFLAGS)
-   # $(LD) -o $(BUILD)/kernel.bin $(LDFLAGS) -Tlink.ld $^
+   @###$(CC) -T link.ld -o $(BUILD)/kernel.bin $^ $(LDFLAGS)
+   $(CC) -Wl,-Map=$(BUILD)/kernel.map -T link.ld -o $(BUILD)/kernel.bin $^ $(LDFLAGS)
+   @# $(LD) -o $(BUILD)/kernel.bin $(LDFLAGS) -Tlink.ld $^

-$(BUILD)/kernel/c/%.obj: %.c always
+$(BUILD)/kernel/c/%.$(OBJ): %.c ###always
    $(CC) $(CCFLAGS) -o $@ $<

-$(BUILD)/kernel/asm/%.obj: %.asm always
-   $(ASM) $(ASMFLAGS) -o $@ $<
+$(BUILD)/kernel/asm/%.$(OBJ): %.asm ###always
+   $(ASM) $(ASMFLAGS) -o $@ $< -l $(basename $@).lst

 always:
    mkdir -p $(BUILD)/kernel/c
    mkdir -p $(BUILD)/kernel/asm

 clean:
-   rm -f $(BUILD)/kernel.bin
+   rm -f $(BUILD)/kernel.bin $(BUILD)/kernel.map
diff --git a/src/kernel/hal.c b/src/kernel/hal.c
index 1b5a7b1..433447c 100644
--- a/src/kernel/hal.c
+++ b/src/kernel/hal.c
@@ -7,13 +7,15 @@
 #include "keyboard.h"

 void HAL_init(){
+    init_serial();              // init the COM1 port (for qemu and bochs)
+
     IDT_init();                 // init the IDT
     ISR_init();                 // init the ISR's
     IRQ_init();                 // init the IRQ's and pic
     timer_install();            // register timer in irq
+#if 1
     keybrd_install();           // register keyboard in irq
-
-    init_serial();              // init the COM1 port (for qemu and bochs)
+#endif

     write_serial('\n');         // print a new line to seperate the qemu things

diff --git a/src/kernel/irq.c b/src/kernel/irq.c
index d3ac3fa..6140a4d 100644
--- a/src/kernel/irq.c
+++ b/src/kernel/irq.c
@@ -10,7 +10,9 @@ void IRQ_handler(Registers_t *regs){
     u8 irq = regs->interrupt - PIC_OFFSET;

     if (g_IRQHandlers[irq] != 0){
+        //dbgprt("IRQ_handler: ENTER irq=%u\n",irq);
         g_IRQHandlers[irq](regs);
+        //dbgprt("IRQ_handler: EXIT\n");
     } else {
         QemuPrintf("Unhandled IRQ %d\n", irq);
     }
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 7136655..4dbf35a 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -9,19 +9,62 @@
 void main(){
     HAL_init();
     set_palette();
+    dbgprt("SCREEN_SIZE=0x%x\n",SCREEN_SIZE);
+    dbgprt("STACK=0x%x\n",__builtin_frame_address(0));

     screen_swap();
+#if 0
     clear_screen(COLOR(0,0,0));
+#else
+    clear_screen(COLOR(0,255,0));
+#endif
     screen_swap();
+    clear_screen(COLOR(0,255,0));
+    screen_swap();
+
+   u64 otimer = get_timer();
+   dbgprt("main: OTIMER otimer=%llu\n",otimer);
+
+   u32 kcount = 0;
+   u8 color = 0;
+   bool kpress_old = 0;
+   bool kpress_cur = 0;
+
+    while (true) {
+       //dbgprt("main: ENTER/GTIMER\n");
+       u64 ctimer = get_timer();
+       //dbgprt("main: EXIT/GTIMER\n");

-    while (true){
-        if (is_key_pressed('a')){
-            clear_screen(COLOR(255,0,0));
+       if (ctimer != otimer) {
+           //dbgprt("\rmain: CTIMER %llu\n",ctimer);
+           otimer = ctimer;
+       }
+
+        kpress_cur = is_key_pressed('a');
+
+       if ((kpress_cur != kpress_old) && kpress_cur) {
+           dbgprt("\n");
+           dbgprt("main: KTIMER kcount=%u ctimer=%llu\n",ctimer);
+           switch (kcount % 3) {
+           case 0:
+               color = COLOR(255,0,0);
+               break;
+           case 1:
+               color = COLOR(0,255,0);
+               break;
+           default:
+               color = COLOR(0,0,255);
+               break;
+           }
+           ++kcount;
+            clear_screen(color);
             screen_swap();
         }
+
+       kpress_old = kpress_cur;
     }

-    while(1){
+    while (1) {
         __asm__ volatile("hlt");
     }
 }
diff --git a/src/kernel/kernel_entry.asm b/src/kernel/kernel_entry.asm
index d9a22bf..8e3e9c7 100644
--- a/src/kernel/kernel_entry.asm
+++ b/src/kernel/kernel_entry.asm
@@ -1,8 +1,31 @@
 [bits    32]
 [extern main]

+KSTACK_SIZE        equ     64 * 1024       ; stack size 64 KB
+
+extern __end
+
 section .entry
 global _start
 _start:
+   ;;;mov      esp,__end               ; this didn't work too well
+   mov     esp,__stack                 ; point to start of stack
+
+   add     esp,KSTACK_SIZE             ; point past the end
+
+   ; get mask to align to 16 byte boundary
+   mov     eax,0x0f
+   not     eax
+
+   ; align stack
+   and     esp,eax
+
+   ; point stack pointer to last valid part of stack
+   sub     esp,16
+
     call main
     hlt
+
+section .bss
+__stack:
+   times KSTACK_SIZE   db 0
diff --git a/src/kernel/keyboard.h b/src/kernel/keyboard.h
index 8091212..8476a61 100644
--- a/src/kernel/keyboard.h
+++ b/src/kernel/keyboard.h
@@ -88,6 +88,7 @@ enum KEYBOARD_SPECIAL_KEYS {
     DOWN               = 0x80
 };

+void keybrd_install();
 bool is_special_key(u8 key);                // check in mode if key is pressed
 bool is_key_pressed(u8 key);                // check if key is pressed

diff --git a/src/kernel/printf.c b/src/kernel/printf.c
index 435d799..af5f85e 100644
--- a/src/kernel/printf.c
+++ b/src/kernel/printf.c
@@ -1,4 +1,5 @@
 #include "util.h"
+#include <stdarg.h>

 // define qemu logs
 void QemuPrintStr(i8* s){
@@ -9,12 +10,12 @@ void QemuPrintStr(i8* s){

 // convert binary number to ascii
 const i8 g_chars[] = "0123456789abcdef";
-void printf_unsigned(u32 num, u32 base){
+void printf_unsigned(u64 num, u32 base){
     i8 string[32];
     i32 pos = 0;

     do {
-        u32 rem = num % base;
+        u64 rem = num % base;
         num /= base;
         string[pos++] = g_chars[rem];
     } while (num > 0);
@@ -24,7 +25,7 @@ void printf_unsigned(u32 num, u32 base){
     }
 }

-void printf_signed(i32 num, u32 base){
+void printf_signed(s64 num, u32 base){
     if (num < 0){
         write_serial('-'); // changed
         printf_unsigned(-num, base);
@@ -36,11 +37,22 @@ void printf_signed(i32 num, u32 base){
 #define STATE_NORMAL 0
 #define STATE_FORMAT 1
 void QemuPrintf(const i8* str, ...){
+#if 0
     u32* argp = (u32*)&str;
+#endif
     u8 state = STATE_NORMAL;
+   int llflg;

+#if 0
     argp += sizeof(str)/sizeof(u32);
+#else
+   va_list ap;
+   va_start(ap,str);
+   u64 uval;
+   s64 sval;
+#endif
+
     while (*str){
         switch (state){
             case STATE_NORMAL:                      // wait for % or print
@@ -55,35 +67,59 @@ void QemuPrintf(const i8* str, ...){
                 }
             // fall through
             case STATE_FORMAT:                      // check what char is after %
+               llflg = 0;
+               if (*str == 'l') {
+                   ++llflg;
+                   ++str;
+               }
+               if (*str == 'l') {
+                   ++llflg;
+                   ++str;
+               }
+
                 switch (*str){
                     case '%':
                         write_serial('%'); // changed
                         break;

                     case 'c':                       // print char
-                        write_serial((char)*argp); // changed
-                        argp++;
+                        write_serial(va_arg(ap,int)); // changed
                         break;

                     case 's':                       // print string
-                        QemuPrintStr((char*)*argp);
-                        argp++;
+                        QemuPrintStr(va_arg(ap,char *));
                         break;

                     case 'd':                       // print signed base 10
-                        printf_signed((i32)*argp, 10);
-                        argp++;
+                       switch (llflg) {
+                       case 0:
+                           sval = va_arg(ap,i32);
+                           break;
+                       case 1:
+                           sval = va_arg(ap,long);
+                           break;
+                       default:
+                           sval = va_arg(ap,long long);
+                           break;
+                       }
+                        printf_signed(sval, 10);
                         break;

                     case 'u':                       // print unsigned base 10
-                        printf_unsigned((u32)*argp, 10);
-                        argp++;
-                        break;
-
                     case 'x':
                     case 'p':                       // print unsigned base 16
-                        printf_unsigned((u32)*argp, 16);
-                        argp++;
+                       switch (llflg) {
+                       case 0:
+                           uval = va_arg(ap,u32);
+                           break;
+                       case 1:
+                           uval = va_arg(ap,unsigned long);
+                           break;
+                       default:
+                           uval = va_arg(ap,unsigned long long);
+                           break;
+                       }
+                        printf_unsigned(uval, (*str == 'u') ? 10 : 16);
                         break;

                     default: break;                 // ignore invalid char
@@ -93,5 +129,10 @@ void QemuPrintf(const i8* str, ...){
         }
         str++;
     }
+
+#if 1
+   va_end(ap);
+#endif
+
     return;
 }
diff --git a/src/kernel/screen.c b/src/kernel/screen.c
index 45f1de1..3713ad3 100644
--- a/src/kernel/screen.c
+++ b/src/kernel/screen.c
@@ -7,21 +7,39 @@ static u8 *BUFFER = (u8*) 0xA0000;
 u8 buffers[2][SCREEN_SIZE];
 u8 current_buffer = 0;

+#if 0
 #define CURRENT     (buffers[current_buffer])
+#else
+#define CURRENT     (&buffers[current_buffer][0])
+#endif
+#if 0
 #define SWAP()      (current_buffer = 1 - current_buffer)
+#else
+#define SWAP()      current_buffer = current_buffer ? 0 : 1
+#endif

 #define VGA_MASK        0x3c6
 #define VGA_READ_ADD    0x3c7
 #define VGA_WRITE_ADD   0x3c8
 #define VGA_DATA        0x3c9

+#define CURRENT_SHOW \
+   dbgprt("%s: BUFFER=0x%x current_buffer=%d/0x%x/0x%x\n", \
+       __FUNCTION__,BUFFER,current_buffer,CURRENT,CURRENT + SCREEN_SIZE)
+
 void screen_swap(){
+   dbgprt("screen_swap: ENTER\n");
+   //CURRENT_SHOW;
     memcpy(BUFFER, CURRENT, SCREEN_SIZE);
     SWAP();
+   dbgprt("screen_swap: EXIT\n");
 }

 void clear_screen(u8 color){
-    memset(&CURRENT, color, SCREEN_SIZE);
+   dbgprt("clear_screen: ENTER color=0x%x\n",color);
+   CURRENT_SHOW;
+    memset(CURRENT, color, SCREEN_SIZE);
+   dbgprt("clear_screen: EXIT\n");
 }

 void plot_pixel(i32 x, i32 y, u8 color){
@@ -30,6 +48,7 @@ void plot_pixel(i32 x, i32 y, u8 color){
 }

 void set_palette(){
+   dbgprt("set_pallette: ENTER\n");
     outb(VGA_WRITE_ADD, 0);
     for(u8 i=0; i < 255; i++){
         // we shift it by 2 because each color is 6 bits
@@ -43,6 +62,7 @@ void set_palette(){
     outb(VGA_DATA, 0xff >> 2);
     outb(VGA_DATA, 0xff >> 2);
     outb(VGA_DATA, 0xff >> 2);
+   dbgprt("set_pallette: EXIT\n");
 }

 u8 COLOR(u8 r, u8 g, u8 b){
diff --git a/src/kernel/timer.c b/src/kernel/timer.c
index 748de08..7e283c0 100644
--- a/src/kernel/timer.c
+++ b/src/kernel/timer.c
@@ -2,36 +2,38 @@
 #include "util.h"
 #include "irq.h"

-static struct {
-    u32 divisor;
-    u32 frequency;
-    u64 ticks;
-} state;
-
 /* u64 timer = 0; */
 void timerFunction(Registers_t *regs){
-    state.ticks++;
+    timer_state.ticks++;
+   //dbgprt("timerFunction: ticks=%llu\n",timer_state.ticks);
 }

 void PIT_setCount(){
     // set the frequency of the pit to 1/TIMER_FREQ
-    state.divisor = TIMER_FREQ;
-    state.frequency = PIT_INTERNAL_FREQUENCY / state.divisor;      // get the desired freq
+    timer_state.divisor = TIMER_FREQ;
+    timer_state.frequency = PIT_INTERNAL_FREQUENCY / timer_state.divisor;      // get the desired freq

     CLI();
     outb(PIT_COMMAND, PIT_SET);
-    outb(PIT_CHANNEL0, state.frequency & 0xff);                  // low byte
-    outb(PIT_CHANNEL0, ((state.frequency & 0xff00) >> 8));       // high byte
+    outb(PIT_CHANNEL0, timer_state.frequency & 0xff);                  // low byte
+    outb(PIT_CHANNEL0, ((timer_state.frequency & 0xff00) >> 8));       // high byte
     STI();

     return;
 }

 u64 get_timer(){
-    return state.ticks;
+    return timer_state.ticks;
 }

 void timer_install(){
+   dbgprt("timer_install: ENTER\n");
+#if 0
     PIT_setCount();
     IRQ_RegisterHandler(0, timerFunction);
+#else
+    IRQ_RegisterHandler(0, timerFunction);
+    PIT_setCount();
+#endif
+   dbgprt("timer_install: EXIT\n");
 }
diff --git a/src/kernel/timer.h b/src/kernel/timer.h
index 9d6de1e..daecf36 100644
--- a/src/kernel/timer.h
+++ b/src/kernel/timer.h
@@ -13,6 +13,14 @@

 #define PIT_SET         0x36

+struct timer {
+    u32 divisor;
+    u32 frequency;
+    u64 ticks;
+};
+
+struct timer timer_state;
+
 void timer_install();
 u64 get_timer();

diff --git a/src/kernel/util.h b/src/kernel/util.h
index df2e92b..4935576 100644
--- a/src/kernel/util.h
+++ b/src/kernel/util.h
@@ -10,6 +10,8 @@ typedef char i8;
 typedef short i16;
 typedef int i32;
 typedef long long i64;
+typedef int s32;
+typedef long long s64;
 typedef u32 size_t;
 typedef u32 uintptr_t;
 typedef float f32;
@@ -41,6 +43,9 @@ typedef u8 bool;
 void QemuPrintStr(i8* s);
 void QemuPrintf(const i8* str, ...);

+#define dbgprt(_fmt...) \
+   QemuPrintf(_fmt)
+
 // communiation via ports --> io.c
 int init_serial();
 void write_serial(char a);

C++相关问答推荐

海湾合作委员会是否保证大小匹配的访问?

设计处理各种数据类型的方法和数据 struct

从STdin读写超过4096个字节

C strlen on char array

有效地计算由一组点构成的等边三角形和等腰三角形的数量

Mbed TLS:OAEP的就地en—/decryption似乎不起作用'

在C中将通用字符名称转换为UTF-8

是否所有C编译器在将浮点数转换为整型数时都会隐式删除小数?

试图从CSV文件中获取双精度值,但在C++中始终为空

如何在C中打印包含扫描字符和整数的语句?

函数的限制限定指针参数允许优化调用方函数吗?

如何确保在C程序中将包含uft8字符的字符串正确写入MySQL?

关于";*(++p)->;t";、&++p->;t";和&q;++*p->;t";的问题

强制转换变量以在 struct 中蚕食

为什么realloc函数在此代码中修改变量?

从C中的函数返回静态字符串是不是一种糟糕的做法?

C:面筋蛋白';为什么不刷新窗口?

%g浮点表示的最大字符串长度是多少?

如何转义包含指令中的字符?

我们可以在不违反标准的情况下向标准函数声明添加属性吗?