From e7838e854f2463e926fb05601c1762f7b2084bd3 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Tue, 15 Sep 2020 12:16:31 +0200 Subject: [PATCH] Revert back to not baking the bootloader into the limine-install binary --- Makefile | 39 +++++++++++++-------------------------- README.md | 27 +++++++++++++++++---------- limine-install.c | 48 +++++++++++++++++++++++++++++++++++------------- 3 files changed, 65 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index 2a18707f..c3b81d40 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,14 @@ -DESTDIR = -PREFIX = /usr/local - CC = cc -OBJCOPY = objcopy CFLAGS = -O2 -pipe -Wall -Wextra -.PHONY: all clean install toolchain stage2 stage2-clean decompressor decompressor-clean limine limine-clean test.img echfs-test ext2-test fat32-test +.PHONY: all clean stage2 stage2-clean decompressor decompressor-clean toolchain test.img echfs-test ext2-test fat32-test -all: limine-install +all: stage2 decompressor + gzip -n -9 < stage2/stage2.bin > stage2/stage2.bin.gz + cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin -limine-install: limine.bin limine-install.c - $(OBJCOPY) -I binary -O default limine.bin limine.o - $(CC) $(CFLAGS) limine.o limine-install.c -o limine-install - -clean: - rm -f limine.o limine-install - -install: all - install -s limine-install $(DESTDIR)$(PREFIX)/bin/ - -toolchain: - cd toolchain && ./make_toolchain.sh -j`nproc` +clean: stage2-clean decompressor-clean + rm -f stage2/stage2.bin.gz stage2: $(MAKE) -C stage2 all @@ -34,12 +22,11 @@ decompressor: decompressor-clean: $(MAKE) -C decompressor clean -limine: stage2 decompressor - gzip -n -9 < stage2/stage2.bin > stage2/stage2.bin.gz - cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin +toolchain: + cd toolchain && ./make_toolchain.sh -j`nproc` -limine-clean: stage2-clean decompressor-clean - rm -f stage2/stage2.bin.gz +limine-install: limine-install.c + $(CC) $(CFLAGS) limine-install.c -o limine-install test.img: rm -f test.img @@ -52,7 +39,7 @@ echfs-test: limine-install test.img echfs-utils -m -p0 test.img quick-format 512 echfs-utils -m -p0 test.img import test/test.elf boot/test.elf echfs-utils -m -p0 test.img import test/limine.cfg limine.cfg - ./limine-install test.img + ./limine-install limine.bin test.img qemu-system-x86_64 -hda test.img -debugcon stdio -enable-kvm ext2-test: limine-install test.img @@ -70,7 +57,7 @@ ext2-test: limine-install test.img sudo umount test_image/ sudo losetup -d `cat loopback_dev` rm -rf test_image loopback_dev - ./limine-install test.img + ./limine-install limine.bin test.img qemu-system-x86_64 -hda test.img -debugcon stdio fat32-test: limine-install test.img @@ -88,5 +75,5 @@ fat32-test: limine-install test.img sudo umount test_image/ sudo losetup -d `cat loopback_dev` rm -rf test_image loopback_dev - ./limine-install test.img + ./limine-install limine.bin test.img qemu-system-x86_64 -hda test.img -debugcon stdio diff --git a/README.md b/README.md index 9412119b..20df7dc5 100644 --- a/README.md +++ b/README.md @@ -30,39 +30,45 @@ This can be accomplished by running: ```bash make toolchain ``` +*The above step may take a while* After that is done, the bootloader itself can be built with: ```bash -make limine +make ``` -A newly generated `limine.bin` image should now be present in the root dir of the repo. +A newly generated `limine.bin` image should now be present in the root of the repo. -This newly built image should match 1:1 (aka, same checksum) as the one shipped with the -respective commit. +This newly built image should match 1:1 (aka, same checksum) with the one shipped +with the respective commit. ### Compiling `limine-install` -A simple `make` and `make install` will suffice. Use the PREFIX variable with -`make install` to specify where to install `limine-install`. It defaults to -`/usr/local`. +To build the `limine-install` program, simply run `make limine-install` in the root +of the repo. ## How to use +### MBR In order to install Limine on a MBR device (which can just be a raw image file), run the `limine-install` as such: ```bash -limine-install +limine-install ``` +Where `` is the path to a `limine.bin` file. + +### GPT If using a GPT formatted device, it will be necessary to create an extra partition (of at least 32K in size) to store stage 2 code. Then it will be necessary to tell -`limine-install` where this partition is located by specifying the start sector. +`limine-install` where this partition is located by specifying the start sector +number (in decimal). ```bash fdisk # Create bootloader partition using your favourite method -limine-install +limine-install ``` +### Configuration Then make sure the device/image contains at least 1 partition formatted in a supported filesystem containing a `/limine.cfg` or `/boot/limine.cfg` file and the kernel/modules one wants to load. @@ -71,6 +77,7 @@ An example `limine.cfg` file can be found in `test/limine.cfg`. More info on the format of `limine.cfg` can be found in `CONFIG.md`. +### Example For example, to create an empty image file of 64MiB in size, 1 echfs partition on the image spanning the whole device, format it, copy the relevant files over, and install Limine, one can do: diff --git a/limine-install.c b/limine-install.c index a7e59b30..dc4fe6d9 100644 --- a/limine-install.c +++ b/limine-install.c @@ -4,41 +4,62 @@ #include #include -extern char _binary_limine_bin_start[]; - int main(int argc, char *argv[]) { - if (argc < 2) { - printf("Usage: %s [stage2 start sector]\n", argv[0]); + FILE *bootloader_file, *device; + uint8_t *bootloader_img; + uint8_t orig_mbr[70], timestamp[6]; + uint32_t stage2_sect; + + if (argc < 3) { + printf("Usage: %s [stage2 start sector]\n", argv[0]); return 1; } - FILE *device = fopen(argv[1], "r+b"); - if (device == NULL) { + bootloader_file = fopen(argv[1], "rb"); + if (bootloader_file == NULL) { perror("Error: "); return 1; } - uint32_t stage2_sect = 1; - if (argc >= 3) - sscanf(argv[2], "%" SCNu32, &stage2_sect); + // The bootloader image is 64 sectors (32k) + bootloader_img = malloc(64 * 512); + if (bootloader_img == NULL) { + perror("Error: "); + fclose(bootloader_file); + return 1; + } + + // Load in bootloader image + fseek(bootloader_file, 0, SEEK_SET); + fread(bootloader_img, 64, 512, bootloader_file); + fclose(bootloader_file); + + device = fopen(argv[2], "r+b"); + if (device == NULL) { + perror("Error: "); + free(bootloader_img); + return 1; + } + + stage2_sect = 1; + if (argc >= 4) + sscanf(argv[3], "%" SCNu32, &stage2_sect); // Save original timestamp - uint8_t timestamp[6]; fseek(device, 218, SEEK_SET); fread(timestamp, 1, 6, device); // Save the original partition table of the device - uint8_t orig_mbr[70]; fseek(device, 440, SEEK_SET); fread(orig_mbr, 1, 70, device); // Write the bootsector from the bootloader to the device fseek(device, 0, SEEK_SET); - fwrite(&_binary_limine_bin_start[0], 1, 512, device); + fwrite(&bootloader_img[0], 1, 512, device); // Write the rest of stage 2 to the device fseek(device, stage2_sect * 512, SEEK_SET); - fwrite(&_binary_limine_bin_start[512], 63, 512, device); + fwrite(&bootloader_img[512], 63, 512, device); // Hardcode in the bootsector the location of stage 2 fseek(device, 0x1b0, SEEK_SET); @@ -53,6 +74,7 @@ int main(int argc, char *argv[]) { fwrite(orig_mbr, 1, 70, device); fclose(device); + free(bootloader_img); return 0; }