2021-12-31 12:58:05 +03:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdnoreturn.h>
|
2021-03-02 01:38:55 +03:00
|
|
|
#include <lib/term.h>
|
|
|
|
#include <lib/real.h>
|
2022-08-27 00:44:47 +03:00
|
|
|
#include <lib/misc.h>
|
2021-03-02 01:38:55 +03:00
|
|
|
#include <lib/libc.h>
|
|
|
|
#include <lib/part.h>
|
|
|
|
#include <lib/config.h>
|
|
|
|
#include <lib/trace.h>
|
|
|
|
#include <sys/e820.h>
|
|
|
|
#include <sys/a20.h>
|
|
|
|
#include <lib/print.h>
|
|
|
|
#include <fs/file.h>
|
|
|
|
#include <lib/elf.h>
|
|
|
|
#include <mm/pmm.h>
|
|
|
|
#include <protos/linux.h>
|
|
|
|
#include <protos/chainload.h>
|
|
|
|
#include <menu.h>
|
|
|
|
#include <pxe/pxe.h>
|
|
|
|
#include <pxe/tftp.h>
|
2021-03-04 11:15:10 +03:00
|
|
|
#include <drivers/disk.h>
|
2021-03-13 05:21:01 +03:00
|
|
|
#include <sys/idt.h>
|
2021-11-21 03:18:39 +03:00
|
|
|
#include <sys/cpu.h>
|
2021-03-02 01:38:55 +03:00
|
|
|
|
2021-03-11 02:23:44 +03:00
|
|
|
struct volume *boot_volume;
|
2021-03-02 12:23:43 +03:00
|
|
|
|
2022-09-02 03:29:12 +03:00
|
|
|
#if defined (BIOS)
|
2021-03-02 12:23:43 +03:00
|
|
|
|
2021-03-02 01:38:55 +03:00
|
|
|
bool stage3_loaded = false;
|
2021-03-21 11:44:07 +03:00
|
|
|
static bool stage3_found = false;
|
2021-03-02 01:38:55 +03:00
|
|
|
|
|
|
|
extern symbol stage3_addr;
|
|
|
|
extern symbol limine_sys_size;
|
2021-11-08 11:42:41 +03:00
|
|
|
extern symbol build_id_s2;
|
|
|
|
extern symbol build_id_s3;
|
2021-03-02 01:38:55 +03:00
|
|
|
|
|
|
|
static bool stage3_init(struct volume *part) {
|
2021-10-21 02:27:05 +03:00
|
|
|
struct file_handle *stage3;
|
2021-03-02 01:38:55 +03:00
|
|
|
|
2022-09-01 15:02:53 +03:00
|
|
|
bool old_cif = case_insensitive_fopen;
|
|
|
|
case_insensitive_fopen = true;
|
2021-10-21 02:27:05 +03:00
|
|
|
if ((stage3 = fopen(part, "/limine.sys")) == NULL
|
2022-10-06 07:29:11 +03:00
|
|
|
&& (stage3 = fopen(part, "/limine/limine.sys")) == NULL
|
|
|
|
&& (stage3 = fopen(part, "/boot/limine.sys")) == NULL
|
|
|
|
&& (stage3 = fopen(part, "/boot/limine/limine.sys")) == NULL) {
|
2022-09-01 15:02:53 +03:00
|
|
|
case_insensitive_fopen = old_cif;
|
2021-03-02 01:38:55 +03:00
|
|
|
return false;
|
|
|
|
}
|
2022-09-01 15:02:53 +03:00
|
|
|
case_insensitive_fopen = old_cif;
|
2021-03-02 01:38:55 +03:00
|
|
|
|
2021-03-21 11:44:07 +03:00
|
|
|
stage3_found = true;
|
|
|
|
|
2021-10-21 02:27:05 +03:00
|
|
|
if (stage3->size != (size_t)limine_sys_size) {
|
2021-03-02 01:38:55 +03:00
|
|
|
print("limine.sys size incorrect.\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-10-21 02:27:05 +03:00
|
|
|
fread(stage3, stage3_addr,
|
2023-03-07 04:21:09 +03:00
|
|
|
(uintptr_t)stage3_addr - 0xf000,
|
|
|
|
stage3->size - ((uintptr_t)stage3_addr - 0xf000));
|
2021-10-21 02:27:05 +03:00
|
|
|
|
|
|
|
fclose(stage3);
|
2021-03-02 01:38:55 +03:00
|
|
|
|
2021-11-08 11:42:41 +03:00
|
|
|
if (memcmp(build_id_s2 + 16, build_id_s3 + 16, 20) != 0) {
|
2021-03-02 01:38:55 +03:00
|
|
|
print("limine.sys build ID mismatch.\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
stage3_loaded = true;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-03-11 02:23:44 +03:00
|
|
|
enum {
|
2022-02-09 14:45:55 +03:00
|
|
|
BOOTED_FROM_HDD = 0,
|
|
|
|
BOOTED_FROM_PXE = 1,
|
|
|
|
BOOTED_FROM_CD = 2
|
2021-03-11 02:23:44 +03:00
|
|
|
};
|
2021-03-02 01:38:55 +03:00
|
|
|
|
2021-12-31 12:58:05 +03:00
|
|
|
noreturn void entry(uint8_t boot_drive, int boot_from) {
|
2021-09-23 01:17:15 +03:00
|
|
|
// XXX DO NOT MOVE A20 ENABLE CALL
|
2022-06-17 21:29:23 +03:00
|
|
|
if (!a20_enable()) {
|
2021-12-11 21:58:00 +03:00
|
|
|
panic(false, "Could not enable A20 line");
|
2022-06-17 21:29:23 +03:00
|
|
|
}
|
|
|
|
|
2021-04-15 03:21:38 +03:00
|
|
|
init_e820();
|
|
|
|
init_memmap();
|
|
|
|
|
2021-03-13 05:21:01 +03:00
|
|
|
init_idt();
|
|
|
|
|
2021-03-04 11:15:10 +03:00
|
|
|
disk_create_index();
|
|
|
|
|
2021-03-11 02:23:44 +03:00
|
|
|
if (boot_from == BOOTED_FROM_HDD || boot_from == BOOTED_FROM_CD) {
|
2021-06-12 14:13:19 +03:00
|
|
|
boot_volume = volume_get_by_bios_drive(boot_drive);
|
2021-03-13 11:08:01 +03:00
|
|
|
} else if (boot_from == BOOTED_FROM_PXE) {
|
|
|
|
pxe_init();
|
|
|
|
boot_volume = pxe_bind_volume();
|
2021-03-11 02:23:44 +03:00
|
|
|
}
|
2021-03-04 11:15:10 +03:00
|
|
|
|
2022-02-09 14:45:55 +03:00
|
|
|
if (boot_volume == NULL) {
|
2022-09-17 14:53:57 +03:00
|
|
|
panic(false, "Could not determine boot drive");
|
2022-02-09 14:45:55 +03:00
|
|
|
}
|
|
|
|
|
2021-03-04 11:15:10 +03:00
|
|
|
volume_iterate_parts(boot_volume,
|
|
|
|
if (stage3_init(_PART)) {
|
2021-03-02 01:38:55 +03:00
|
|
|
break;
|
|
|
|
}
|
2021-03-04 11:15:10 +03:00
|
|
|
);
|
|
|
|
|
2021-11-20 23:47:51 +03:00
|
|
|
if (!stage3_found) {
|
2021-03-21 11:44:07 +03:00
|
|
|
print("\n"
|
|
|
|
"!! Stage 3 file not found!\n"
|
2022-10-14 00:10:56 +03:00
|
|
|
"!! Have you copied limine.sys to the root, /boot, /limine, or /boot/limine\n"
|
|
|
|
"!! directories of one of the partitions on the boot device?\n\n");
|
2021-11-20 23:47:51 +03:00
|
|
|
}
|
2021-03-21 11:44:07 +03:00
|
|
|
|
2021-11-20 23:47:51 +03:00
|
|
|
if (!stage3_loaded) {
|
2021-12-11 21:58:00 +03:00
|
|
|
panic(false, "Failed to load stage 3.");
|
2021-11-20 23:47:51 +03:00
|
|
|
}
|
2021-03-02 01:38:55 +03:00
|
|
|
|
2022-09-23 21:53:14 +03:00
|
|
|
term_fallback();
|
|
|
|
|
2021-12-11 21:58:00 +03:00
|
|
|
stage3_common();
|
2021-03-02 01:38:55 +03:00
|
|
|
}
|
2021-03-02 12:23:43 +03:00
|
|
|
|
|
|
|
#endif
|