2022-01-13 14:01:51 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <kernaux/multiboot2.h>
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
2022-01-13 14:32:19 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
2022-01-13 14:01:51 +00:00
|
|
|
|
|
|
|
bool KernAux_Multiboot2_Header_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_Header *const multiboot2_header
|
|
|
|
) {
|
2022-01-13 14:41:50 +00:00
|
|
|
if (multiboot2_header->magic != KERNAUX_MULTIBOOT2_MAGIC) return false;
|
|
|
|
|
|
|
|
if (multiboot2_header->arch != KERNAUX_MULTIBOOT2_ARCH_I386 &&
|
|
|
|
multiboot2_header->arch != KERNAUX_MULTIBOOT2_ARCH_MIPS32)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-13 14:32:19 +00:00
|
|
|
if (multiboot2_header->total_size <
|
|
|
|
sizeof(struct KernAux_Multiboot2_Header) +
|
|
|
|
sizeof(struct KernAux_Multiboot2_HTag_None))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-13 14:43:57 +00:00
|
|
|
if (multiboot2_header->total_size % KERNAUX_MULTIBOOT2_TAG_ALIGN != 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-13 14:41:50 +00:00
|
|
|
if (multiboot2_header->checksum !=
|
|
|
|
KERNAUX_MULTIBOOT2_CHECKSUM(
|
|
|
|
multiboot2_header->arch,
|
|
|
|
multiboot2_header->total_size
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-13 14:32:19 +00:00
|
|
|
const struct KernAux_Multiboot2_HTagBase *tag_base =
|
|
|
|
(struct KernAux_Multiboot2_HTagBase*)
|
|
|
|
KERNAUX_MULTIBOOT2_DATA(multiboot2_header);
|
|
|
|
|
|
|
|
const struct KernAux_Multiboot2_HTagBase *none_tag_base = NULL;
|
|
|
|
|
|
|
|
while (tag_base <
|
|
|
|
(struct KernAux_Multiboot2_HTagBase*)
|
|
|
|
((uint8_t*)multiboot2_header + multiboot2_header->total_size))
|
|
|
|
{
|
|
|
|
if (!KernAux_Multiboot2_HTagBase_is_valid(tag_base)) return false;
|
|
|
|
|
|
|
|
if (tag_base->type == KERNAUX_MULTIBOOT2_HTAG_NONE &&
|
|
|
|
none_tag_base == NULL
|
|
|
|
) {
|
|
|
|
none_tag_base = tag_base;
|
|
|
|
}
|
|
|
|
|
|
|
|
tag_base = KERNAUX_MULTIBOOT2_HTAG_NEXT(tag_base);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tag_base !=
|
|
|
|
(struct KernAux_Multiboot2_HTagBase*)
|
|
|
|
((uint8_t*)multiboot2_header + multiboot2_header->total_size))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (none_tag_base !=
|
|
|
|
(struct KernAux_Multiboot2_HTagBase*)
|
|
|
|
((uint8_t*)tag_base -
|
|
|
|
sizeof(struct KernAux_Multiboot2_HTag_None)))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2022-01-13 14:01:51 +00:00
|
|
|
}
|
2022-01-13 14:23:24 +00:00
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTagBase_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTagBase *tag_base
|
|
|
|
) {
|
2022-01-13 14:36:58 +00:00
|
|
|
switch (tag_base->type) {
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_NONE:
|
|
|
|
return KernAux_Multiboot2_HTag_None_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_None*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_INFO_REQ:
|
|
|
|
return KernAux_Multiboot2_HTag_InfoReq_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_InfoReq*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_ADDR:
|
|
|
|
return KernAux_Multiboot2_HTag_Addr_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_Addr*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_ENTRY_ADDR:
|
|
|
|
return KernAux_Multiboot2_HTag_EntryAddr_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_EntryAddr*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_FLAGS:
|
|
|
|
return KernAux_Multiboot2_HTag_Flags_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_Flags*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_FRAMEBUFFER:
|
|
|
|
return KernAux_Multiboot2_HTag_Framebuffer_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_Framebuffer*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_MODULE_ALIGN:
|
|
|
|
return KernAux_Multiboot2_HTag_ModuleAlign_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_ModuleAlign*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_EFI_BOOT_SERVICES:
|
|
|
|
return KernAux_Multiboot2_HTag_EFIBootServices_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_EFIBootServices*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_EFI_I386_ENTRY_ADDR:
|
|
|
|
return KernAux_Multiboot2_HTag_EFII386EntryAddr_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_EFII386EntryAddr*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_EFI_AMD64_ENTRY_ADDR:
|
|
|
|
return KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr*)tag_base
|
|
|
|
);
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER:
|
|
|
|
return KernAux_Multiboot2_HTag_RelocatableHeader_is_valid(
|
|
|
|
(struct KernAux_Multiboot2_HTag_RelocatableHeader*)tag_base
|
|
|
|
);
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_None_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_None *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_NONE &&
|
|
|
|
tag->base.size == 8
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_InfoReq_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_InfoReq *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_INFO_REQ &&
|
|
|
|
tag->base.size > 8 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_Addr_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_Addr *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_ADDR &&
|
|
|
|
tag->base.size == 24 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_EntryAddr_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_EntryAddr *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_ENTRY_ADDR &&
|
|
|
|
tag->base.size == 12 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_Flags_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_Flags *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_FLAGS &&
|
|
|
|
tag->base.size == 12 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_Framebuffer_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_Framebuffer *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_FRAMEBUFFER &&
|
|
|
|
tag->base.size == 20 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_ModuleAlign_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_ModuleAlign *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_MODULE_ALIGN &&
|
|
|
|
tag->base.size == 8
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_EFIBootServices_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_EFIBootServices *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_EFI_BOOT_SERVICES &&
|
|
|
|
tag->base.size == 8
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_EFII386EntryAddr_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_EFII386EntryAddr *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_EFI_I386_ENTRY_ADDR &&
|
|
|
|
tag->base.size == 12 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_EFIAmd64EntryAddr_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_EFIAmd64EntryAddr *tag
|
|
|
|
) {
|
2022-01-13 14:50:52 +00:00
|
|
|
return (
|
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_EFI_AMD64_ENTRY_ADDR &&
|
|
|
|
tag->base.size == 12 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
|
|
|
);
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KernAux_Multiboot2_HTag_RelocatableHeader_is_valid(
|
|
|
|
const struct KernAux_Multiboot2_HTag_RelocatableHeader *tag
|
|
|
|
) {
|
2022-01-14 04:43:59 +00:00
|
|
|
if (!(
|
2022-01-13 14:50:52 +00:00
|
|
|
tag->base.type == KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER &&
|
|
|
|
tag->base.size == 24 &&
|
|
|
|
// TODO: write this
|
|
|
|
true
|
2022-01-14 04:43:59 +00:00
|
|
|
)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (tag->preferences) {
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER_PREFERENCE_NONE: break;
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER_PREFERENCE_LOWEST: break;
|
|
|
|
case KERNAUX_MULTIBOOT2_HTAG_RELOCATABLE_HEADER_PREFERENCE_HIGHEST: break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2022-01-13 14:23:24 +00:00
|
|
|
}
|