123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /*
- * x86_64-bios/mkboot.c
- *
- * Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
- *
- * 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 THE AUTHORS OR COPYRIGHT
- * HOLDERS 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.
- *
- * This file is part of the BOOTBOOT Protocol package.
- * @brief Little tool to install boot.bin in MBR or VBR
- *
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
- /* the BOOTBOOT 1st stage loader code */
- extern unsigned char *_binary____dist_boot_bin_start;
- /* entry point */
- int main(int argc, char** argv)
- {
- // variables
- unsigned char bootrec[512], data[512];
- int f, lba=0, seek=0, lsn, bootlsn=-1;
- // check arguments
- if(argc < 2) {
- printf( "BOOTBOOT mkboot utility - bztsrc@gitlab\n\nUsage:\n"
- " ./mkboot <disk> [partition lba] [bootsector lba]\n\n"
- "Installs boot record on a disk. Disk can be a local file, a disk or partition\n"
- "device. If you want to install it on a partition, you'll have to specify the\n"
- "starting LBA of that partition as well. Requires that bootboot.bin is already\n"
- "copied on the disk in a contiguous area in order to work.\n\n"
- "Examples:\n"
- " ./mkboot diskimage.dd - installing on a disk image\n"
- " ./mkboot /dev/sda - installing as (P)MBR\n"
- " ./mkboot /dev/sda 123 - installing as VBR on a disk device\n"
- " ./mkboot /dev/sda1 123 0 - installing as VBR on a partition device\n");
- return 1;
- }
- if(argc > 2 || argv[2]!=NULL) {
- lba = seek = atoi(argv[2]);
- }
- if(argc > 3 || argv[3]!=NULL) {
- seek = atoi(argv[3]);
- }
- if(lba < seek) seek = lba;
- // open file
- f = open(argv[1], O_RDONLY);
- if(f < 0) {
- fprintf(stderr, "mkboot: file not found\n");
- return 2;
- }
- // read the boot record
- if(seek>0) lseek(f, seek*512, SEEK_SET);
- if(read(f, data, 512)==-1) {
- close(f);
- fprintf(stderr, "mkboot: unable to read file\n");
- return 2;
- }
- // create the boot record. First copy the code then the data area from original sector on disk
- memcpy((void*)&bootrec, (void*)&_binary____dist_boot_bin_start, 512);
- memcpy((void*)&bootrec+0x3, (void*)&data+0x3, 0x78-0x3); // copy BPB (if any)
- memcpy((void*)&bootrec+0x1B8, (void*)&data+0x1B8, 510-0x1B8); // copy WNTID and partitioning table (if any)
- // now locate the second stage by magic bytes
- for(lsn = 1; lsn < 1024*1024; lsn++) {
- printf("Checking sector %d\r", lsn);
- if(read(f, data, 512) != -1 &&
- data[0] == 0x55 && data[1] == 0xAA && data[3] == 0xE9 && data[8] == 'B' && data[12] == 'B') {
- bootlsn=lsn;
- break;
- }
- }
- close(f);
- if(bootlsn == -1) {
- fprintf(stderr, "mkboot: unable to locate 2nd stage (bootboot.bin) in the first 512 Mbyte\n");
- return 2;
- }
- // add bootboot.bin's address to boot record
- bootlsn += lba - seek;
- memcpy((void*)&bootrec+0x1B0, (void*)&bootlsn, 4);
- // save boot record
- f = open(argv[1], O_WRONLY);
- if(seek>0 && f) lseek(f, seek*512, SEEK_SET);
- if(f < 0 || write(f, bootrec, 512) <= 0) {
- fprintf(stderr, "mkboot: unable to write boot record\n");
- return 3;
- }
- close(f);
- // all went well
- printf("mkboot: BOOTBOOT installed, 2nd stage starts at LBA %d\n", bootlsn);
- }
|