diff --git a/README.md b/README.md new file mode 100644 index 0000000..22c2373 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# My Kernel +A bodged together mess that resembles something like a kernel. + +## ELF Symbols +Qemu's `-kernel` does not expose the symbol table to the kernel. To retrieve this table, use `--net` + +## launch-qemu.sh +This is the main way of launching the kernel. + +Some options: +### --net +Launch the kernel over the network using GRUB. + +First build the netdir: +```bash +grub-mknetdir --net-directory=netdir --subdir=/boot/grub -d /usr/lib/grub/i386-pc +``` +Now the `--net` option should work as expected diff --git a/kernel/command.c b/kernel/command.c index be35831..3200cd7 100644 --- a/kernel/command.c +++ b/kernel/command.c @@ -44,15 +44,26 @@ void help(const char *args); void shutdown(const char *args); +void explode(const char *args); + cmd_handler cmd_handlers[] = { {"help\0", help}, {"echo\0", echo}, {"print\0", print}, {"ide\0", ide}, {"shutdown", shutdown}, + {"explode", explode}, {NULL, NULL}, }; + +void explode(const char *args) { + uint32_t x = 0; + uint32_t y = 0; + __asm__("div %%ebx" : + "=a" (x), "=b" (y)); +} + void shutdown(const char *args) { power_shutdown(); } diff --git a/kernel/cpu/isr.c b/kernel/cpu/isr.c index b117828..38e722f 100644 --- a/kernel/cpu/isr.c +++ b/kernel/cpu/isr.c @@ -4,6 +4,7 @@ #include "isr.h" +#include #include #include #include @@ -131,6 +132,7 @@ void isr_handler(isr_registers_t r) { return; } sprintf(msg, "Received interrupt: %d - %s\n", r.int_no, exception_messages[r.int_no]); + debug_backtrace(true); k_panics(msg); } diff --git a/kernel/debug/debug.c b/kernel/debug/debug.c new file mode 100644 index 0000000..aae5183 --- /dev/null +++ b/kernel/debug/debug.c @@ -0,0 +1,113 @@ +// +// Created by rick on 08-03-21. +// + +#include "debug.h" +#include +#include +#include +#include +#include +#include + +static struct elf32_section_header* elf_headers = NULL; +static struct elf32_section_header* elf_shstrtab = NULL; +static struct elf32_section_header* elf_symtab = NULL; +static struct elf32_section_header* elf_strtab = NULL; +static uint32_t elf_header_cnt; + +static const char* elf_name_symtab = ".symtab"; +static const char* elf_name_strtab = ".strtab"; + +struct stackframe { + struct stackframe* ebp; + uint32_t eip; +}; + +char *debug_get_shstrtab_entry(uint32_t ndx) { + if (elf_shstrtab == NULL) { + return NULL; + } + if (ndx > elf_shstrtab->sh_size) { + return NULL; + } + return ((char*)elf_shstrtab->sh_addr + ndx); +} + +char *debug_get_strtab_entry(uint32_t ndx) { + if (elf_strtab == NULL) { + return NULL; + } + if (ndx > elf_strtab->sh_size) { + return NULL; + } + return ((char*)elf_strtab->sh_addr + ndx); +} + +void debug_find_sections(uint32_t shndx) { + elf_shstrtab = &elf_headers[shndx]; + for (uint32_t i = 0; i < elf_header_cnt; ++i) { + struct elf32_section_header *current = &elf_headers[i]; + char *name = debug_get_shstrtab_entry(current->sh_name); + if (name == NULL) { + printf("Name was NULL\n"); + continue; + } + if (strcmp(name, elf_name_symtab) == 0) { + elf_symtab = current; + continue; + } + if (strcmp(name, elf_name_strtab) == 0) { + elf_strtab = current; + continue; + } + } +} + +void debug_store_info(struct multiboot_info *info) { + if (!(info->flags & MULTIBOOT_INFO_ELF_SHDR)) { + return; + } + if (sizeof(struct elf32_section_header) != info->u.elf_sec.size) { + k_panics("ELF size not correct"); + } + elf_headers = (struct elf32_section_header *) info->u.elf_sec.addr; + elf_header_cnt = info->u.elf_sec.num; + debug_find_sections(info->u.elf_sec.shndx); +} + +struct elf32_symtab_entry* debug_get_entry_for_addr(uint32_t addr) { + if (elf_symtab == NULL) { + return NULL; + } + struct elf32_symtab_entry* first = (struct elf32_symtab_entry *) elf_symtab->sh_addr; + uint32_t num = elf_symtab->sh_size / sizeof(struct elf32_symtab_entry); + for (uint32_t i = 0; i < num; ++i) { + // only functions for now + if (ELF32_ST_TYPE(first[i].st_info) != STT_FUNC) { + continue; + } + if (addr >= first[i].st_value && addr < (first[i].st_value + first[i].st_size)) { + return &first[i]; + } + } + return NULL; +} + +void debug_backtrace(bool do_sync) { + struct stackframe *frame = __builtin_frame_address(0); + void (*printer)(const char*) = do_sync ? kprint_sync : kprint; + printer("\n\n## Stack Trace ##\n"); + char msg[1024] = {0}; + while (frame->ebp != NULL) { + struct elf32_symtab_entry *entry = debug_get_entry_for_addr(frame->eip); + if (entry == NULL) { + sprintf(msg, "#unknown (%x)\n", frame->eip); + } else { + sprintf(msg, "%s (%x)\n", debug_get_strtab_entry(entry->st_name), frame->eip); + }; + printer(msg); + frame = frame->ebp; + } + printer("\n"); +} diff --git a/kernel/debug/debug.h b/kernel/debug/debug.h new file mode 100644 index 0000000..9f08881 --- /dev/null +++ b/kernel/debug/debug.h @@ -0,0 +1,14 @@ +// +// Created by rick on 08-03-21. +// + +#ifndef NEW_KERNEL_DEBUG_H +#define NEW_KERNEL_DEBUG_H +#include +#include + +void debug_store_info(struct multiboot_info *info); + +void debug_backtrace(bool do_sync); + +#endif //NEW_KERNEL_DEBUG_H diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c index 85ee9e9..32d43b7 100644 --- a/kernel/drivers/ide.c +++ b/kernel/drivers/ide.c @@ -4,6 +4,7 @@ // https://wiki.osdev.org/PCI_IDE_Controller #include "ide.h" +#include #include "ports.h" #include #include @@ -264,6 +265,8 @@ unsigned char ide_print_error(unsigned int drive, unsigned char err) { if (err == 0) return err; + debug_backtrace(false); + kprint("IDE:"); if (err == 1) { kprint("- Device Fault "); diff --git a/kernel/elf.h b/kernel/elf.h new file mode 100644 index 0000000..fbb9976 --- /dev/null +++ b/kernel/elf.h @@ -0,0 +1,73 @@ +// +// Created by rick on 07-03-21. +// + +#ifndef NEW_KERNEL_ELF_H +#define NEW_KERNEL_ELF_H + +#include +#include + +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MASKPROC 0xf0000000 + +#define ELF32_ST_BIND(i) ((i)>>4) +#define ELF32_ST_TYPE(i) ((i)&0xf) +#define ELF32_ST_INFO(b, t) (((b)<<4)+((t)&0xf)) + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +struct elf32_section_header { + uint32_t sh_name; + uint32_t sh_type; + uint32_t sh_flags; + uint32_t sh_addr; + uint32_t sh_offset; + uint32_t sh_size; + uint32_t sh_link; + uint32_t sh_info; + uint32_t sh_addr_align; + uint32_t sh_ent_size; +} packed; + +struct elf32_symtab_entry { + uint32_t st_name; + uint32_t st_value; + uint32_t st_size; + uint8_t st_info; + uint8_t st_other; + uint16_t st_shndx; +}; + +#endif //NEW_KERNEL_ELF_H diff --git a/kernel/kernel.c b/kernel/kernel.c index 3962b71..bdd50f6 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -15,6 +15,7 @@ #include #include #include +#include const int version_major = 0, version_minor = 0, @@ -56,6 +57,8 @@ void noreturn used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) { // initialize kprint functionality kprint_init(); + debug_store_info(multiboot_info); + // identify cpu cpuidx_print_info(); diff --git a/kernel/multiboot2.h b/kernel/multiboot2.h deleted file mode 100644 index 54e8599..0000000 --- a/kernel/multiboot2.h +++ /dev/null @@ -1,380 +0,0 @@ -/* multiboot2.h - Multiboot 2 header file. */ -/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY - * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MULTIBOOT_HEADER -#define MULTIBOOT_HEADER 1 - -/* How many bytes from the start of the file we search for the header. */ -#define MULTIBOOT_SEARCH 32768 -#define MULTIBOOT_HEADER_ALIGN 8 - -/* The magic field should contain this. */ -#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 - -/* This should be in %eax. */ -#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 - -/* Alignment of multiboot modules. */ -#define MULTIBOOT_MOD_ALIGN 0x00001000 - -/* Alignment of the multiboot info structure. */ -#define MULTIBOOT_INFO_ALIGN 0x00000008 - -/* Flags set in the ’flags’ member of the multiboot header. */ - -#define MULTIBOOT_TAG_ALIGN 8 -#define MULTIBOOT_TAG_TYPE_END 0 -#define MULTIBOOT_TAG_TYPE_CMDLINE 1 -#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 -#define MULTIBOOT_TAG_TYPE_MODULE 3 -#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 -#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 -#define MULTIBOOT_TAG_TYPE_MMAP 6 -#define MULTIBOOT_TAG_TYPE_VBE 7 -#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 -#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 -#define MULTIBOOT_TAG_TYPE_APM 10 -#define MULTIBOOT_TAG_TYPE_EFI32 11 -#define MULTIBOOT_TAG_TYPE_EFI64 12 -#define MULTIBOOT_TAG_TYPE_SMBIOS 13 -#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 -#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 -#define MULTIBOOT_TAG_TYPE_NETWORK 16 -#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 -#define MULTIBOOT_TAG_TYPE_EFI_BS 18 -#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 -#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 -#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 - -#define MULTIBOOT_HEADER_TAG_END 0 -#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 -#define MULTIBOOT_HEADER_TAG_ADDRESS 2 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 -#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 -#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 -#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 -#define MULTIBOOT_HEADER_TAG_EFI_BS 7 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 -#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 - -#define MULTIBOOT_ARCHITECTURE_I386 0 -#define MULTIBOOT_ARCHITECTURE_MIPS32 4 -#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 - -#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 -#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 -#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 - -#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 -#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 - -#ifndef ASM_FILE - -typedef unsigned char multiboot_uint8_t; -typedef unsigned short multiboot_uint16_t; -typedef unsigned int multiboot_uint32_t; -typedef unsigned long long multiboot_uint64_t; - -struct multiboot_header { - /* Must be MULTIBOOT_MAGIC - see above. */ - multiboot_uint32_t magic; - - /* ISA */ - multiboot_uint32_t architecture; - - /* Total header length. */ - multiboot_uint32_t header_length; - - /* The above fields plus this one must equal 0 mod 2^32. */ - multiboot_uint32_t checksum; -}; - -struct multiboot_header_tag { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; -}; - -struct multiboot_header_tag_information_request { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t requests[0]; -}; - -struct multiboot_header_tag_address { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t header_addr; - multiboot_uint32_t load_addr; - multiboot_uint32_t load_end_addr; - multiboot_uint32_t bss_end_addr; -}; - -struct multiboot_header_tag_entry_address { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t entry_addr; -}; - -struct multiboot_header_tag_console_flags { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t console_flags; -}; - -struct multiboot_header_tag_framebuffer { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t width; - multiboot_uint32_t height; - multiboot_uint32_t depth; -}; - -struct multiboot_header_tag_module_align { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; -}; - -struct multiboot_header_tag_relocatable { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t min_addr; - multiboot_uint32_t max_addr; - multiboot_uint32_t align; - multiboot_uint32_t preference; -}; - -struct multiboot_color { - multiboot_uint8_t red; - multiboot_uint8_t green; - multiboot_uint8_t blue; -}; - -struct multiboot_mmap_entry { - multiboot_uint64_t addr; - multiboot_uint64_t len; -#define MULTIBOOT_MEMORY_AVAILABLE 1 -#define MULTIBOOT_MEMORY_RESERVED 2 -#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 -#define MULTIBOOT_MEMORY_NVS 4 -#define MULTIBOOT_MEMORY_BADRAM 5 - multiboot_uint32_t type; - multiboot_uint32_t zero; -}; -typedef struct multiboot_mmap_entry multiboot_memory_map_t; - -struct multiboot_tag { - multiboot_uint32_t type; - multiboot_uint32_t size; -}; - -struct multiboot_tag_string { - multiboot_uint32_t type; - multiboot_uint32_t size; - char string[0]; -}; - -struct multiboot_tag_module { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mod_start; - multiboot_uint32_t mod_end; - char cmdline[0]; -}; - -struct multiboot_tag_basic_meminfo { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mem_lower; - multiboot_uint32_t mem_upper; -}; - -struct multiboot_tag_bootdev { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t biosdev; - multiboot_uint32_t slice; - multiboot_uint32_t part; -}; - -struct multiboot_tag_mmap { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t entry_size; - multiboot_uint32_t entry_version; - struct multiboot_mmap_entry entries[0]; -}; - -struct multiboot_vbe_info_block { - multiboot_uint8_t external_specification[512]; -}; - -struct multiboot_vbe_mode_info_block { - multiboot_uint8_t external_specification[256]; -}; - -struct multiboot_tag_vbe { - multiboot_uint32_t type; - multiboot_uint32_t size; - - multiboot_uint16_t vbe_mode; - multiboot_uint16_t vbe_interface_seg; - multiboot_uint16_t vbe_interface_off; - multiboot_uint16_t vbe_interface_len; - - struct multiboot_vbe_info_block vbe_control_info; - struct multiboot_vbe_mode_info_block vbe_mode_info; -}; - -struct multiboot_tag_framebuffer_common { - multiboot_uint32_t type; - multiboot_uint32_t size; - - multiboot_uint64_t framebuffer_addr; - multiboot_uint32_t framebuffer_pitch; - multiboot_uint32_t framebuffer_width; - multiboot_uint32_t framebuffer_height; - multiboot_uint8_t framebuffer_bpp; -#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 -#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - multiboot_uint8_t framebuffer_type; - multiboot_uint16_t reserved; -}; - -struct multiboot_tag_framebuffer { - struct multiboot_tag_framebuffer_common common; - - union { - struct { - multiboot_uint16_t framebuffer_palette_num_colors; - struct multiboot_color framebuffer_palette[0]; - }; - struct { - multiboot_uint8_t framebuffer_red_field_position; - multiboot_uint8_t framebuffer_red_mask_size; - multiboot_uint8_t framebuffer_green_field_position; - multiboot_uint8_t framebuffer_green_mask_size; - multiboot_uint8_t framebuffer_blue_field_position; - multiboot_uint8_t framebuffer_blue_mask_size; - }; - }; -}; - -struct multiboot_tag_elf_sections { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t num; - multiboot_uint32_t entsize; - multiboot_uint32_t shndx; - char sections[0]; -}; - -struct multiboot_tag_apm { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint16_t version; - multiboot_uint16_t cseg; - multiboot_uint32_t offset; - multiboot_uint16_t cseg_16; - multiboot_uint16_t dseg; - multiboot_uint16_t flags; - multiboot_uint16_t cseg_len; - multiboot_uint16_t cseg_16_len; - multiboot_uint16_t dseg_len; -}; - -struct multiboot_tag_efi32 { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; - -struct multiboot_tag_efi64 { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; - -struct multiboot_tag_smbios { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t major; - multiboot_uint8_t minor; - multiboot_uint8_t reserved[6]; - multiboot_uint8_t tables[0]; -}; - -struct multiboot_tag_old_acpi { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_new_acpi { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_network { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t dhcpack[0]; -}; - -struct multiboot_tag_efi_mmap { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t descr_size; - multiboot_uint32_t descr_vers; - multiboot_uint8_t efi_mmap[0]; -}; - -struct multiboot_tag_efi32_ih { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; - -struct multiboot_tag_efi64_ih { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; - -struct multiboot_tag_load_base_addr { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t load_base_addr; -}; - -#endif /* ! ASM_FILE */ - -#endif /* ! MULTIBOOT_HEADER */ diff --git a/launch-qemu.sh b/launch-qemu.sh index 54b2985..52db6a9 100755 --- a/launch-qemu.sh +++ b/launch-qemu.sh @@ -13,6 +13,7 @@ Options: -i [disk], --ide [disk] Use [disk] as a hda on an IDE bus -n, --nohup Run QEMU using nohup and output to /dev/null -m, --max-cpu Run qemu with -m max + --net Launch the kernel using TFTP. (Requires GRUB to be set up) EOF } @@ -23,6 +24,11 @@ while [[ "$#" -gt 0 ]]; do ARGS="${ARGS} -S -s -d guest_errors,int" shift ;; + --net) + cp cmake-build-debug/my-kernel.bin netdir/my-kernel.bin + KERNEL="-netdev user,id=n0,tftp=netdir,bootfile=/boot/grub/i386-pc/core.0 -device e1000,netdev=n0" + shift + ;; -i | --ide) ARGS="${ARGS} -hda $2" shift 2 diff --git a/netdir/.gitignore b/netdir/.gitignore new file mode 100644 index 0000000..7cf8d6c --- /dev/null +++ b/netdir/.gitignore @@ -0,0 +1,3 @@ +my-kernel.bin +boot/grub/* +!boot/grub/grub.cfg \ No newline at end of file diff --git a/netdir/boot/grub/grub.cfg b/netdir/boot/grub/grub.cfg new file mode 100644 index 0000000..4e1a377 --- /dev/null +++ b/netdir/boot/grub/grub.cfg @@ -0,0 +1,7 @@ +set timeout=0 +set default=0 + +menuentry "my-kernel" + multiboot (tftp)/my-kernel.bin + boot +}