From: acevest Date: Tue, 30 May 2023 12:16:56 +0000 (+0800) Subject: 进一步解决在启动初期printk无法正常显示的问题;在boot阶段引入临时时钟中断以限制输出信息过快 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/doc/man.7.ps?a=commitdiff_plain;h=7b17646ffe1cd079f3f0773ac968f3acf69c6ceb;p=kernel.git 进一步解决在启动初期printk无法正常显示的问题;在boot阶段引入临时时钟中断以限制输出信息过快 --- diff --git a/Makefile b/Makefile index e295b1f..5f727f7 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ OBJS := $(patsubst %,%.o,$(SOURCE_FILES)) ${KERNELBIN}: ${OBJS} ${LD} -z noexecstack -m elf_i386 -M -T$(LINKSCRIPT) $(OBJS) -o $@ > $(SYSTEMMAP) nm -a $@ > kernel.sym - rm kernel/setup.c.o + #rm kernel/setup.c.o %.S.o: %.S ${HEADER_FILES} ${CC} ${CFLAGS} $< -o $@ diff --git a/boot/boot.c b/boot/boot.c index e7510a0..6652611 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -21,18 +21,71 @@ struct boot_params boot_params __attribute__((aligned(32))); void parse_cmdline(const char *cmdline); void init_vbe(void *, void *); + +// ticks < 0 代表永远等待 +void boot_delay(int ticks) { + char chs[] = {'\\', '-', '/', '-'}; + uint32_t cnt = 0; + + printk(" "); + asm("sti;"); + while (true) { + if (ticks == 0) { + break; + } + + if (ticks > 0) { + ticks--; + } + + printk("\b%c", chs[(cnt++ / 3) % sizeof(chs)]); + asm("hlt"); + } + asm("cli;"); + printk("\b \b"); +} + +void init_ttys(); +void setup_gdt(); +void setup_idt(); +void setup_gates(); +void set_tss(); +void setup_i8253(uint16_t); +void setup_boot_irqs(); + void check_kernel(unsigned long addr, unsigned long magic) { + init_ttys(); + + printk("setup gdt\n"); + setup_gdt(); + + printk("setup idt\n"); + setup_idt(); + + printk("setup trap and interrupt gates\n"); + setup_gates(); + + // 在初始化阶段一直运行在特权级0上 + // 在正在进入用户态前,所有中断都不会涉及特权级变化 + // 自然就不会有栈切换 + // 因此这里set_tss里的tss.esp0是不用初始化的 + set_tss(); + + setup_boot_irqs(); + + setup_i8253(100); + + boot_delay(DEFAULT_BOOT_DELAY_TICKS); + if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) { printk("Your boot loader does not support multiboot.\n"); - while (1) { - } + boot_delay(-1); } - unsigned long total_size = *((unsigned long *)addr); struct multiboot_tag *tag = (struct multiboot_tag *)(addr + 8); // 跳过中间的 reserved 字段 printk("total size: %d tags: %x\n", total_size, tag); - + boot_delay(DEFAULT_BOOT_DELAY_TICKS); struct multiboot_tag_basic_meminfo *mminfo = 0; struct multiboot_tag_bootdev *bootdev = 0; struct multiboot_tag_mmap *mmap_tag = 0; @@ -96,6 +149,8 @@ void check_kernel(unsigned long addr, unsigned long magic) { unsigned long size = (tag->size + 7) & (~7UL); tag = (struct multiboot_tag *)(((unsigned long)tag) + size); } + + boot_delay(DEFAULT_BOOT_DELAY_TICKS); #if 0 multiboot_info_t *mbi = (multiboot_info_t *)addr; @@ -130,13 +185,15 @@ void check_kernel(unsigned long addr, unsigned long magic) { } init_boot_params(mbi); + + boot_delay(DEFAULT_BOOT_DELAY_TICKS); #endif } extern void *kernel_begin; extern void *kernel_end; extern void *bootmem_bitmap_begin; -extern void init_default_tty_before_paging(); + void init_system_info() { system.kernel_begin = &kernel_begin; system.kernel_end = &kernel_end; @@ -148,4 +205,6 @@ void init_system_info() { printk("boot device: bios dev %x partition %x sub partition %x\n", boot_params.biosdev, boot_params.partition, boot_params.sub_partition); printk("mem lower %uKB upper %uKB\n", boot_params.mem_lower >> 10, boot_params.mem_upper >> 10); + + boot_delay(DEFAULT_BOOT_DELAY_TICKS); } diff --git a/boot/multiboot.S b/boot/multiboot.S index 6616ee8..aad20a0 100644 --- a/boot/multiboot.S +++ b/boot/multiboot.S @@ -20,7 +20,6 @@ .global kernel_entry .global main .extern check_kernel -.extern init_default_tty_before_paging .extern init_system_info .extern setup_kernel .extern init_pgd @@ -130,7 +129,6 @@ Label: addl $8, %esp movl $root_task + TASK_SIZE, %esp - call init_default_tty_before_paging call init_system_info call setup_kernel diff --git a/drivers/ide.c b/drivers/ide.c index 61bb7da..b314272 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -169,7 +169,7 @@ void ide_pci_init(pci_device_t *pci) { ide_pci_controller.pci = pci; - printk("channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x\n", ATA_CHL0_CMD_BASE, ATA_CHL0_CTL_BASE, + printd("channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x\n", ATA_CHL0_CMD_BASE, ATA_CHL0_CTL_BASE, ATA_CHL1_CMD_BASE, ATA_CHL1_CTL_BASE); // printl(18, "channel0: cmd %04x ctl %04x channel1: cmd %04x ctl %04x", HD_CHL0_CMD_BASE, HD_CHL0_CTL_BASE, // HD_CHL1_CMD_BASE, HD_CHL1_CTL_BASE); diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 5c44506..dea5b29 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -82,7 +82,7 @@ void kbd_debug(uint8_t scan_code) { // reboot(); } - printd("[%02x]", scan_code); + // printd("[%02x]", scan_code); if (scan_code == 0x3B) { // F1 tty_switch(&default_tty); diff --git a/include/i8259.h b/include/i8259.h index c18fa12..8a5108d 100644 --- a/include/i8259.h +++ b/include/i8259.h @@ -36,6 +36,11 @@ extern void init_i8259(); extern void mask_i8259(); +int enable_i8259_irq(unsigned int irq); +int disable_i8259_irq(unsigned int irq); +void mask_ack_i8259_irq(unsigned int irq); +void ack_i8259_irq(unsigned int irq); + #if 0 =Programmable Interrupt Controller= diff --git a/include/irq.h b/include/irq.h index 034ca1a..c96eae4 100644 --- a/include/irq.h +++ b/include/irq.h @@ -75,4 +75,9 @@ bool irq_disabled(); __asm__ __volatile__("pushl %0; popfl" ::"g"(x) : "memory", "cc"); \ } while (0) +#define IRQ_CLOCK 0x00 +#define IRQ_KEYBOARD 0x01 +#define IRQ_CASCADE 0x02 +#define IRQ_DISK 0x0E + #endif //_IRQ_H diff --git a/include/printk.h b/include/printk.h index 00efc26..5b2908c 100644 --- a/include/printk.h +++ b/include/printk.h @@ -52,3 +52,5 @@ enum { MPO_KEYBOARD = 50, MPO_IDE = 1, }; + +int sprintf(char *str, const char *fmtstr, ...); diff --git a/include/system.h b/include/system.h index a40cc79..7e920eb 100644 --- a/include/system.h +++ b/include/system.h @@ -70,14 +70,8 @@ void kfree(void *addr); extern char etext, edata, end; -extern char gdtr[6], idtr[6]; -#define lgdt() __asm__ __volatile__("lgdt gdtr") -#define sgdt() __asm__ __volatile__("sgdt gdtr") -#define lidt() __asm__ __volatile__("lidt idtr") -#define sidt() __asm__ __volatile__("sidt idtr") - -#define cli() __asm__ __volatile__("cli") -#define sti() __asm__ __volatile__("sti") +#define cli() asm volatile("cli") +#define sti() asm volatile("sti") #define nop() asm volatile("nop") #define mb() asm volatile("" ::: "memory") #define disableIRQ() cli() @@ -271,6 +265,9 @@ void disk_task_entry(); void user_task_entry(); extern volatile int reenter; + +#define DEFAULT_BOOT_DELAY_TICKS 30 +void boot_delay(int ticks); #endif #endif //_SYSTEM_H diff --git a/kernel/entry.S b/kernel/entry.S index 32a5d68..4c00895 100644 --- a/kernel/entry.S +++ b/kernel/entry.S @@ -1,16 +1,16 @@ /* *-------------------------------------------------------------------------- * File Name: entry.S - * + * * Description: none - * - * + * + * * Author: Zhao Yanbai [zhaoyanbai@126.com] - * + * * Version: 1.0 * Create Date: Thu Jul 09 19:56:40 2009 * Last Update: Thu Jul 09 19:56:40 2009 - * + * *-------------------------------------------------------------------------- */ #define ASM @@ -70,4 +70,3 @@ ERRORCODE (StackFault) ERRORCODE (GeneralProtection) ERRORCODE (PageFault) NOERRCODE (CoprocError) - diff --git a/kernel/fork.c b/kernel/fork.c index e49942a..d600f73 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -22,7 +22,7 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { task_union *tsk; tsk = alloc_task_union(); - printk("fork task %08x flags %08x\n", tsk, flags); + printd("fork task %08x flags %08x\n", tsk, flags); if (tsk == NULL) { panic("can not malloc PCB"); } @@ -95,7 +95,7 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1; - printk("child regs: %x %x\n", child_regs, regs); + printd("child regs: %x %x\n", child_regs, regs); memcpy(child_regs, regs, sizeof(*regs)); tsk->esp0 = TASK_SIZE + (unsigned long)tsk; @@ -109,7 +109,7 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { child_regs->eax = 0; child_regs->eflags |= 0x200; // enable IF - printk("tsk %08x child_regs esp %08x esp0 %08x\n", tsk, tsk->esp, tsk->esp0); + printd("task %08x child_regs esp %08x esp0 %08x\n", tsk, tsk->esp, tsk->esp0); tsk->state = TASK_INITING; @@ -124,4 +124,4 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { return (int)tsk->pid; } -int sysc_fork(pt_regs_t regs) { return do_fork(®s, 0); } \ No newline at end of file +int sysc_fork(pt_regs_t regs) { return do_fork(®s, 0); } diff --git a/kernel/i8259.c b/kernel/i8259.c index 1c01157..73078dc 100644 --- a/kernel/i8259.c +++ b/kernel/i8259.c @@ -138,3 +138,21 @@ irq_chip_t i8259_chip = { }; void do_i8259_IRQ(pt_regs_t *regs, unsigned int irq) {} + +__attribute__((regparm(1))) void boot_irq_handler(pt_regs_t *regs) { + unsigned int irq = regs->irq; + if (irq != 0 && irq != 1) { + panic("invalid irq %d\n", irq); + } + + assert(irq_disabled()); + + // 屏蔽当前中断 + disable_i8259_irq(irq); + + // 发送EOI + ack_i8259_irq(irq); + + // 解除屏蔽当前中断 + enable_i8259_irq(irq); +} diff --git a/kernel/interrupts.S b/kernel/interrupts.S index f480ff3..8bc701b 100644 --- a/kernel/interrupts.S +++ b/kernel/interrupts.S @@ -1,16 +1,16 @@ /* *-------------------------------------------------------------------------- * File Name: interrupts.S - * + * * Description: none - * - * + * + * * Author: Zhao Yanbai [zhaoyanbai@126.com] - * + * * Version: 1.0 * Create Date: Thu Jul 16 18:54:08 2009 * Last Update: Wed Feb 10 23:10:56 2010 - * + * *-------------------------------------------------------------------------- */ #define ASM @@ -29,7 +29,7 @@ jmp _irq_handler; .global no_irq_handler no_irq_handler: pushl $0xFFFFFFFF -jmp _irq_handler +jmp _boot_irq_handler DEF_IRQ(0,0) @@ -67,7 +67,41 @@ _irq_handler: movl %esp, %eax call irq_handler - + RESTORE_REGS addl $4, %esp - iret \ No newline at end of file + iret + + + +.extern boot_irq_handler +_boot_irq_handler: + SAVE_REGS + + // ebp指向栈桢 + movl $-TASK_SIZE, %ebp + andl %esp, %ebp + + movw %ss, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + movl %esp, %eax + call boot_irq_handler + + RESTORE_REGS + addl $4, %esp + iret + + +.global _boot_clk_irq_handler +.global _boot_kbd_irq_handler + +_boot_clk_irq_handler: + push $0x00; + jmp _boot_irq_handler +_boot_kbd_irq_handler: + push $0x01; + jmp _boot_irq_handler diff --git a/kernel/setup.c b/kernel/setup.c index 016d433..4270530 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -56,32 +56,35 @@ void setup_kernel() { init_mm(); // printk("kernel: %08x - %08x\n", system.kernel_begin, system.kernel_end); - - setup_gdt(); - setup_idt(); - setup_gate(); - set_tss(); - - setup_i8253(100); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); setup_sysc(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); cnsl_init(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); printl(MPL_TITLE, " KERNEL MONITOR"); setup_tasks(); - - setup_irqs(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); setup_pci(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); detect_cpu(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); printk(version); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); extern tty_t monitor_tty; - tty_switch(&monitor_tty); + // tty_switch(&monitor_tty); + + boot_delay(DEFAULT_BOOT_DELAY_TICKS); + + setup_i8253(100); + setup_irqs(); void ide_init(); ide_init(); diff --git a/kernel/system.c b/kernel/system.c index 53b72dd..4bd43a2 100644 --- a/kernel/system.c +++ b/kernel/system.c @@ -26,14 +26,51 @@ #include #include +System system; +TSS_t tss; +Desc idt[NIDT] __attribute__((__aligned__(8))); +Desc gdt[NGDT] __attribute__((__aligned__(8))); +char gdtr[6] __attribute__((__aligned__(4))); +char idtr[6] __attribute__((__aligned__(4))); + +extern char _gdtr[6]; +extern char _idtr[6]; + +volatile int reenter = -1; + +#if 0 +void setup_gdt_before_pageing() { + pDesc pdesc; + // change to new gdt. + asm volatile("sgdt _gdtr"); + Desc *_gdt = (Desc *)va2pa(gdt); + memcpy((void *)_gdt, (void *)(_gdtr + 2), *((uint16_t *)(_gdtr + 0))); + + // + *((uint16_t *)(_gdtr + 0)) = NGDT * sizeof(Desc); + *((uint32_t *)(_gdtr + 2)) = (uint32_t)_gdt; + asm volatile("sgdt _gdtr"); + memcpy(_gdt + INDEX_UCODE, _gdt + INDEX_KCODE, sizeof(Desc)); + memcpy(_gdt + INDEX_UDATA, _gdt + INDEX_KDATA, sizeof(Desc)); + pdesc = _gdt + INDEX_UCODE; + pdesc->seg.DPL = 3; + pdesc = _gdt + INDEX_UDATA; + pdesc->seg.DPL = 3; +} +#endif + void setup_gdt() { pDesc pdesc; // change to new gdt. - sgdt(); - memcpy(gdt, (void *)pa2va(*((unsigned long *)(gdtr + 2))), *((unsigned short *)gdtr)); + asm volatile("sgdt gdtr"); + + // 复制旧的GDT + memcpy(gdt, (void *)pa2va(*((uint32_t *)(gdtr + 2))), *((uint16_t *)(gdtr + 0))); *((unsigned short *)gdtr) = NGDT * sizeof(Desc); *((unsigned long *)(gdtr + 2)) = (unsigned long)gdt; - lgdt(); + + asm volatile("lgdt gdtr"); + memcpy(gdt + INDEX_UCODE, gdt + INDEX_KCODE, sizeof(Desc)); memcpy(gdt + INDEX_UDATA, gdt + INDEX_KDATA, sizeof(Desc)); pdesc = gdt + INDEX_UCODE; @@ -42,14 +79,16 @@ void setup_gdt() { pdesc->seg.DPL = 3; } +// 中断门和陷阱门的区别是 +// 通过中断门进入中断服务程序CPU会自动将中断关闭,也就是将EFLAGS的IF位清0 +// 通过陷阱门进入服务程序时则维持IF标志位不变 void setup_idt() { *((unsigned short *)idtr) = NIDT * sizeof(Gate); *((unsigned long *)(idtr + 2)) = (unsigned long)idt; - lidt(); + asm volatile("lidt idtr"); } -void setup_gate() { - int i; +void setup_gates() { set_sys_int(0x00, TRAP_GATE, PRIVILEGE_KRNL, DivideError); set_sys_int(0x01, TRAP_GATE, PRIVILEGE_KRNL, Debug); set_sys_int(0x02, INTR_GATE, PRIVILEGE_KRNL, NMI); @@ -67,10 +106,22 @@ void setup_gate() { set_sys_int(0x0E, TRAP_GATE, PRIVILEGE_KRNL, PageFault); set_sys_int(0x10, TRAP_GATE, PRIVILEGE_KRNL, CoprocError); - for (i = 0x11; i < 0x20; i++) set_sys_int(i, INTR_GATE, PRIVILEGE_KRNL, no_irq_handler); + for (int i = 0x11; i < 0x20; i++) { + set_sys_int(i, INTR_GATE, PRIVILEGE_KRNL, no_irq_handler); + } + + for (int i = 0x20; i < 256; i++) { + set_sys_int(i, INTR_GATE, PRIVILEGE_KRNL, no_irq_handler); + } +} + +void ide_irq(); + +void default_irq_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { printk("default irq handler %d \n", irq); } - for (i = 0x20; i < 256; i++) set_sys_int(i, INTR_GATE, PRIVILEGE_KRNL, no_irq_handler); +void init_i8259(); +void setup_irqs() { set_sys_int(0x20, INTR_GATE, PRIVILEGE_KRNL, irq_0x00_handler); set_sys_int(0x21, INTR_GATE, PRIVILEGE_KRNL, irq_0x01_handler); set_sys_int(0x22, INTR_GATE, PRIVILEGE_KRNL, irq_0x02_handler); @@ -87,15 +138,6 @@ void setup_gate() { set_sys_int(0x2D, INTR_GATE, PRIVILEGE_KRNL, irq_0x0D_handler); set_sys_int(0x2E, INTR_GATE, PRIVILEGE_KRNL, irq_0x0E_handler); set_sys_int(0x2F, INTR_GATE, PRIVILEGE_KRNL, irq_0x0F_handler); -} - -void ide_irq(); - -void default_irq_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { printk("default irq handler %d \n", irq); } - -void setup_irqs() { - extern void init_i8259(); - init_i8259(); for (int i = 0; i < NR_IRQS; i++) { irq_desc[i] = no_irq_desc; @@ -125,12 +167,27 @@ void setup_irqs() { // 清除8259A的级连中断引脚的中断屏蔽位 // 以让从片的中断在放开后能发送到CPU - open_irq(2); + open_irq(IRQ_CASCADE); // 打开支持的中断 - open_irq(0x00); - open_irq(0x01); - open_irq(0x0E); + open_irq(IRQ_CLOCK); + open_irq(IRQ_KEYBOARD); + open_irq(IRQ_DISK); +} + +void boot_irq_handler(); +void setup_boot_irqs() { + init_i8259(); + + // clock + set_sys_int(0x20 + IRQ_CLOCK, INTR_GATE, PRIVILEGE_KRNL, _boot_clk_irq_handler); + + // keyboard + set_sys_int(0x20 + IRQ_KEYBOARD, INTR_GATE, PRIVILEGE_KRNL, _boot_kbd_irq_handler); + + // 打开支持的中断 + enable_i8259_irq(IRQ_CLOCK); + enable_i8259_irq(IRQ_KEYBOARD); } void set_tss_gate(u32 vec, u32 addr, u32 limit) { @@ -185,12 +242,3 @@ int sysc_reboot(int mode) { return 0; } - -System system; -TSS_t tss; -Desc idt[NIDT] __attribute__((__aligned__(8))); -Desc gdt[NGDT] __attribute__((__aligned__(8))); -char gdtr[6] __attribute__((__aligned__(4))); -char idtr[6] __attribute__((__aligned__(4))); - -volatile int reenter = -1; \ No newline at end of file diff --git a/kernel/task_root.c b/kernel/task_root.c index fcde446..4baa768 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -46,7 +46,7 @@ void kernel_task(char *name, void *entry) { int pid = do_fork(®s, FORK_KRNL); - printk("kernel[%s] task pid is %d\n", name, pid); + printd("kernel[%s] task pid is %d\n", name, pid); } // 测试用的代码 @@ -178,4 +178,4 @@ void root_task_entry() { while (1) { asm("hlt;"); } -} \ No newline at end of file +} diff --git a/kernel/task_user.c b/kernel/task_user.c index 1545db9..d5ec98e 100644 --- a/kernel/task_user.c +++ b/kernel/task_user.c @@ -64,8 +64,8 @@ void user_task_entry() { unsigned long *p = (unsigned long *)(pa2va(current->cr3)); - printk("page dir : %x %x %x %x\n", p, pt_text_page, ring3_text_page); - printk("pt bss page %x %x", pt_bss_page, ring3_bss_page); + printd("page dir : %x %x %x %x\n", p, pt_text_page, ring3_text_page); + printd("pt bss page %x %x", pt_bss_page, ring3_bss_page); // text: 0x0800_0000 // bss: 0x3000_0000 @@ -84,4 +84,4 @@ void user_task_entry() { // eip --> edx // esp --> ecx asm volatile("sysexit;" ::"d"(0x08000000), "c"(0x30000000 + PAGE_SIZE - 100)); -} \ No newline at end of file +} diff --git a/kernel/tty.c b/kernel/tty.c index 11a23f5..8c0a289 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -19,7 +19,7 @@ // 所以大致可以分出8个tty // 每个的起始地址以0x1000对齐 const uint32_t PHY_VADDR = 0xB8000; -#define VADDR ((uint32_t)pa2va(PHY_VADDR)) +const uint32_t VADDR = (uint32_t)pa2va(PHY_VADDR); #define TTY_VRAM_SIZE (0x1000) #define MAX_X 80 @@ -62,14 +62,6 @@ void __tty_set_next_pos_color(tty_t *tty, char color) { } } -void init_default_tty_before_paging() { - default_tty.fg_color = TTY_FG_HIGHLIGHT | TTY_GREEN; // 高亮 - default_tty.bg_color = TTY_BLACK; // 不闪 - default_tty.base_addr = PHY_VADDR; - default_tty.xpos = 0; - default_tty.ypos = 0; -} - void init_tty(tty_t *tty, const char *name, unsigned long base) { assert(0 != tty); @@ -81,6 +73,12 @@ void init_tty(tty_t *tty, const char *name, unsigned long base) { tty->bg_color = TTY_BLACK; // 不闪 tty->base_addr = base; + + for (int i = 0; i < TTY_VRAM_SIZE; i += 2) { + uint8_t *p = (uint8_t *)base; + p[i + 0] = ' '; + p[i + 1] = (tty->bg_color << 4) | tty->fg_color; + } } void init_ttys() { @@ -103,10 +101,6 @@ void init_ttys() { tty_clear(&monitor_tty); tty_clear(&debug_tty); - // 恢复在分页前的输出位置 - default_tty.xpos = xpos; - default_tty.ypos = ypos; - current_tty = &default_tty; } diff --git a/lib/lib.c b/lib/lib.c index 6c1fec6..80c515b 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -33,3 +33,12 @@ int systest() { return syscall0(SYSC_TEST); } int sysdebug(unsigned int v) { return syscall1(SYSC_DEBUG, v); } int pause(unsigned long tick) { return syscall1(SYSC_PAUSE, tick); } + +int vsprintf(char *buf, const char *fmt, char *args); +int sprintf(char *str, const char *fmtstr, ...) { + char *args = (char *)(((char *)&fmtstr) + 4); + + vsprintf(str, fmtstr, args); + + return 0; +} diff --git a/mm/bootmem.c b/mm/bootmem.c index a4f09d7..c8d2f52 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -12,25 +12,61 @@ #include #include -static void e820_print_type(unsigned long type) { +static void get_e820_size(uint32_t size, char *buf) { + const char *fmt = "%3u %s"; + if (size < (1 << 10)) { + sprintf(buf, fmt, size, "B"); + } else if (size < (1 << 20)) { + sprintf(buf, fmt, size >> 10, "KB"); + } else if (size < (1 << 30)) { + sprintf(buf, fmt, size >> 20, "MB"); + } else { + sprintf(buf, fmt, size >> 30, "GB"); + } +} + +// static void e820_print_type(unsigned long type) { +// switch (type) { +// case E820_RAM: +// printk("RAM"); +// break; +// case E820_RESERVED: +// printk("RESERVED"); +// break; +// case E820_ACPI: +// printk("ACPI"); +// break; +// case E820_NVS: +// printk("NVS"); +// break; +// case E820_UNUSABLE: +// printk("UNUSABLE"); +// break; +// default: +// printk("type %x", type); +// break; +// } +// } + +static void get_e820_type(uint32_t type, char *buf) { switch (type) { case E820_RAM: - printk("RAM"); + sprintf(buf, "%s", "RAM"); break; case E820_RESERVED: - printk("RESERVED"); + sprintf(buf, "%s", "RESERVED"); break; case E820_ACPI: - printk("ACPI"); + sprintf(buf, "%s", "ACPI"); break; case E820_NVS: - printk("NVS"); + sprintf(buf, "%s", "NVS"); break; case E820_UNUSABLE: - printk("UNUSABLE"); + sprintf(buf, "%s", "UNUSABLE"); break; default: - printk("type %x", type); + sprintf(buf, "type %x", type); break; } } @@ -63,16 +99,16 @@ void fast_init_bootmem_bitmap(unsigned long bgn_pfn, unsigned long end_pfn, int void e820_print_map() { unsigned int i = 0; - for (i = 0; i < boot_params.e820map.map_cnt; ++i) { struct e820_entry *p = boot_params.e820map.map + i; - printk(" [%02d] 0x%010lX - 0x%010lX size %- 10u %8dKB %5dMB ", i, p->addr, (p->addr + p->size - 1), - (uint32_t)p->size, (uint32_t)(p->size >> 10), (uint32_t)(p->size >> 20)); - - e820_print_type(p->type); - - printk("\n"); + // printk(" [%02d] 0x%010lX - 0x%010lX size %- 10u %8dKB %5dMB ", i, p->addr, (p->addr + p->size - 1), + // (uint32_t)p->size, (uint32_t)(p->size >> 10), (uint32_t)(p->size >> 20)); + char size_buf[16]; + char type_buf[16]; + get_e820_size((uint32_t)p->size, size_buf); + get_e820_type(p->type, type_buf); + printk(" [%02d] 0x%08lX - 0x%08lX %7s %s\n", i, p->addr, (p->addr + p->size - 1), size_buf, type_buf); } } diff --git a/mm/mm.c b/mm/mm.c index 7d06373..71deb05 100644 --- a/mm/mm.c +++ b/mm/mm.c @@ -125,20 +125,19 @@ void init_mm() { printk("init bootmem alloc...\n"); extern void init_bootmem(); init_bootmem(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); printk("init global paging...\n"); init_paging(); - - // 只能将这个调用放在此处 - // 在这之前是没开启页映射用的是物理地址 - // 在这之后需要用到线性地址来定位显存 - init_ttys(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); printk("init buddy system...\n"); extern void init_buddy_system(); init_buddy_system(); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); printk("init kmem caches...\n"); extern void init_kmem_caches(); init_kmem_caches(); printk("memory init finished...\n"); + boot_delay(DEFAULT_BOOT_DELAY_TICKS); }