:: limine / test / multiboot2.c 7.3 KB raw

1
#include <e9print.h>
2
#include <stdint.h>
3
#include <multiboot2.h>
4
5
struct multiboot_info {
6
    uint32_t size;
7
    uint32_t reserved;
8
    struct multiboot_tag *first;
9
};
10
11
void multiboot2_main(uint32_t magic, struct multiboot_info* mb_info_addr) {
12
    if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
13
        e9_printf("multiboot2: Invalid magic: %x\n", magic);
14
        goto out;
15
    }
16
17
    e9_printf("Welcome to the multiboot2 test kernel: ");
18
    e9_printf("\t size=%d", mb_info_addr->size);
19
    e9_printf("\t reserved=%d", mb_info_addr->reserved);
20
21
    e9_print("\nTags:\n");
22
23
    size_t add_size = 0;
24
25
    // NOTE: We set i to 8 to skip size and reserved fields:
26
    for (size_t i = 8; i < mb_info_addr->size; i += add_size) {
27
        struct multiboot_tag *tag = (struct multiboot_tag *)((uint8_t *)mb_info_addr + i);
28
29
        if (tag->type == MULTIBOOT_TAG_TYPE_END) {
30
            break;
31
        }
32
33
        switch (tag->type) {
34
            case MULTIBOOT_TAG_TYPE_CMDLINE: {
35
                struct multiboot_tag_string *cmdline = (struct multiboot_tag_string *)tag;
36
                e9_printf("\t cmdline:");
37
                e9_printf("\t\t string=%s", cmdline->string);
38
                break;
39
            }
40
41
            case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: {
42
                struct multiboot_tag_string *name = (struct multiboot_tag_string *)tag;
43
                e9_printf("\t bootloader_name:");
44
                e9_printf("\t\t string=%s", name->string);
45
                break;
46
            }
47
48
            case MULTIBOOT_TAG_TYPE_ACPI_OLD: {
49
                struct multiboot_tag_old_acpi *old_acpi = (struct multiboot_tag_old_acpi *)tag;
50
                e9_printf("\t acpi_old:");
51
                e9_printf("\t\t rsdp=%s", old_acpi->rsdp);
52
                break;
53
            }
54
55
            case MULTIBOOT_TAG_TYPE_ACPI_NEW: {
56
                struct multiboot_tag_new_acpi *new_acpi = (struct multiboot_tag_new_acpi *)tag;
57
                e9_printf("\t acpi_new:");
58
                e9_printf("\t\t rsdp=%s", new_acpi->rsdp);
59
                break;
60
            }
61
62
            case MULTIBOOT_TAG_TYPE_MODULE: {
63
                struct multiboot_tag_module *module = (struct multiboot_tag_module *)tag;
64
                e9_printf("\t module:");
65
                e9_printf("\t\t mod_start=%x", module->mod_start);
66
                e9_printf("\t\t mod_end=%x", module->mod_end);
67
                e9_printf("\t\t cmdline=%s", module->cmdline);
68
                break;
69
            }
70
71
            case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: {
72
                struct multiboot_tag_basic_meminfo *meminfo = (struct multiboot_tag_basic_meminfo *)tag;
73
                e9_printf("\t basic_meminfo:");
74
                e9_printf("\t\t mem_lower=%x", meminfo->mem_lower);
75
                e9_printf("\t\t mem_upper=%x", meminfo->mem_upper);
76
                break;
77
            }
78
79
            // unimplemented(Andy-Python-Programmer): MULTIBOOT_TAG_TYPE_BOOTDEV
80
81
            case MULTIBOOT_TAG_TYPE_MMAP: {
82
                struct multiboot_tag_mmap *mmap = (struct multiboot_tag_mmap *)tag;
83
                e9_printf("\t mmap:");
84
                e9_printf("\t\t entry_size=%d", mmap->entry_size);
85
                e9_printf("\t\t entry_version=%d", mmap->entry_version);
86
                e9_printf("\t\t entries:");
87
88
                struct multiboot_mmap_entry *m = (struct multiboot_mmap_entry *)(mmap->entries);
89
90
                size_t entry_count = (mmap->size - sizeof(struct multiboot_tag_mmap)) / sizeof(struct multiboot_mmap_entry);
91
                e9_printf("\t\t entry count: %d", entry_count);
92
93
                for (size_t i = 0; i < entry_count; i++) {
94
                    e9_printf("\t\t\t addr=%x", m[i].addr);
95
                    e9_printf("\t\t\t len=%x", m[i].len);
96
                    e9_printf("\t\t\t type=%x", m[i].type);
97
                }
98
99
                break;
100
            }
101
102
            case MULTIBOOT_TAG_TYPE_EFI_MMAP: {
103
                struct multiboot_tag_efi_mmap *mmap = (struct multiboot_tag_efi_mmap *)tag;
104
                e9_printf("\t efi_mmap:");
105
                e9_printf("\t\t descr_vers=%d", mmap->descr_vers);
106
                e9_printf("\t\t descr_size=%d", mmap->descr_size);
107
                e9_printf("\t\t size=%d", mmap->size);
108
                e9_printf("\t\t entries:");
109
110
                struct memory_descriptor {
111
                    uint32_t type;
112
                    uint32_t pad;
113
                    uint64_t physical_start;
114
                    uint64_t virtual_start;
115
                    uint64_t pages;
116
                    uint64_t attribute;
117
                };
118
119
                size_t entry_count = (mmap->size - sizeof(struct multiboot_tag_efi_mmap)) / mmap->descr_size;
120
                e9_printf("\t\t entry count: %d", entry_count);
121
122
                for (size_t i = 0; i < entry_count; i++) {
123
                    struct memory_descriptor *m = (struct memory_descriptor *)(mmap->efi_mmap + i * mmap->descr_size);
124
125
                    e9_printf("\t\t\t type=%x", m->type);
126
                    e9_printf("\t\t\t physical_start=%x", m->physical_start);
127
                    e9_printf("\t\t\t virtual_start=%x", m->virtual_start);
128
                    e9_printf("\t\t\t pages=%x", m->pages);
129
                    e9_printf("\t\t\t attribute=%x", m->attribute);
130
                }
131
132
                break;
133
            }
134
135
            // unimplemented(Andy-Python-Programmer): MULTIBOOT_TAG_TYPE_VBE
136
137
            case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: {
138
                struct multiboot_tag_framebuffer *fb = (struct multiboot_tag_framebuffer *)tag;
139
140
                e9_printf("\t framebuffer:");
141
                e9_printf("\t\t framebuffer_pitch: %d", fb->common.framebuffer_pitch);
142
                e9_printf("\t\t framebuffer_width: %d", fb->common.framebuffer_width);
143
                e9_printf("\t\t framebuffer_height: %d", fb->common.framebuffer_height);
144
                e9_printf("\t\t framebuffer_bpp: %d", fb->common.framebuffer_bpp);
145
                e9_printf("\t\t framebuffer_type: %d", fb->common.framebuffer_type);
146
                e9_printf("\t\t framebuffer_address: %x", fb->common.framebuffer_addr);
147
148
                switch (fb->common.framebuffer_type) {
149
                    case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: {
150
                        e9_printf("\t\t framebuffer_red_field_position: %x", fb->framebuffer_red_field_position);
151
                        e9_printf("\t\t framebuffer_red_mask_size: %x", fb->framebuffer_red_mask_size);
152
                        e9_printf("\t\t framebuffer_green_field_position: %x", fb->framebuffer_green_field_position);
153
                        e9_printf("\t\t framebuffer_green_mask_size: %x", fb->framebuffer_green_mask_size);
154
                        e9_printf("\t\t framebuffer_blue_field_position: %x", fb->framebuffer_blue_field_position);
155
                        e9_printf("\t\t framebuffer_blue_mask_size: %x", fb->framebuffer_blue_mask_size);
156
                        break;
157
                    }
158
159
                    // Rest are unimplemented(Andy-Python-Programmer):
160
                }
161
162
                break;
163
            }
164
165
            case MULTIBOOT_TAG_TYPE_NETWORK: {
166
                struct multiboot_tag_network *network = (struct multiboot_tag_network *)tag;
167
                e9_printf("\t network tag exists");
168
                break;
169
            }
170
        }
171
172
        add_size = tag->size;
173
174
        // Align the size to 8 bytes.
175
        if ((add_size % 8) != 0)
176
			add_size += (8 - add_size % 8);
177
    }
178
179
out:
180
    for (;;);
181
}
tab: 248 wrap: offon