kernel/kernel/info.c

131 lines
3.4 KiB
C
Raw Normal View History

2017-11-09 16:00:36 +00:00
#include "info.h"
2021-12-17 22:35:04 +00:00
#include <kernaux/libc.h>
2021-12-17 22:32:04 +00:00
static bool cmdline_terminated(const char *s);
2017-11-04 14:03:45 +00:00
2021-12-17 22:45:22 +00:00
void kernel_info_initialize(
struct Kernel_Info *const kinfo,
const size_t offset,
const size_t size,
const size_t phys_base,
const size_t virt_base,
const size_t stack_top
) {
2021-12-17 22:35:04 +00:00
memset(kinfo, 0, sizeof(*kinfo));
2021-12-17 22:45:22 +00:00
kinfo->kernel_offset = offset;
kinfo->kernel_size = size;
kinfo->kernel_phys_base = phys_base;
kinfo->kernel_virt_base = virt_base;
kinfo->kernel_phys_limit = phys_base + size - 1;
kinfo->kernel_virt_limit = virt_base + size - 1;
kinfo->kernel_stack_top = stack_top;
2021-12-17 22:35:04 +00:00
}
2021-12-17 22:32:04 +00:00
bool kernel_info_validate(const struct Kernel_Info *const kinfo)
2020-11-26 18:50:25 +00:00
{
2021-12-17 22:32:04 +00:00
if (!kinfo) return false;
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
if (!cmdline_terminated(kinfo->cmdline)) return false;
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
if (kinfo->modules_count > KERNEL_INFO_MODULES_MAX) return false;
if (kinfo->areas_count > KERNEL_INFO_AREAS_MAX) return false;
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
if (kinfo->kernel_offset == 0) return false;
if (kinfo->kernel_size == 0) return false;
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
if (kinfo->kernel_phys_base + kinfo->kernel_size !=
kinfo->kernel_phys_limit + 1)
{
return false;
2017-11-04 14:03:45 +00:00
}
2021-12-17 22:32:04 +00:00
if (kinfo->kernel_virt_base + kinfo->kernel_size !=
kinfo->kernel_virt_limit + 1)
{
return false;
2017-11-04 14:03:45 +00:00
}
2021-12-17 22:32:04 +00:00
if (kinfo->kernel_virt_base - kinfo->kernel_phys_base !=
kinfo->kernel_offset)
{
return false;
2017-11-04 14:03:45 +00:00
}
2021-12-17 22:32:04 +00:00
size_t modules_total_size = 0;
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
for (size_t i = 0; i < kinfo->modules_count; ++i) {
2021-12-12 14:00:17 +00:00
const struct Kernel_Info_Module *const module = &kinfo->modules[i];
2017-11-04 14:03:45 +00:00
modules_total_size += module->size;
2021-12-17 22:32:04 +00:00
if (module->size == 0) return false;
if (module->base + module->size != module->limit + 1) return false;
if (!cmdline_terminated(module->cmdline)) return false;
2017-11-04 14:03:45 +00:00
}
2021-12-17 22:32:04 +00:00
if (kinfo->modules_total_size != modules_total_size) return false;
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
if (kinfo->kernel_and_modules_total_size !=
kinfo->kernel_size + kinfo->modules_total_size)
{
return false;
2017-11-04 14:03:45 +00:00
}
2021-12-17 22:32:04 +00:00
uint64_t last = 0;
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
for (size_t i = 0; i < kinfo->areas_count; ++i) {
2021-12-12 14:00:17 +00:00
const struct Kernel_Info_Area *const area = &kinfo->areas[i];
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
if (last > area->base) return false;
if (area->size == 0) return false;
if (area->base + area->size != area->limit + 1) return false;
2017-11-04 14:03:45 +00:00
last = area->limit + 1;
if (!area->is_available) {
2020-11-26 18:50:25 +00:00
if (kinfo->kernel_phys_base >= area->base &&
2021-12-17 22:32:04 +00:00
kinfo->kernel_phys_base <= area->limit)
{
return false;
2017-11-04 14:03:45 +00:00
}
2020-11-26 18:50:25 +00:00
if (kinfo->kernel_phys_limit >= area->base &&
2021-12-17 22:32:04 +00:00
kinfo->kernel_phys_limit <= area->limit)
{
return false;
2017-11-04 14:03:45 +00:00
}
2020-11-26 18:50:25 +00:00
for (unsigned int j = 0; j < kinfo->modules_count; ++j) {
2021-12-17 22:32:04 +00:00
const struct Kernel_Info_Module *const module =
&kinfo->modules[j];
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
if (module->base >= area->base && module->base <= area->limit) {
return false;
2017-11-04 14:03:45 +00:00
}
if (module->limit >= area->base &&
2021-12-17 22:32:04 +00:00
module->limit <= area->limit)
{
return false;
2017-11-04 14:03:45 +00:00
}
}
}
}
return 1;
}
2017-11-04 14:03:45 +00:00
2021-12-17 22:32:04 +00:00
bool cmdline_terminated(const char *const str)
2017-11-04 14:03:45 +00:00
{
2021-12-17 22:32:04 +00:00
for (size_t i = 0; i < KERNEL_INFO_CMDLINE_SIZE_MAX; ++i) {
if (str[i] == '\0') return true;
2017-11-04 14:03:45 +00:00
}
2021-12-17 22:32:04 +00:00
return false;
2017-11-04 14:03:45 +00:00
}