From 7360362e24431c0bde7044bd2e282c5c53bed69a Mon Sep 17 00:00:00 2001 From: acevest Date: Thu, 12 Oct 2023 18:58:22 +0800 Subject: [PATCH] =?utf8?q?VBE=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91=E4=BF=AE?= =?utf8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + boot/boot.c | 11 +++---- boot/multiboot.S | 15 +++++++-- boot/vbe.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++- gdbscript | 4 ++- 5 files changed, 105 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index cba73dc..603e279 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ bochsout.txt *.DS_Store .vscode/settings.json *.iso +**/serial_monitor/serial_monitor diff --git a/boot/boot.c b/boot/boot.c index 339d744..a29fab4 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -100,6 +100,7 @@ void check_kernel(unsigned long addr, unsigned long magic) { boot_params.e820map.map_cnt = 0; while (tag->type != MULTIBOOT_TAG_TYPE_END) { + bool support = true; switch (tag->type) { case MULTIBOOT_TAG_TYPE_CMDLINE: strlcpy(boot_params.cmdline, ((struct multiboot_tag_string *)tag)->string, sizeof(boot_params.cmdline)); @@ -137,19 +138,17 @@ void check_kernel(unsigned long addr, unsigned long magic) { vbe = (struct multiboot_tag_vbe *)tag; void *vci = (void *)vbe->vbe_control_info.external_specification; void *vmi = (void *)vbe->vbe_mode_info.external_specification; - // vbe->vbe_control_info; - // asm volatile("xchg %%bx, %%bx;nop;nop;" ::"a"(vci), "b"(vmi)); - // asm volatile("xchg %%bx, %%bx;nop;nop;" ::"a"(vbe->vbe_interface_seg), "b"(vbe->vbe_interface_off), - // "c"(vbe->vbe_interface_len)); + printk("VBE MODE %04x\n", vbe->vbe_mode); init_vbe(vci, vmi); break; case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: - // asm volatile("xchg %bx, %bx;nop;nop;nop;nop;"); + printk("frame buffer\n"); break; default: - printk("tag %x size %x\n", tag->type, tag->size); + support = false; break; } + printk("tag %x size %x\t[%ssupport]\n", tag->type, tag->size, support ? "" : "un"); // next tag unsigned long size = (tag->size + 7) & (~7UL); tag = (struct multiboot_tag *)(((unsigned long)tag) + size); diff --git a/boot/multiboot.S b/boot/multiboot.S index aad20a0..3791f26 100644 --- a/boot/multiboot.S +++ b/boot/multiboot.S @@ -172,8 +172,19 @@ multiboot2_header_bgn: // .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER // .short MULTIBOOT_HEADER_TAG_OPTIONAL // .long .framebuffer_tag_end - .framebuffer_tag_bgn - // .long 800 - // .long 600 + // # width + // # Contains the number of the columns. This is specified in pixels in a graphics mode, + // # and in characters in a text mode. + // # The value zero indicates that the OS image has no preference. + // .long 1024 + // # height + // # Contains the number of the lines. This is specified in pixels in a graphics mode, + // # and in characters in a text mode. + // # The value zero indicates that the OS image has no preference. + // .long 768 + // # depth + // # Contains the number of bits per pixel in a graphics mode, and zero in a text mode. + // # The value zero indicates that the OS image has no preference. // .long 32 // .framebuffer_tag_end: diff --git a/boot/vbe.c b/boot/vbe.c index d6a6ac4..598905d 100644 --- a/boot/vbe.c +++ b/boot/vbe.c @@ -12,6 +12,58 @@ #include #include +// VESA BIOS Extensions + +// VGA +// VGA(Video Graphics Array)即视频图形阵列,是IBM在1987年随PS/2机推出的。 +// VGA主要由七大块组成:图形控制器、显示存储器、定序器、CRT控制器、数据串行发生器、属性控制器和数模转换器DAC。 + +// VBE +// IBM的VGA标准是显示卡发展史上的一块丰碑。但后来无法满足人们的需要,于是市场上出现了TVGA、S3系列、Cirrus +// Logic、ET等为首的一批显示卡,提供了比VGA分辨率更高,颜色更丰富的显示模式,又兼容VGA显示卡,它们被统称为Super +// VGA(SVGA)。 各种不同的SVGA之间的显示控制各不相同,带来软件兼容性问题,为此视频电子学标准协会VESA(Video Electronics +// Standards Association)提出了一组附加的BIOS功能调用接口——VBE(VESA BIOS EXTENSION)标准, +// 从而在软件接口层次上实现了各种SVGA显示卡之间的兼容性。时至今日,所有的显示卡OEM厂商都提供了符合VESA +// SUPER标准的扩展BIOS 通过一组INT 10H中断调用(AH=4FH),可以方便地使用VESA +// SVGA的扩展功能而不必了解各种显示卡的硬件细节。 Super VGA 的扩充显示能力关键取决于对较大显示存储器的寻址能力。 各Super +// VGA 卡提供的分辨率远高于VGA,VESA VBE均赋予一个标准的16位模式号(实际上是9位,其他各位为标志位或留给以后扩充)。 + +// typedef uint8_t BCD; +// typedef struct vg_vbe_contr_info { +// char VBESignature[4]; +// BCD VBEVersion[2]; +// char *OEMString; +// uint16_t *VideoModeList; +// uint32_t TotalMemory; +// char *OEMVendorNamePtr; +// char *OEMProductNamePtr; +// char *OEMProductRevPtr; +// } vg_vbe_contr_info_t; + +#define VBE_MODE_END 0xFFFF +typedef struct segoff { + uint16_t offset; + uint16_t segment; +} __attribute__((packed)) segoff_t; + +// typedef uint32_t segoff_t; +typedef struct vbe_controller_info { + uint8_t signature[4]; // 'VESA' + uint16_t version; // BCD + // uint8_t major_version; // BCD + // uint8_t minor_version; // BCD + segoff_t oem_string_ptr; + uint8_t capabilities[4]; + segoff_t video_mode_ptr; + uint16_t total_memory; // Number of 64kB memory blocks. + // ... 更多 VBE 3.0+ 字段 + uint16_t oem_software_rev; + segoff_t oem_vendor_name_ptr; + segoff_t oem_product_name_ptr; + segoff_t oem_product_rev_ptr; + uint8_t reserved[222]; +} __attribute__((packed)) vbe_controller_info_t; + typedef struct vbe_mode_info { u16 mode_attributes; u8 wina_attributes; @@ -62,11 +114,41 @@ typedef struct vbe_mode_info { // pte_t vbe_pte[PTECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE))); +uint32_t segoff_to_addr(segoff_t sg) { return 0xC0000000 + (sg.segment << 4) + sg.offset; } + +vbe_mode_info_t *get_vbe_mode_info(uint16_t) { + // 设置并执行实模式代码以调用 VBE 函数 0x4F01 + // 返回指向 VBE 模式信息的指针 + return NULL; +} // extern pde_t init_pgd[]; void init_vbe(void *vciptr, void *vmiptr) { + vbe_controller_info_t *vci = vciptr; vbe_mode_info_t *vmi = (vbe_mode_info_t *)vmiptr; + printk("VBE:\n"); + printk("Signature %c%c%c%c\n", vci->signature[0], vci->signature[1], vci->signature[2], vci->signature[3]); + printk("version %04x\n", vci->version); + printk("total memory %u x 64K\n", vci->total_memory); + printk("OEM software rev: %04X\n", vci->oem_software_rev); + printk("OEM vendor: %s\n", segoff_to_addr(vci->oem_vendor_name_ptr)); + printk("OEM product name: %s\n", segoff_to_addr(vci->oem_product_name_ptr)); + printk("OEM product rev: %s\n", segoff_to_addr(vci->oem_product_rev_ptr)); + + printk("SEG %04X OFFSET %04X\n", vci->video_mode_ptr.segment, vci->video_mode_ptr.offset); + uint16_t *modes = (uint16_t *)segoff_to_addr(vci->video_mode_ptr); + while (*modes != VBE_MODE_END) { + printk("mode: %04x\n", *modes); + // vbe_mode_info_t *mi = get_vbe_mode_info(*modes); + // if (mi->mode_attributes & 0x01) { + // printk("R %u x %u\n", mi->x_resolution, mi->y_resolution); + // } + modes++; + } + system.vbe_phys_addr = vmi->phys_base_ptr; system.x_resolution = vmi->x_resolution; system.y_resolution = vmi->y_resolution; -} \ No newline at end of file + + printk(" phys addr %08x resolution %u x %u\n", system.vbe_phys_addr, system.x_resolution, system.y_resolution); +} diff --git a/gdbscript b/gdbscript index 9dd6925..3af0e80 100644 --- a/gdbscript +++ b/gdbscript @@ -8,8 +8,10 @@ # watch point #wa *0x7c00 -target remote localhost:1234 +break *0x100000 +# break *0xC0100000 +target remote localhost:1234 set pagination off -- 2.44.0