1*150a6952SToomas Soome /* 2*150a6952SToomas Soome * This file and its contents are supplied under the terms of the 3*150a6952SToomas Soome * Common Development and Distribution License ("CDDL"), version 1.0. 4*150a6952SToomas Soome * You may only use this file in accordance with the terms of version 5*150a6952SToomas Soome * 1.0 of the CDDL. 6*150a6952SToomas Soome * 7*150a6952SToomas Soome * A full copy of the text of the CDDL should have accompanied this 8*150a6952SToomas Soome * source. A copy of the CDDL is also available via the Internet at 9*150a6952SToomas Soome * http://www.illumos.org/license/CDDL. 10*150a6952SToomas Soome */ 11*150a6952SToomas Soome 12*150a6952SToomas Soome /* 13*150a6952SToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com> 14*150a6952SToomas Soome */ 15*150a6952SToomas Soome 16*150a6952SToomas Soome #include <stdio.h> 17*150a6952SToomas Soome #include <sys/types.h> 18*150a6952SToomas Soome #include <sys/stat.h> 19*150a6952SToomas Soome #include <fcntl.h> 20*150a6952SToomas Soome #include <unistd.h> 21*150a6952SToomas Soome #include <sys/sysmacros.h> 22*150a6952SToomas Soome #include <sys/multiboot.h> 23*150a6952SToomas Soome 24*150a6952SToomas Soome #include "bblk_einfo.h" 25*150a6952SToomas Soome #include "boot_utils.h" 26*150a6952SToomas Soome #include "mboot_extra.h" 27*150a6952SToomas Soome 28*150a6952SToomas Soome /* 29*150a6952SToomas Soome * Add version to loader bootblock file. The file should have fake 30*150a6952SToomas Soome * multiboot header and version data will be added at the end of the file. 31*150a6952SToomas Soome * MB header is fake in sense that this bootblock is *not* MB compatible, 32*150a6952SToomas Soome * and MB header will only include load_addr and load_end_addr components. 33*150a6952SToomas Soome * load_addr will be set to value 0 to indicate the beginning of the file 34*150a6952SToomas Soome * and load_end_addr will be set to the size of the original file. 35*150a6952SToomas Soome * The flags value in header must be exactly AOUT kludge. 36*150a6952SToomas Soome * 37*150a6952SToomas Soome * version data is aligned by 8 bytes and whole blootblock will be padded to 38*150a6952SToomas Soome * 512B sector size. 39*150a6952SToomas Soome * 40*150a6952SToomas Soome * To use and verify version data, first find MB header, then load_end_addr 41*150a6952SToomas Soome * will point to the end of the original file, aligned up by 8, is version 42*150a6952SToomas Soome * data implemented as bblk einfo. 43*150a6952SToomas Soome */ 44*150a6952SToomas Soome 45*150a6952SToomas Soome void 46*150a6952SToomas Soome add_version(char *file, char *version) 47*150a6952SToomas Soome { 48*150a6952SToomas Soome int fd; 49*150a6952SToomas Soome int ret; 50*150a6952SToomas Soome uint32_t buf_size; 51*150a6952SToomas Soome uint32_t mboot_off; 52*150a6952SToomas Soome uint32_t extra; 53*150a6952SToomas Soome uint32_t avail_space; 54*150a6952SToomas Soome multiboot_header_t *mboot; 55*150a6952SToomas Soome struct stat sb; 56*150a6952SToomas Soome char *buf; 57*150a6952SToomas Soome bblk_hs_t hs; 58*150a6952SToomas Soome 59*150a6952SToomas Soome fd = open(file, O_RDONLY); 60*150a6952SToomas Soome if (fd == -1) { 61*150a6952SToomas Soome perror("open"); 62*150a6952SToomas Soome return; 63*150a6952SToomas Soome } 64*150a6952SToomas Soome if (fstat(fd, &sb) == -1) { 65*150a6952SToomas Soome perror("fstat"); 66*150a6952SToomas Soome close(fd); 67*150a6952SToomas Soome return; 68*150a6952SToomas Soome } 69*150a6952SToomas Soome 70*150a6952SToomas Soome /* 71*150a6952SToomas Soome * make sure we have enough space to append EINFO. 72*150a6952SToomas Soome */ 73*150a6952SToomas Soome buf_size = P2ROUNDUP(sb.st_size + SECTOR_SIZE, SECTOR_SIZE); 74*150a6952SToomas Soome buf = malloc(buf_size); 75*150a6952SToomas Soome if (buf == NULL) { 76*150a6952SToomas Soome perror("malloc"); 77*150a6952SToomas Soome close(fd); 78*150a6952SToomas Soome return; 79*150a6952SToomas Soome } 80*150a6952SToomas Soome 81*150a6952SToomas Soome /* 82*150a6952SToomas Soome * read in whole file. we need to access MB header and einfo 83*150a6952SToomas Soome * will create MD5 hash. 84*150a6952SToomas Soome */ 85*150a6952SToomas Soome ret = read(fd, buf, sb.st_size); 86*150a6952SToomas Soome if (ret != sb.st_size) { 87*150a6952SToomas Soome perror("read"); 88*150a6952SToomas Soome free(buf); 89*150a6952SToomas Soome close(fd); 90*150a6952SToomas Soome return; 91*150a6952SToomas Soome } 92*150a6952SToomas Soome close(fd); 93*150a6952SToomas Soome 94*150a6952SToomas Soome if (find_multiboot(buf, MBOOT_SCAN_SIZE, &mboot_off) 95*150a6952SToomas Soome != BC_SUCCESS) { 96*150a6952SToomas Soome printf("Unable to find multiboot header\n"); 97*150a6952SToomas Soome free(buf); 98*150a6952SToomas Soome return; 99*150a6952SToomas Soome } 100*150a6952SToomas Soome 101*150a6952SToomas Soome mboot = (multiboot_header_t *)(buf + mboot_off); 102*150a6952SToomas Soome mboot->load_addr = 0; 103*150a6952SToomas Soome mboot->load_end_addr = sb.st_size; 104*150a6952SToomas Soome 105*150a6952SToomas Soome 106*150a6952SToomas Soome hs.src_buf = (unsigned char *)buf; 107*150a6952SToomas Soome hs.src_size = sb.st_size; 108*150a6952SToomas Soome 109*150a6952SToomas Soome /* 110*150a6952SToomas Soome * this is location for EINFO data 111*150a6952SToomas Soome */ 112*150a6952SToomas Soome extra = P2ROUNDUP(sb.st_size, 8); 113*150a6952SToomas Soome avail_space = buf_size - extra; 114*150a6952SToomas Soome memset(buf+sb.st_size, 0, buf_size - sb.st_size); 115*150a6952SToomas Soome add_einfo(buf + extra, version, &hs, avail_space); 116*150a6952SToomas Soome 117*150a6952SToomas Soome fd = open(file, O_WRONLY | O_TRUNC); 118*150a6952SToomas Soome if (fd == -1) { 119*150a6952SToomas Soome perror("open"); 120*150a6952SToomas Soome free(buf); 121*150a6952SToomas Soome return; 122*150a6952SToomas Soome } 123*150a6952SToomas Soome ret = write(fd, buf, buf_size); 124*150a6952SToomas Soome close(fd); 125*150a6952SToomas Soome free(buf); 126*150a6952SToomas Soome } 127