2017-11-09 16:00:36 +00:00
|
|
|
#include "info.h"
|
2017-11-04 12:01:10 +00:00
|
|
|
|
2021-12-17 23:30:09 +00:00
|
|
|
#include <kernaux/assert.h>
|
2021-12-17 23:05:01 +00:00
|
|
|
#include <kernaux/console.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 23:26:56 +00:00
|
|
|
void kernel_info_init_start(
|
2021-12-17 22:45:22 +00:00
|
|
|
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-18 01:04:00 +00:00
|
|
|
KERNAUX_NOTNULL_RETURN(kinfo);
|
2021-12-17 23:30:09 +00:00
|
|
|
|
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 23:05:01 +00:00
|
|
|
void kernel_info_print(const struct Kernel_Info *const kinfo)
|
|
|
|
{
|
2021-12-18 01:04:00 +00:00
|
|
|
KERNAUX_NOTNULL_RETURN(kinfo);
|
2021-12-17 23:30:09 +00:00
|
|
|
|
2021-12-17 23:05:01 +00:00
|
|
|
kernaux_console_printf("Kernel info\n");
|
|
|
|
kernaux_console_printf(" cmdline: %s\n", kinfo->cmdline);
|
|
|
|
kernaux_console_printf(" modules: %lu\n", kinfo->modules_count);
|
|
|
|
kernaux_console_printf(" areas: %lu\n", kinfo->areas_count);
|
|
|
|
kernaux_console_printf("\n");
|
|
|
|
kernaux_console_printf(" offset: %lu\n", kinfo->kernel_offset);
|
|
|
|
kernaux_console_printf(" size: %lu\n", kinfo->kernel_size);
|
|
|
|
kernaux_console_printf("\n");
|
|
|
|
kernaux_console_printf(" phys base: %lu\n", kinfo->kernel_phys_base);
|
|
|
|
kernaux_console_printf(" phys limit: %lu\n", kinfo->kernel_phys_limit);
|
|
|
|
kernaux_console_printf("\n");
|
|
|
|
kernaux_console_printf(" virt base: %lu\n", kinfo->kernel_virt_base);
|
|
|
|
kernaux_console_printf(" virt limit: %lu\n", kinfo->kernel_virt_limit);
|
|
|
|
kernaux_console_printf("\n");
|
|
|
|
kernaux_console_printf(" modules size: %lu\n", kinfo->modules_total_size);
|
|
|
|
kernaux_console_printf(" kernel & modules sizet: %lu\n", kinfo->kernel_and_modules_total_size);
|
|
|
|
kernaux_console_printf("\n");
|
|
|
|
kernaux_console_printf(" stack top: %lu\n", kinfo->kernel_stack_top);
|
|
|
|
}
|
|
|
|
|
2021-12-17 23:26:56 +00:00
|
|
|
bool kernel_info_init_finish(const struct Kernel_Info *const kinfo)
|
2020-11-26 18:50:25 +00:00
|
|
|
{
|
2021-12-18 01:04:00 +00:00
|
|
|
KERNAUX_NOTNULL_RETVAL(kinfo, 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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-04 12:01:10 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-11-04 14:03:45 +00:00
|
|
|
|
2021-12-18 02:29:25 +00:00
|
|
|
void kernel_info_init_cmdline(
|
|
|
|
struct Kernel_Info *const kinfo,
|
|
|
|
const char *const cmdline
|
|
|
|
) {
|
|
|
|
KERNAUX_NOTNULL_RETURN(kinfo);
|
|
|
|
KERNAUX_ASSERT_RETURN(kinfo->cmdline[0] == '\0');
|
|
|
|
|
|
|
|
if (!cmdline) return;
|
|
|
|
|
|
|
|
KERNAUX_ASSERT(strlen(cmdline) <= KERNEL_INFO_CMDLINE_SLEN_MAX);
|
|
|
|
|
|
|
|
strcpy(kinfo->cmdline, cmdline);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|