AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
boot.h
Go to the documentation of this file.
1#ifndef _X86_BOOT_H
2#define _X86_BOOT_H
3
4#include_next <boot/boot.h>
5#include <boot/multiboot.h>
6
7#ifdef MULTIBOOT_GFX
8#include <dev/fbdev.h>
9#include <video/vbe.h>
10#include <video/vesa.h>
11#endif
12
13/*
14 * x86: what a Multiboot boot loader passed, turned into the kernel's
15 * struct boot (boot/boot.h): the memory map, the modules (the RAM disk),
16 * the command line, the kernel's symbols, and the framebuffer.
17 */
18
19#define MULTIBOOT_MMAP_MAX 32
20#define MULTIBOOT_MODULES_MAX 32
21
22/*
23 * Converts the Multiboot memory map into the kernel's mmap_t array,
24 * storing at most `max` entries, and returns how many it stored. On i386,
25 * regions starting above 4 GiB are skipped, and regions crossing 4 GiB are
26 * cut there, since the kernel can't address them anyway.
27 */
28static inline int
29build_multiboot_mmap(multiboot_info_t *info, mmap_t *boot_mmap, int max)
30{
31 int count = 0;
32 uint32_t _mmap = info->mmap_addr;
34 uint32_t mmap_end = _mmap + info->mmap_length;
35
36 while (_mmap < mmap_end && count < max) {
37 uint64_t start = mmap->addr;
38 uint64_t end = mmap->addr + mmap->len;
39
40#if ARCH_BITS==32
41 if (start < 0x100000000ULL) {
42 if (end > 0xFFFFFFFFULL || end < start)
43 end = 0xFFFFFFFFULL;
44#else
45 {
46#endif
47
48 boot_mmap[count++] = (mmap_t) {
49 .type = mmap->type,
50 .start = (uintptr_t) start,
51 .end = (uintptr_t) end,
52 };
53 }
54
55 _mmap += mmap->size + sizeof(uint32_t);
56 mmap = (multiboot_mmap_t *)(uintptr_t) _mmap;
57 }
58
59 return count;
60}
61
62/* Converts the Multiboot modules into the kernel's module_t array, storing
63 * at most `max` of them, and returns how many it stored. */
64static inline int
66{
68 int count = 0;
69
70 for (unsigned i = 0; i < info->mods_count && count < max; ++i) {
71 modules[count++] = (module_t) {
72 .paddr = mods[i].mod_start,
73 .size = mods[i].mod_end - mods[i].mod_start,
74 .cmdline = mods[i].cmdline ?
75 (char *) VMA((uintptr_t) mods[i].cmdline) : "",
76 };
77 }
78
79 return count;
80}
81
82/* Reads the Multiboot information that the boot loader passed into the
83 * kernel's struct boot, and returns it. */
84static inline struct boot *process_multiboot_info(multiboot_info_t *info)
85{
86 static struct boot boot;
87
88 if ((info->flags & MULTIBOOT_INFO_CMDLINE) && info->cmdline)
89 boot.cmdline = (char *) VMA((uintptr_t) info->cmdline);
90 else
91 boot.cmdline = "";
92
93 if (info->flags & MULTIBOOT_INFO_MEMORY)
94 boot.total_mem = info->mem_lower + info->mem_upper;
95
96 /* the kernel's section headers, if they're of its own ELF class */
97 if ((info->flags & MULTIBOOT_INFO_ELF_SHDR) && info->u.elf_sec.size == sizeof(elf_shdr_t)) {
98 boot.shdr = (elf_shdr_t *) VMA((uintptr_t) info->u.elf_sec.addr);
99 boot.shdr_num = info->u.elf_sec.num;
100
101 for (size_t i = 0; i < boot.shdr_num; ++i) {
102 elf_shdr_t *shdr = &boot.shdr[i];
103
104 if (shdr->sh_type == SHT_SYMTAB && !boot.symtab) {
106 boot.symtab = shdr;
107 boot.symnum = shdr->sh_size / sizeof(elf_sym_t);
108
109 /* the symbols' names are in the string table that the
110 * symbol table links to, not necessarily the first one */
111 if (shdr->sh_link && shdr->sh_link < boot.shdr_num) {
115 }
116 }
117 }
118
119 /* the symbols are useless without their string table */
120 if (!boot.strtab) {
121 boot.symtab = NULL;
122 boot.symnum = 0;
123 }
124 }
125
126 /* one more entry, for the framebuffer's region */
127 static mmap_t mmap[MULTIBOOT_MMAP_MAX + 1];
128 boot.mmap = mmap;
129 boot.mmap_count = 0;
130
131 if (info->flags & MULTIBOOT_INFO_MEM_MAP)
133
134#ifdef MULTIBOOT_GFX
135 /*
136 * The linear framebuffer, from the VBE mode information (GRUB) or from
137 * Multiboot's framebuffer fields (Limine), if a mode was set. minfo is
138 * read here, through the identity mapping; the fbdev uses the kernel's
139 * mapping of the structures later.
140 */
141 struct mode_info_block *minfo = NULL;
142 static struct fbdev_vesa data;
143
144 if ((info->flags & MULTIBOOT_INFO_VIDEO_INFO) && info->vbe_mode_info) {
145 minfo = (struct mode_info_block *)(uintptr_t) info->vbe_mode_info;
146 data.vbe_info = (struct vbe_info_block *) VMA(info->vbe_control_info);
147 data.mode_info = (struct mode_info_block *) VMA(info->vbe_mode_info);
148 } else if ((info->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) &&
150 !(info->framebuffer_addr >> 32)) {
151 /* describe it as a VBE mode, for the vesa fbdev */
152 static struct mode_info_block fb_minfo;
153
154 fb_minfo.phys_base_ptr = info->framebuffer_addr;
155 fb_minfo.bytes_per_scanline = info->framebuffer_pitch;
157 fb_minfo.x_resolution = info->framebuffer_width;
158 fb_minfo.y_resolution = info->framebuffer_height;
159 fb_minfo.bits_per_pixel = info->framebuffer_bpp;
160
161 /* the positions and sizes of red, green and blue */
162 uint8_t *color = info->framebuffer_color_info;
163 fb_minfo.red_field_position = color[0];
164 fb_minfo.red_mask_size = color[1];
165 fb_minfo.green_field_position = color[2];
166 fb_minfo.green_mask_size = color[3];
167 fb_minfo.blue_field_position = color[4];
168 fb_minfo.blue_mask_size = color[5];
169
170 minfo = &fb_minfo;
171 data.vbe_info = NULL;
172 data.mode_info = &fb_minfo;
173 }
174
175 if (minfo) {
176 uintptr_t paddr = minfo->phys_base_ptr;
177 uint32_t scanline = minfo->lin_bytes_per_scanline;
178 uint32_t yres = minfo->y_resolution;
179 uint32_t xres = minfo->x_resolution;
180 uint32_t depth = minfo->bits_per_pixel;
181
182 /* the framebuffer's memory is a reserved region of the map */
184 .type = MMAP_RESERVED,
185 .start = paddr,
186 .end = paddr + yres * scanline,
187 };
188
190
192 earlycon_fb_register(paddr, scanline, yres, xres, depth);
193
194 /* and it is a vesa fbdev, /dev/fb0 */
196 }
197#endif
198
199 static module_t modules[MULTIBOOT_MODULES_MAX];
200 boot.modules = modules;
202
203 if (info->flags & MULTIBOOT_INFO_MODS)
205
206 return &boot;
207}
208
209#endif /* _X86_BOOT_H */
#define VMA(obj)
Definition mm.h:36
void earlycon_fb_register(uintptr_t paddr, uint32_t scanline, uint32_t yres, uint32_t xres, uint32_t depth)
Registers the boot loader's framebuffer, for the early console.
Definition fb.c:40
static int build_multiboot_modules(multiboot_info_t *info, module_t *modules, int max)
Definition boot.h:65
static struct boot * process_multiboot_info(multiboot_info_t *info)
Definition boot.h:84
#define MULTIBOOT_MODULES_MAX
Definition boot.h:20
static int build_multiboot_mmap(multiboot_info_t *info, mmap_t *boot_mmap, int max)
Definition boot.h:29
#define MULTIBOOT_MMAP_MAX
Definition boot.h:19
#define SHT_SYMTAB
Definition elf.h:75
struct elf32_sym elf_sym_t
Definition elf.h:224
struct elf32_shdr elf_shdr_t
Definition elf.h:223
int fbdev_register(int type, void *data)
Registers a framebuffer, which fbdev_probe() sets up with its driver.
Definition fbdev.c:37
#define FBDEV_TYPE_VESA
Definition fbdev.h:11
@ MMAP_RESERVED
Definition boot.h:24
multiboot.h - Multiboot header file.
struct multiboot_mmap_entry multiboot_mmap_t
Definition multiboot.h:219
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO
Definition multiboot.h:95
#define MULTIBOOT_INFO_MEMORY
Definition multiboot.h:61
#define MULTIBOOT_INFO_VIDEO_INFO
Definition multiboot.h:92
#define MULTIBOOT_INFO_MEM_MAP
Definition multiboot.h:77
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB
Definition multiboot.h:203
struct multiboot_mod_list multiboot_module_t
Definition multiboot.h:233
struct multiboot_info multiboot_info_t
Definition multiboot.h:208
#define MULTIBOOT_INFO_MODS
Definition multiboot.h:67
#define MULTIBOOT_INFO_ELF_SHDR
Definition multiboot.h:74
#define MULTIBOOT_INFO_CMDLINE
Definition multiboot.h:65
#define NULL
Definition stddef.h:27
__SIZE_TYPE__ uintptr_t
Definition stddef.h:12
unsigned int uint32_t
Definition stddef.h:22
unsigned char uint8_t
Definition stddef.h:20
unsigned long long int uint64_t
Definition stddef.h:23
Definition boot.h:35
int mmap_count
Definition boot.h:40
char * cmdline
Definition boot.h:36
module_t * modules
Definition boot.h:41
elf_shdr_t * symtab
Definition boot.h:49
uint32_t shdr_num
Definition boot.h:47
size_t symnum
Definition boot.h:50
uintptr_t total_mem
Definition boot.h:37
elf_shdr_t * strtab
Definition boot.h:52
elf_shdr_t * shdr
Definition boot.h:46
mmap_t * mmap
Definition boot.h:42
int modules_count
Definition boot.h:39
elf32_addr sh_addr
Definition elf.h:173
elf32_word sh_type
Definition elf.h:171
elf32_word sh_size
Definition elf.h:175
elf32_word sh_link
Definition elf.h:176
The boot loader's VBE framebuffer: what VBE said about the card and the mode (dev/fb/vesa/).
Definition vesa.h:8
struct mode_info_block * mode_info
Definition vesa.h:10
struct vbe_info_block * vbe_info
Definition vesa.h:9
Definition boot.h:28
A VBE mode's information block.
Definition vbe.h:33
uint8_t bits_per_pixel
Definition vbe.h:50
uint8_t red_field_position
Definition vbe.h:58
uint8_t blue_mask_size
Definition vbe.h:61
uint16_t bytes_per_scanline
Definition vbe.h:43
uint8_t red_mask_size
Definition vbe.h:57
uint8_t blue_field_position
Definition vbe.h:62
uint8_t green_mask_size
Definition vbe.h:59
uint16_t x_resolution
Definition vbe.h:45
uint8_t green_field_position
Definition vbe.h:60
uint32_t phys_base_ptr
Definition vbe.h:67
uint16_t y_resolution
Definition vbe.h:46
uint16_t lin_bytes_per_scanline
Definition vbe.h:71
uint32_t vbe_control_info
Definition multiboot.h:189
uint32_t flags
Definition multiboot.h:149
uint32_t vbe_mode_info
Definition multiboot.h:190
uint8_t framebuffer_type
Definition multiboot.h:205
uint32_t framebuffer_pitch
Definition multiboot.h:198
uint32_t mmap_length
Definition multiboot.h:172
union multiboot_info::@271253110040301035057036353331356106057115263040 u
uint32_t mem_lower
Definition multiboot.h:152
uint32_t mem_upper
Definition multiboot.h:153
uint32_t mods_addr
Definition multiboot.h:163
uint32_t cmdline
Definition multiboot.h:159
uint32_t mmap_addr
Definition multiboot.h:173
uint8_t framebuffer_color_info[6]
Definition multiboot.h:206
uint64_t framebuffer_addr
Definition multiboot.h:197
uint32_t framebuffer_width
Definition multiboot.h:199
uint32_t mods_count
Definition multiboot.h:162
uint32_t framebuffer_height
Definition multiboot.h:200
uint8_t framebuffer_bpp
Definition multiboot.h:201
uint32_t type
Definition multiboot.h:217
uint64_t len
Definition multiboot.h:214
uint64_t addr
Definition multiboot.h:213
uint32_t size
Definition multiboot.h:212
The VBE controller information block.
Definition vbe.h:13