return;
}
- // unsigned long ddd = 0xFEC00000;
- // while(ddd < 0xFF000000) {
- // page_map((void*)ddd, (void*)ddd, PAGE_P);
- // ddd += 0x1000;
- // }
-
page_map(addr, addr, PAGE_P | PAGE_WR);
rsdt_t *rsdt = (rsdt_t *)addr;
#include <page.h>
#include <string.h>
#include <system.h>
-#include <msr.h>
-#include <cpuid.h>
#include <elf.h>
struct boot_params boot_params __attribute__((aligned(32)));
#endif
}
-
-void for_breakpoint() {
-
-}
-
-void lapic_init() {
- cpuid_regs_t r;
- r = cpuid(1);
- if(r.edx & (1 << 9)) {
- printk("local apic supported\n");
- if(r.ecx & (1 << 21)) {
- printk("x2apic supported\n");
- } else {
- panic("x2apic not supported\n");
- }
- } else {
- panic("local apic not supported\n");
- }
-
- uint64_t apic_base = read_msr(MSR_IA32_APIC_BASE);
- printk("apic base: %016lx\n", apic_base);
-
- // 开启2xapic
- apic_base |= (1 << 10);
- write_msr(MSR_IA32_APIC_BASE, apic_base);
-
- apic_base = read_msr(MSR_IA32_APIC_BASE);
- printk("after 2xapic enable apic base: %016lx\n", apic_base);
-
- uint64_t apic_version = read_msr(MSR_IA32_X2APIC_VERSION);
- printk("apic version: %08lx\n", apic_version);
-
- for_breakpoint();
-}
-
-
extern void *kernel_begin;
extern void *kernel_end;
extern void *bootmem_bitmap_begin;
printk("mem lower %uKB upper %uKB\n", boot_params.mem_lower >> 10, boot_params.mem_upper >> 10);
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
-
-
- lapic_init();
}
set architecture i386
-b main
+#b acpi.c:144
+#b main
#b boot_paging
#b *0x100000
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: apic.c
+ * Author: Zhao Yanbai
+ * 2025-12-28 20:52:47 Sunday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <msr.h>
+#include <cpuid.h>
+#include <system.h>
+
+ void lapic_init() {
+ cpuid_regs_t r;
+ r = cpuid(1);
+ if(r.edx & (1 << 9)) {
+ printk("local apic supported\n");
+ if(r.ecx & (1 << 21)) {
+ printk("x2apic supported\n");
+ } else {
+ panic("x2apic not supported\n");
+ }
+ } else {
+ panic("local apic not supported\n");
+ }
+
+ uint64_t apic_base = read_msr(MSR_IA32_APIC_BASE);
+ printk("apic base: %016lx\n", apic_base);
+
+
+ // apic 必然已经开启
+ assert((apic_base & (1 << 11)) != 0);
+
+ // 开启2xapic
+ apic_base |= (1 << 10);
+ write_msr(MSR_IA32_APIC_BASE, apic_base);
+
+ apic_base = read_msr(MSR_IA32_APIC_BASE);
+ printk("after 2xapic enable apic base: %016lx\n", apic_base);
+
+ uint64_t apic_version = read_msr(MSR_IA32_X2APIC_VERSION);
+ printk("apic version: %08lx\n", apic_version);
+
+
+ unsigned long apic_phys_base_addr = apic_base & 0xFFFFF000;
+ unsigned long apic_virt_base_addr = apic_phys_base_addr;
+ #if 0
+ unsigned long ddd = 0xFEC00000;
+ while(ddd < 0xFF000000) {
+ page_map((void*)ddd, (void*)ddd, PAGE_P);
+ ddd += 0x1000;
+ }
+ #endif
+ page_map((void*)apic_virt_base_addr, (void*)apic_phys_base_addr, PAGE_P);
+
+ {
+ volatile uint32_t *base = (volatile uint32_t *)apic_virt_base_addr;
+ uint32_t id = base[0x20/4]; // APIC ID 偏移
+ uint32_t version = base[0x30/4];
+ printk("APIC id %08x version %08x\n", id, version);
+ }
+
+}
+
+
+void init_apic() {
+ lapic_init();
+}
init_buffer();
+ #if 1
parse_rsdt(system.rsdt_addr);
+ void init_apic();
+ init_apic();
+ #endif
+
void init_mount();
init_mount();
// 页表指向物理地址
pgt[npte] = PAGE_ALIGN(paddr) | flags;
+
+
+ asm volatile("invlpg (%0)" : : "r"(vaddr));
+
+ uint32_t cr3 = 0;
+ asm("mov %%cr3, %0" : "=r"(cr3));
+
+ asm("nop;nop;nop;");
+
+ asm("mov %0, %%cr3" : : "r"(cr3));
+ // asm volatile("mov %0, %%cr3" : : "r"(pgd_pyhs_addr));
}
-serial tcp::6666,server,nowait \
-drive file=hd.img,format=raw,index=0,media=disk \
-drive file=kernel.iso,index=1,media=cdrom \
+ -drive file=sata.img,format=raw,if=none,id=sata-disk \
+ -device ahci,id=ahci0 \
+ -device ide-hd,drive=sata-disk,bus=ahci0.0 \
-name kernel \
-vga std \
-display cocoa \
# nc -U /tmp/qemu-monitor.sock
+ # -d int,cpu_reset \
+
# -machine pc-q35-9.2 \
# -cpu qemu32,+apic \
# -cpu qemu32,+x2apic \
#-cpu qemu32,+apic \
#-cpu core2duo-v1,+apic \
+ # -serial file:serial_output.log \
+ # -serial tcp::6666,server,nowait \
+
pid=$!
echo "pid is ${pid}"
)
var addr string
+var logFile string
+var clearMode bool
func main() {
flag.StringVar(&addr, "a", ":6666", "")
+ flag.StringVar(&logFile, "f", "last.log", "")
+ flag.BoolVar(&clearMode, "c", true, "clear log file every time")
flag.Parse()
+ // 创建一个可写的文本文件
+ f, err := os.Create(logFile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer f.Close()
+
for {
- log.Printf("addr %v", addr)
- monitor()
+ var modeStr string
+ if clearMode {
+ modeStr = "clear log file every time"
+ } else {
+ modeStr = "do not clear log file"
+ }
+ log.Printf("listen addr %v log file %v %v", addr, logFile, modeStr)
+
+ monitor(f)
+
+
}
}
-func monitor() {
+func monitor(f *os.File) {
var conn net.Conn
var err error
start := time.Now()
+
// 不断尝试连接串行控制台
for {
conn, err = net.Dial("tcp", addr)
log.Printf("\nconnected...\n")
break
} else {
- fmt.Printf("\r\033[Kwait %d seconds", int(time.Now().Sub(start).Seconds()))
+ fmt.Printf("\r\033[Kwait %d seconds", int(time.Since(start).Seconds()))
time.Sleep(500 * time.Millisecond)
}
}
defer conn.Close()
+
+
+ // 每次连接成功,就清空这个文件,从头开始写数据
+ if clearMode {
+ err = f.Truncate(0)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ f.Seek(0, 0)
+ }
+
+ // 写入当前时间
+ f.WriteString("\n\n")
+ _, err = f.WriteString(time.Now().Format("2006-01-02 15:04:05.000") + "\n")
+ if err != nil {
+ log.Fatal(err)
+ }
+ f.WriteString("\n\n")
+
end := make(chan bool, 0)
// 将串行控制台的输出发送到屏幕
go func() {
- _, _ = io.Copy(os.Stdout, conn)
- log.Printf("qemu -> stdout end\n")
+ // 将conn的输出复制到os.Stdout和f
+ _, err = io.Copy(io.MultiWriter(os.Stdout, f), conn)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("qemu -> stdout end\n")
end <- true
}()