Revert back to not baking the bootloader into the limine-install binary

This commit is contained in:
mintsuki 2020-09-15 12:16:31 +02:00
parent 1ddf568281
commit e7838e854f
3 changed files with 65 additions and 49 deletions

View File

@ -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

View File

@ -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 <path to device/image>
limine-install <bootloader image> <path to device/image>
```
Where `<bootloader image>` 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 <device> # Create bootloader partition using your favourite method
limine-install <path to device/image> <start sector of boot partition>
limine-install <bootloader image> <path to device/image> <start sector of boot partition>
```
### 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:

View File

@ -4,41 +4,62 @@
#include <stddef.h>
#include <inttypes.h>
extern char _binary_limine_bin_start[];
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <device> [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 <bootloader image> <device> [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;
}