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));
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);
#include <system.h>
#include <types.h>
+// 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;
// 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);
+}