# vga: extension=cirrus, update_freq=10, ddc=builtin
#=======================================================================
#vga: extension=vbe, update_freq=5, realtime=1, ddc=file:monitor.bin
+vga: extension=vbe, update_freq=5, realtime=1, ddc=builtin
#=======================================================================
# VOODOO:
struct boot_params boot_params __attribute__((aligned(32)));
void parse_cmdline(const char *cmdline);
-
+void init_vbe(void *vmiptr);
void check_kernel(unsigned long addr, unsigned long magic) {
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
printk("Your boot loader does not support multiboot.\n");
printk("total size: %d tags: %x\n", total_size, tag);
struct multiboot_tag_basic_meminfo *mminfo = 0;
- multiboot_memory_map_t *mmap = 0;
- struct multiboot_tag_mmap *mmap_tag = 0;
struct multiboot_tag_bootdev *bootdev = 0;
+ struct multiboot_tag_mmap *mmap_tag = 0;
+ struct multiboot_tag_vbe *vbe = 0;
+ struct multiboot_tag_framebuffer *fb = 0;
boot_params.e820map.map_cnt = 0;
break;
case MULTIBOOT_TAG_TYPE_MMAP:
mmap_tag = (struct multiboot_tag_mmap *)tag;
- mmap = mmap_tag->entries;
+ multiboot_memory_map_t *mmap = mmap_tag->entries;
while (((multiboot_uint32_t)mmap) < (((multiboot_uint32_t)mmap_tag) + mmap_tag->size)) {
boot_params.e820map.map[boot_params.e820map.map_cnt].addr = mmap->addr;
boot_params.e820map.map[boot_params.e820map.map_cnt].size = mmap->len;
mmap = (multiboot_memory_map_t *)(((unsigned long)mmap) + mmap_tag->entry_size);
}
break;
+ case MULTIBOOT_TAG_TYPE_VBE:
+ 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));
+ init_vbe(vmi);
+ break;
+ case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
+ asm volatile("xchg %bx, %bx;nop;nop;nop;nop;");
+ break;
default:
printk("tag %x size %x\n", tag->type, tag->size);
break;
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);
- while (1)
- ;
+ // while (1)
+ // ;
}
# checksum
.long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot2_header_end - multiboot2_header_bgn))
- // .align 8
- // .framebuffer_tag_bgn:
- // .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
- // .short MULTIBOOT_HEADER_TAG_OPTIONAL
- // .long .framebuffer_tag_end - .framebuffer_tag_bgn
- // .long 1280
- // .long 800
- // .long 32
- // .framebuffer_tag_end:
+ .align 8
+ .framebuffer_tag_bgn:
+ .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
+ .short MULTIBOOT_HEADER_TAG_OPTIONAL
+ .long .framebuffer_tag_end - .framebuffer_tag_bgn
+ .long 1280
+ .long 800
+ .long 32
+ .framebuffer_tag_end:
.align 8
.multiboot2_tag_end:
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: vbe.c
+ * Author: Zhao Yanbai
+ * 2021-11-06 15:56:23 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <linkage.h>
+// #include <page.h>
+#include <system.h>
+#include <types.h>
+typedef struct vbe_mode_info {
+ u16 mode_attributes;
+ u8 wina_attributes;
+ u8 winb_attributes;
+ u16 win_granularity;
+ u16 win_size;
+ u16 wina_segment;
+ u16 winb_segment;
+ u32 win_func_ptr;
+ u16 bytes_per_scan_line;
+ u16 x_resolution;
+ u16 y_resolution;
+ u8 xchar_size;
+ u8 ychar_size;
+ u8 number_of_planes;
+ u8 bits_per_pixel;
+ u8 number_of_banks;
+ u8 memory_model;
+ u8 bank_size;
+ u8 number_of_image_pages;
+ u8 _reserved0;
+ u8 red_mask_size;
+ u8 red_field_position;
+ u8 green_mask_size;
+ u8 green_field_position;
+ u8 blue_mask_size;
+ u8 blue_field_position;
+ u8 rsvd_mask_size;
+ u8 rsvd_field_position;
+ u8 direct_color_mode_info;
+ u32 phys_base_ptr;
+ u32 _reserved1;
+ u16 _reserved2;
+ u16 lin_bytes_per_scan_line;
+ u8 bank_number_of_image_pages;
+ u8 lin_number_of_image_pages;
+ u8 lin_red_mask_size;
+ u8 lin_red_field_position;
+ u8 lin_green_mask_size;
+ u8 lin_green_field_position;
+ u8 lin_blue_mask_size;
+ u8 lin_blue_field_position;
+ u8 lin_rvsd_mask_size;
+ u8 lin_rvsd_field_position;
+ u32 max_pixel_clock;
+ u8 _reserved3[189];
+} __attribute__((packed)) vbe_mode_info_t;
+
+// pte_t vbe_pte[PTECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
+
+// extern pde_t init_pgd[];
+void init_vbe(void *vmiptr) {
+ vbe_mode_info_t *vmi = (vbe_mode_info_t *)vmiptr;
+ system.vbe_phys_addr = vmi->phys_base_ptr;
+ system.x_resolution = vmi->x_resolution;
+ system.y_resolution = vmi->y_resolution;
+ // unsigned long phys_base_addr = vmi->phys_base_ptr;
+
+ // asm volatile("xchg %%bx, %%bx;nop;" ::"a"(phys_base_addr));
+
+ // init_pgd[phys_base_addr >> 22] = va2pa(vbe_pte) | 7;
+ // asm volatile("xchg %bx, %bx;nop;nop;nop;nop;");
+ // for (int i = 0; i < PTECNT_PER_PAGE; i++) {
+ // vbe_pte[i] = phys_base_addr + i * PAGE_SIZE + 7;
+ // }
+ // asm volatile("xchg %bx, %bx;nop;nop;nop;nop;");
+ // unsigned long *p = (unsigned long *)phys_base_addr;
+ // for (int i = 0; i < 1024; i++) {
+ // p[i] = 0x00FF0000;
+ // }
+}
\ No newline at end of file
#define MAX_ORDER (11)
-#define LoadCR3(cr3) asm volatile ("movl %%edx, %%cr3"::"d"(cr3))
+#define LoadCR3(cr3) asm volatile("movl %%edx, %%cr3" ::"d"(cr3))
typedef unsigned int gfp_t;
#define ALIGN(x, a) (((x) + (a)-1) & ~((a)-1))
-// 1 GB
-#define MAX_SUPT_PHYMM_SIZE (1UL << 30)
+// 定义最大显存为 16MB
+#define VRAM_VADDR_SIZE (16 << 20)
+
+// 最大支持的线性地址空间为1G
+#define MAX_SUPT_VADDR_SIZE (1UL << 30)
+
+// 把内核线性地址的最高部分留给显存
+// 余下的部分为支持映射其它物理内存的空间
+#define MAX_SUPT_PHYMM_SIZE (MAX_SUPT_VADDR_SIZE - VRAM_VADDR_SIZE)
+
+// 算出显存的线性地址
+// 之后要将这个地址映射到显存的物理地址
+#define VRAM_VADDR_BASE (PAGE_OFFSET + MAX_SUPT_PHYMM_SIZE)
#define INT_STACK_SIZE PAGE_SIZE
// More Infomation see 'info multiboot'
u32 boot_device;
+ u32 vbe_phys_addr;
+ u16 x_resolution;
+ u16 y_resolution;
+
dev_t root_dev;
#define CMD_LINE_SIZE 128
const char *cmdline;
unsigned long max_support_pfn = PFN_DW(MAX_SUPT_PHYMM_SIZE);
if (bootmem_data.max_pfn > max_support_pfn) {
bootmem_data.max_pfn = max_support_pfn;
- printk("memory > 1G, only support to 1G.\n");
+ unsigned long ms = max_support_pfn / 1024 * 4; // 1024个pfn正好4MB
+ printk("memory > %dMB, only support to %dMB.\n", ms, ms);
}
printk("pfn_min: %d pfn_max: %d\n", bootmem_data.min_pfn, bootmem_data.max_pfn);
unsigned int i;
unsigned long pfn = 0;
pte_t *pte = 0;
- unsigned long pgtb_addr = 0;
+ unsigned long *pgtb_addr = 0;
+ void *alloc_from_bootmem(unsigned long size, char *title);
// 在multiboot.S是已经初始化了BOOT_INIT_PAGETBL_CNT个页
// 这里接着初始化剩余的页
unsigned long ti = pfn % PAGE_PTE_CNT;
unsigned long page_addr = pfn2pa(pfn);
if (ti == 0) {
- void *alloc_from_bootmem(unsigned long size, char *title);
- pgtb_addr = (unsigned long)va2pa(alloc_from_bootmem(PAGE_SIZE, "paging"));
- if (0 == pgtb_addr) panic("No Pages for Paging...");
+ pgtb_addr = (unsigned long *)alloc_from_bootmem(PAGE_SIZE, "paging");
+ if (0 == pgtb_addr) {
+ panic("no pages for paging...");
+ }
memset((void *)pgtb_addr, 0, PAGE_SIZE);
- init_pgd[get_npd(page_addr)] = (pde_t)(pgtb_addr | PAGE_P | PAGE_WR);
+ init_pgd[get_npd(page_addr)] = (pde_t)((unsigned long)va2pa(pgtb_addr) | PAGE_P | PAGE_WR);
}
- pte = ((pte_t *)pa2va(pgtb_addr)) + ti;
+ pte = ((pte_t *)pgtb_addr) + ti;
*pte = (pte_t)(page_addr | PAGE_P | PAGE_WR);
}
init_pgd[i - delta] = 0;
}
+ // 接下来为显存建立页映射
+ unsigned long vram_phys_addr = system.vbe_phys_addr;
+ for (int pde_inx = 0; pde_inx < get_npd(VRAM_VADDR_SIZE); pde_inx++) {
+ pgtb_addr = (unsigned long *)(alloc_from_bootmem(PAGE_SIZE, "vrampaging"));
+ if (0 == pgtb_addr) {
+ panic("no pages for paging...");
+ }
+ // 后续要初始化,所以此处不用memset
+ // memset((void *)pgtb_addr, 0, PAGE_SIZE);
+ init_pgd[get_npd(VRAM_VADDR_BASE) + pde_inx] = (pde_t)((unsigned long)va2pa(pgtb_addr) | PAGE_P | PAGE_WR);
+
+ for (int pte_inx = 0; pte_inx < PTECNT_PER_PAGE; pte_inx++) {
+ pgtb_addr[pte_inx] = vram_phys_addr | PAGE_P | PAGE_WR;
+ vram_phys_addr += PAGE_SIZE;
+ }
+ }
+
// paging for user space
extern void sysexit();
set_page_shared(sysexit);
LoadCR3(va2pa(init_pgd));
+
+ // 测试显存
+ for (int i = 0; i < 4096; i++) {
+ unsigned long *vram = (unsigned long *)VRAM_VADDR_BASE;
+ vram[i] = 0x00FF0000;
+ }
}
void init_mm() {