2020-03-25 23:05:14 +03:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
2020-05-03 23:37:24 +03:00
|
|
|
#include <stdbool.h>
|
2020-03-25 23:05:14 +03:00
|
|
|
#include <protos/stivale.h>
|
|
|
|
#include <lib/elf.h>
|
2020-03-26 02:46:35 +03:00
|
|
|
#include <lib/blib.h>
|
2020-03-26 03:37:56 +03:00
|
|
|
#include <lib/acpi.h>
|
2020-03-30 23:27:15 +03:00
|
|
|
#include <lib/config.h>
|
2020-04-30 22:19:12 +03:00
|
|
|
#include <lib/time.h>
|
2020-05-10 01:38:27 +03:00
|
|
|
#include <lib/print.h>
|
2020-06-01 11:20:34 +03:00
|
|
|
#include <lib/rand.h>
|
2020-06-01 05:47:55 +03:00
|
|
|
#include <lib/real.h>
|
2020-03-26 05:13:19 +03:00
|
|
|
#include <drivers/vbe.h>
|
2020-09-02 10:55:56 +03:00
|
|
|
#include <lib/term.h>
|
2020-09-18 21:02:10 +03:00
|
|
|
#include <sys/pic.h>
|
2020-04-14 06:20:55 +03:00
|
|
|
#include <fs/file.h>
|
2020-09-21 13:15:55 +03:00
|
|
|
#include <mm/vmm.h>
|
2020-09-20 13:03:44 +03:00
|
|
|
#include <mm/pmm.h>
|
2020-09-18 13:51:26 +03:00
|
|
|
#include <stivale/stivale.h>
|
2020-03-26 02:46:35 +03:00
|
|
|
|
2020-05-29 12:05:50 +03:00
|
|
|
#define KASLR_SLIDE_BITMASK 0x03FFFF000u
|
|
|
|
|
2020-03-26 06:06:23 +03:00
|
|
|
struct stivale_struct stivale_struct = {0};
|
2020-03-25 23:05:14 +03:00
|
|
|
|
2020-05-06 17:38:45 +03:00
|
|
|
void stivale_load(char *cmdline, int boot_drive) {
|
2020-06-25 19:51:54 +03:00
|
|
|
stivale_struct.flags |= (1 << 0); // set bit 0 since we are BIOS and not UEFI
|
2020-05-15 06:47:38 +03:00
|
|
|
|
2020-05-06 17:38:45 +03:00
|
|
|
int kernel_drive; {
|
|
|
|
char buf[32];
|
|
|
|
if (!config_get_value(buf, 0, 32, "KERNEL_DRIVE")) {
|
|
|
|
kernel_drive = boot_drive;
|
|
|
|
} else {
|
|
|
|
kernel_drive = (int)strtoui(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int kernel_part; {
|
|
|
|
char buf[32];
|
|
|
|
if (!config_get_value(buf, 0, 32, "KERNEL_PARTITION")) {
|
|
|
|
panic("KERNEL_PARTITION not specified");
|
|
|
|
} else {
|
|
|
|
kernel_part = (int)strtoui(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-20 13:03:44 +03:00
|
|
|
char *kernel_path = conv_mem_alloc(128);
|
2020-05-06 17:38:45 +03:00
|
|
|
if (!config_get_value(kernel_path, 0, 128, "KERNEL_PATH")) {
|
|
|
|
panic("KERNEL_PATH not specified");
|
|
|
|
}
|
|
|
|
|
2020-09-20 13:03:44 +03:00
|
|
|
struct file_handle *fd = conv_mem_alloc(sizeof(struct file_handle));
|
2020-05-06 17:38:45 +03:00
|
|
|
if (fopen(fd, kernel_drive, kernel_part, kernel_path)) {
|
|
|
|
panic("Could not open kernel file");
|
|
|
|
}
|
|
|
|
|
2020-03-26 02:46:35 +03:00
|
|
|
struct stivale_header stivale_hdr;
|
2020-04-18 19:01:29 +03:00
|
|
|
|
|
|
|
int bits = elf_bits(fd);
|
|
|
|
|
|
|
|
int ret;
|
|
|
|
|
2020-05-29 12:05:50 +03:00
|
|
|
uint64_t slide = 0;
|
|
|
|
|
2020-05-03 23:37:24 +03:00
|
|
|
bool level5pg = false;
|
2020-04-18 19:01:29 +03:00
|
|
|
switch (bits) {
|
2020-05-03 23:37:24 +03:00
|
|
|
case 64: {
|
2020-04-30 14:03:04 +03:00
|
|
|
// Check if 64 bit CPU
|
2020-05-03 23:37:24 +03:00
|
|
|
uint32_t eax, ebx, ecx, edx;
|
|
|
|
cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
|
|
|
|
if (!(edx & (1 << 29))) {
|
|
|
|
panic("stivale: This CPU does not support 64-bit mode.");
|
|
|
|
}
|
|
|
|
// Check if 5-level paging is available
|
|
|
|
cpuid(0x00000007, 0, &eax, &ebx, &ecx, &edx);
|
|
|
|
if (ecx & (1 << 16)) {
|
|
|
|
print("stivale: CPU has 5-level paging support\n");
|
|
|
|
level5pg = true;
|
2020-04-30 14:03:04 +03:00
|
|
|
}
|
2020-05-29 12:05:50 +03:00
|
|
|
|
|
|
|
ret = elf64_load_section(fd, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header), slide);
|
|
|
|
|
|
|
|
if (!ret && ((stivale_hdr.flags >> 2) & 1)) {
|
|
|
|
// KASLR is enabled, set the slide
|
2020-06-01 11:20:34 +03:00
|
|
|
slide = rand64() & KASLR_SLIDE_BITMASK;
|
2020-05-29 12:05:50 +03:00
|
|
|
|
|
|
|
// Re-read the .stivalehdr with slid relocations
|
|
|
|
ret = elf64_load_section(fd, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header), slide);
|
|
|
|
}
|
|
|
|
|
2020-04-18 19:01:29 +03:00
|
|
|
break;
|
2020-05-03 23:37:24 +03:00
|
|
|
}
|
2020-04-18 19:01:29 +03:00
|
|
|
case 32:
|
|
|
|
ret = elf32_load_section(fd, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header));
|
|
|
|
break;
|
2020-04-29 17:53:05 +03:00
|
|
|
default:
|
2020-04-30 14:03:04 +03:00
|
|
|
panic("stivale: Not 32 nor 64 bit x86 ELF file.");
|
2020-04-18 19:01:29 +03:00
|
|
|
}
|
|
|
|
|
2020-04-29 17:53:05 +03:00
|
|
|
print("stivale: %u-bit ELF file detected\n", bits);
|
|
|
|
|
2020-03-26 02:46:35 +03:00
|
|
|
switch (ret) {
|
|
|
|
case 1:
|
2020-05-10 01:48:58 +03:00
|
|
|
panic("stivale: File is not a valid ELF.");
|
2020-03-26 02:46:35 +03:00
|
|
|
case 2:
|
2020-05-10 01:48:58 +03:00
|
|
|
panic("stivale: Section .stivalehdr not found.");
|
2020-03-26 02:46:35 +03:00
|
|
|
case 3:
|
2020-05-10 01:48:58 +03:00
|
|
|
panic("stivale: Section .stivalehdr exceeds the size of the struct.");
|
2020-05-30 16:44:14 +03:00
|
|
|
case 4:
|
|
|
|
panic("stivale: Section .stivalehdr is smaller than size of the struct.");
|
2020-03-26 02:46:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
print("stivale: Requested stack at %X\n", stivale_hdr.stack);
|
|
|
|
|
2020-04-18 19:01:29 +03:00
|
|
|
uint64_t entry_point = 0;
|
|
|
|
uint64_t top_used_addr = 0;
|
2020-05-29 12:05:50 +03:00
|
|
|
|
2020-04-18 19:01:29 +03:00
|
|
|
switch (bits) {
|
|
|
|
case 64:
|
2020-08-11 19:00:51 +03:00
|
|
|
elf64_load(fd, &entry_point, &top_used_addr, slide, 10);
|
2020-04-18 19:01:29 +03:00
|
|
|
break;
|
|
|
|
case 32:
|
2020-08-11 19:00:51 +03:00
|
|
|
elf32_load(fd, (uint32_t *)&entry_point, (uint32_t *)&top_used_addr, 10);
|
2020-04-18 19:01:29 +03:00
|
|
|
break;
|
|
|
|
}
|
2020-03-30 23:27:15 +03:00
|
|
|
|
2020-05-30 16:44:14 +03:00
|
|
|
if (stivale_hdr.entry_point != 0)
|
|
|
|
entry_point = stivale_hdr.entry_point;
|
|
|
|
|
2020-05-29 12:05:50 +03:00
|
|
|
print("stivale: Kernel slide: %X\n", slide);
|
|
|
|
|
2020-03-30 23:27:15 +03:00
|
|
|
print("stivale: Top used address in ELF: %X\n", top_used_addr);
|
2020-03-25 23:05:14 +03:00
|
|
|
|
2020-03-30 23:27:15 +03:00
|
|
|
stivale_struct.module_count = 0;
|
|
|
|
uint64_t *prev_mod_ptr = &stivale_struct.modules;
|
|
|
|
for (int i = 0; ; i++) {
|
|
|
|
char module_file[64];
|
|
|
|
if (!config_get_value(module_file, i, 64, "MODULE_PATH"))
|
|
|
|
break;
|
|
|
|
|
|
|
|
stivale_struct.module_count++;
|
|
|
|
|
2020-09-20 13:03:44 +03:00
|
|
|
struct stivale_module *m = conv_mem_alloc(sizeof(struct stivale_module));
|
2020-03-30 23:27:15 +03:00
|
|
|
|
2020-06-05 18:51:33 +03:00
|
|
|
if (!config_get_value(m->string, i, 128, "MODULE_STRING")) {
|
|
|
|
m->string[0] = '\0';
|
|
|
|
}
|
2020-03-30 23:27:15 +03:00
|
|
|
|
|
|
|
int part; {
|
|
|
|
char buf[32];
|
2020-06-05 18:51:33 +03:00
|
|
|
if (!config_get_value(buf, i, 32, "MODULE_PARTITION")) {
|
|
|
|
part = kernel_part;
|
|
|
|
} else {
|
|
|
|
part = (int)strtoui(buf);
|
|
|
|
}
|
2020-03-30 23:27:15 +03:00
|
|
|
}
|
|
|
|
|
2020-04-14 06:20:55 +03:00
|
|
|
struct file_handle f;
|
2020-06-05 20:33:51 +03:00
|
|
|
if (fopen(&f, fd->disk, part, module_file)) {
|
|
|
|
panic("Requested module with path \"%s\" not found!\n", module_file);
|
|
|
|
}
|
2020-03-30 23:27:15 +03:00
|
|
|
|
|
|
|
void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
|
|
|
|
((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
|
|
|
|
(uint32_t)top_used_addr);
|
|
|
|
|
2020-08-11 19:00:51 +03:00
|
|
|
memmap_alloc_range((size_t)module_addr, f.size, 10);
|
2020-04-14 06:20:55 +03:00
|
|
|
fread(&f, module_addr, 0, f.size);
|
2020-03-30 23:27:15 +03:00
|
|
|
|
|
|
|
m->begin = (uint64_t)(size_t)module_addr;
|
2020-04-14 06:20:55 +03:00
|
|
|
m->end = m->begin + f.size;
|
2020-03-30 23:27:15 +03:00
|
|
|
m->next = 0;
|
|
|
|
|
|
|
|
top_used_addr = (uint64_t)(size_t)m->end;
|
|
|
|
|
|
|
|
*prev_mod_ptr = (uint64_t)(size_t)m;
|
|
|
|
prev_mod_ptr = &m->next;
|
|
|
|
|
|
|
|
print("stivale: Requested module %u:\n", i);
|
|
|
|
print(" Path: %s\n", module_file);
|
|
|
|
print(" String: %s\n", m->string);
|
|
|
|
print(" Begin: %X\n", m->begin);
|
|
|
|
print(" End: %X\n", m->end);
|
|
|
|
}
|
|
|
|
|
2020-09-17 13:06:35 +03:00
|
|
|
stivale_struct.rsdp = (uint64_t)(size_t)acpi_get_rsdp();
|
2020-03-26 03:37:56 +03:00
|
|
|
|
2020-03-31 11:48:24 +03:00
|
|
|
stivale_struct.cmdline = (uint64_t)(size_t)cmdline;
|
|
|
|
|
2020-04-30 22:19:12 +03:00
|
|
|
stivale_struct.epoch = time();
|
2020-06-25 19:51:54 +03:00
|
|
|
print("stivale: Current epoch: %U\n", stivale_struct.epoch);
|
2020-04-30 22:19:12 +03:00
|
|
|
|
2020-03-26 05:13:19 +03:00
|
|
|
stivale_struct.framebuffer_width = stivale_hdr.framebuffer_width;
|
|
|
|
stivale_struct.framebuffer_height = stivale_hdr.framebuffer_height;
|
2020-03-27 07:58:37 +03:00
|
|
|
stivale_struct.framebuffer_bpp = stivale_hdr.framebuffer_bpp;
|
2020-03-26 05:13:19 +03:00
|
|
|
|
2020-09-02 10:55:56 +03:00
|
|
|
term_deinit();
|
|
|
|
|
2020-05-03 23:37:24 +03:00
|
|
|
if (stivale_hdr.flags & (1 << 0)) {
|
2020-09-02 08:16:05 +03:00
|
|
|
uint32_t *fb32;
|
|
|
|
init_vbe(&fb32,
|
2020-03-26 05:13:19 +03:00
|
|
|
&stivale_struct.framebuffer_pitch,
|
|
|
|
&stivale_struct.framebuffer_width,
|
2020-03-27 07:58:37 +03:00
|
|
|
&stivale_struct.framebuffer_height,
|
|
|
|
&stivale_struct.framebuffer_bpp);
|
2020-09-02 08:16:05 +03:00
|
|
|
stivale_struct.framebuffer_addr = (uint64_t)(size_t)fb32;
|
2020-03-26 05:13:19 +03:00
|
|
|
}
|
|
|
|
|
2020-06-05 18:51:33 +03:00
|
|
|
size_t memmap_entries;
|
|
|
|
struct e820_entry_t *memmap = get_memmap(&memmap_entries);
|
|
|
|
|
2020-09-18 15:39:29 +03:00
|
|
|
bool want_5lv = level5pg && (stivale_hdr.flags & (1 << 1));
|
|
|
|
pagemap_t pagemap = stivale_build_pagemap(want_5lv, memmap, memmap_entries);
|
|
|
|
|
2020-09-26 16:06:59 +03:00
|
|
|
memmap = get_memmap(&memmap_entries);
|
|
|
|
stivale_struct.memory_map_entries = (uint64_t)memmap_entries;
|
|
|
|
stivale_struct.memory_map_addr = (uint64_t)(size_t)memmap;
|
|
|
|
|
2020-09-18 15:39:29 +03:00
|
|
|
stivale_spinup(bits, want_5lv, pagemap,
|
|
|
|
entry_point, &stivale_struct, stivale_hdr.stack);
|
2020-09-02 10:55:56 +03:00
|
|
|
}
|
|
|
|
|
2020-09-18 15:39:29 +03:00
|
|
|
pagemap_t stivale_build_pagemap(bool level5pg, struct e820_entry_t *memmap,
|
|
|
|
size_t memmap_entries) {
|
|
|
|
pagemap_t pagemap = new_pagemap(level5pg ? 5 : 4);
|
|
|
|
uint64_t higher_half_base = level5pg ? 0xff00000000000000 : 0xffff800000000000;
|
|
|
|
|
|
|
|
// Map 0 to 2GiB at 0xffffffff80000000
|
|
|
|
for (uint64_t i = 0; i < 0x80000000; i += PAGE_SIZE) {
|
|
|
|
map_page(pagemap, 0xffffffff80000000 + i, i, 0x03);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Map 0 to 4GiB at higher half base and 0
|
|
|
|
for (uint64_t i = 0; i < 0x100000000; i += PAGE_SIZE) {
|
|
|
|
map_page(pagemap, i, i, 0x03);
|
|
|
|
map_page(pagemap, higher_half_base + i, i, 0x03);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Map any other region of memory from the memmap
|
|
|
|
for (size_t i = 0; i < memmap_entries; i++) {
|
|
|
|
uint64_t base = memmap[i].base;
|
|
|
|
uint64_t length = memmap[i].length;
|
|
|
|
uint64_t top = base + length;
|
|
|
|
|
|
|
|
uint64_t aligned_base = ALIGN_DOWN(base, PAGE_SIZE);
|
|
|
|
uint64_t aligned_top = ALIGN_UP(top, PAGE_SIZE);
|
|
|
|
uint64_t aligned_length = aligned_top - aligned_base;
|
|
|
|
|
|
|
|
for (uint64_t i = 0; i < aligned_length; i += PAGE_SIZE) {
|
|
|
|
uint64_t page = aligned_base + i;
|
|
|
|
map_page(pagemap, page, page, 0x03);
|
|
|
|
map_page(pagemap, higher_half_base + page, page, 0x03);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pagemap;
|
|
|
|
}
|
|
|
|
|
|
|
|
__attribute__((noreturn)) void stivale_spinup(
|
|
|
|
int bits, bool level5pg, pagemap_t pagemap,
|
|
|
|
uint64_t entry_point, void *stivale_struct, uint64_t stack) {
|
2020-06-03 14:54:54 +03:00
|
|
|
if (bits == 64) {
|
|
|
|
// If we're going 64, we might as well call this BIOS interrupt
|
|
|
|
// to tell the BIOS that we are entering Long Mode, since it is in
|
|
|
|
// the specification.
|
|
|
|
struct rm_regs r = {0};
|
|
|
|
r.eax = 0xec00;
|
|
|
|
r.ebx = 0x02; // Long mode only
|
|
|
|
rm_int(0x15, &r, &r);
|
|
|
|
}
|
|
|
|
|
2020-09-02 03:32:04 +03:00
|
|
|
pic_mask_all();
|
|
|
|
pic_flush();
|
2020-06-01 05:47:55 +03:00
|
|
|
|
2020-04-18 19:01:29 +03:00
|
|
|
if (bits == 64) {
|
2020-09-02 10:55:56 +03:00
|
|
|
if (level5pg) {
|
2020-05-03 23:37:24 +03:00
|
|
|
// Enable CR4.LA57
|
2020-09-16 18:22:05 +03:00
|
|
|
asm volatile (
|
2020-05-03 23:37:24 +03:00
|
|
|
"mov eax, cr4\n\t"
|
|
|
|
"bts eax, 12\n\t"
|
2020-09-16 18:22:05 +03:00
|
|
|
"mov cr4, eax\n\t" ::: "eax", "memory"
|
2020-05-03 23:37:24 +03:00
|
|
|
);
|
2020-09-11 15:09:15 +03:00
|
|
|
}
|
2020-05-03 23:37:24 +03:00
|
|
|
|
2020-09-16 18:22:05 +03:00
|
|
|
asm volatile (
|
2020-04-18 19:01:29 +03:00
|
|
|
"cli\n\t"
|
|
|
|
"cld\n\t"
|
|
|
|
"mov cr3, eax\n\t"
|
|
|
|
"mov eax, cr4\n\t"
|
|
|
|
"or eax, 1 << 5\n\t"
|
|
|
|
"mov cr4, eax\n\t"
|
|
|
|
"mov ecx, 0xc0000080\n\t"
|
|
|
|
"rdmsr\n\t"
|
|
|
|
"or eax, 1 << 8\n\t"
|
|
|
|
"wrmsr\n\t"
|
|
|
|
"mov eax, cr0\n\t"
|
|
|
|
"or eax, 1 << 31\n\t"
|
|
|
|
"mov cr0, eax\n\t"
|
2020-09-16 18:22:05 +03:00
|
|
|
"jmp 0x28:1f\n\t"
|
2020-04-18 19:01:29 +03:00
|
|
|
"1: .code64\n\t"
|
|
|
|
"mov ax, 0x30\n\t"
|
|
|
|
"mov ds, ax\n\t"
|
|
|
|
"mov es, ax\n\t"
|
|
|
|
"mov fs, ax\n\t"
|
|
|
|
"mov gs, ax\n\t"
|
|
|
|
"mov ss, ax\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
|
2020-09-17 13:06:35 +03:00
|
|
|
// Since we don't really know what is now present in the upper
|
|
|
|
// 32 bits of the 64 bit registers, clear up the upper bits
|
|
|
|
// of the registers we use to store stack pointer and instruction
|
|
|
|
// pointer
|
|
|
|
"mov esi, esi\n\t"
|
|
|
|
"mov ebx, ebx\n\t"
|
|
|
|
"mov edi, edi\n\t"
|
|
|
|
|
2020-09-18 11:57:38 +03:00
|
|
|
// Let's pretend we push a return address
|
|
|
|
"mov rsi, qword ptr [rsi]\n\t"
|
|
|
|
"test rsi, rsi\n\t"
|
|
|
|
"jz 1f\n\t"
|
|
|
|
|
|
|
|
"sub rsi, 8\n\t"
|
|
|
|
"mov qword ptr [rsi], 0\n\t"
|
|
|
|
|
|
|
|
"1:\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
"push 0x30\n\t"
|
2020-09-18 11:57:38 +03:00
|
|
|
"push rsi\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
"pushfq\n\t"
|
|
|
|
"push 0x28\n\t"
|
|
|
|
"push [rbx]\n\t"
|
|
|
|
|
2020-07-24 16:38:55 +03:00
|
|
|
"xor rax, rax\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
"xor rbx, rbx\n\t"
|
|
|
|
"xor rcx, rcx\n\t"
|
|
|
|
"xor rdx, rdx\n\t"
|
|
|
|
"xor rsi, rsi\n\t"
|
|
|
|
"xor rbp, rbp\n\t"
|
|
|
|
"xor r8, r8\n\t"
|
|
|
|
"xor r9, r9\n\t"
|
|
|
|
"xor r10, r10\n\t"
|
|
|
|
"xor r11, r11\n\t"
|
|
|
|
"xor r12, r12\n\t"
|
|
|
|
"xor r13, r13\n\t"
|
|
|
|
"xor r14, r14\n\t"
|
|
|
|
"xor r15, r15\n\t"
|
|
|
|
|
|
|
|
"iretq\n\t"
|
2020-09-16 18:22:05 +03:00
|
|
|
".code32\n\t"
|
|
|
|
:
|
2020-09-11 15:09:15 +03:00
|
|
|
: "a" (pagemap.top_level), "b" (&entry_point),
|
2020-09-02 10:55:56 +03:00
|
|
|
"D" (stivale_struct), "S" (&stack)
|
2020-07-09 04:24:54 +03:00
|
|
|
: "memory"
|
2020-04-18 19:01:29 +03:00
|
|
|
);
|
|
|
|
} else if (bits == 32) {
|
2020-09-25 23:57:57 +03:00
|
|
|
asm volatile (
|
2020-04-18 19:01:29 +03:00
|
|
|
"cli\n\t"
|
|
|
|
"cld\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
|
2020-09-18 00:22:53 +03:00
|
|
|
"mov esp, dword ptr [esi]\n\t"
|
|
|
|
"push edi\n\t"
|
2020-09-18 11:16:24 +03:00
|
|
|
"push 0\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
|
|
|
|
"pushfd\n\t"
|
|
|
|
"push 0x18\n\t"
|
|
|
|
"push [ebx]\n\t"
|
|
|
|
|
2020-07-24 16:38:55 +03:00
|
|
|
"xor eax, eax\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
"xor ebx, ebx\n\t"
|
|
|
|
"xor ecx, ecx\n\t"
|
2020-07-24 16:38:55 +03:00
|
|
|
"xor edx, edx\n\t"
|
2020-07-09 04:24:54 +03:00
|
|
|
"xor esi, esi\n\t"
|
|
|
|
"xor edi, edi\n\t"
|
|
|
|
"xor ebp, ebp\n\t"
|
|
|
|
|
2020-09-18 11:16:24 +03:00
|
|
|
"iret\n\t"
|
|
|
|
:
|
|
|
|
: "b"(&entry_point), "D"(stivale_struct), "S"(&stack)
|
2020-09-25 23:57:57 +03:00
|
|
|
: "memory"
|
|
|
|
);
|
2020-04-18 19:01:29 +03:00
|
|
|
}
|
2020-09-02 10:55:56 +03:00
|
|
|
for (;;);
|
2020-03-25 23:05:14 +03:00
|
|
|
}
|