10cc5983cSToomas Soome /*
20cc5983cSToomas Soome * This file and its contents are supplied under the terms of the
30cc5983cSToomas Soome * Common Development and Distribution License ("CDDL"), version 1.0.
40cc5983cSToomas Soome * You may only use this file in accordance with the terms of version
50cc5983cSToomas Soome * 1.0 of the CDDL.
60cc5983cSToomas Soome *
70cc5983cSToomas Soome * A full copy of the text of the CDDL should have accompanied this
80cc5983cSToomas Soome * source. A copy of the CDDL is also available via the Internet at
90cc5983cSToomas Soome * http://www.illumos.org/license/CDDL.
100cc5983cSToomas Soome */
110cc5983cSToomas Soome
120cc5983cSToomas Soome /*
130cc5983cSToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com>
140cc5983cSToomas Soome */
150cc5983cSToomas Soome
160cc5983cSToomas Soome #include <stdio.h>
170cc5983cSToomas Soome #include <sys/types.h>
180cc5983cSToomas Soome #include <sys/stat.h>
190cc5983cSToomas Soome #include <fcntl.h>
200cc5983cSToomas Soome #include <unistd.h>
210cc5983cSToomas Soome #include <sys/sysmacros.h>
220cc5983cSToomas Soome #include <sys/multiboot.h>
230cc5983cSToomas Soome
240cc5983cSToomas Soome #include "bblk_einfo.h"
250cc5983cSToomas Soome #include "boot_utils.h"
260cc5983cSToomas Soome #include "mboot_extra.h"
270cc5983cSToomas Soome
280cc5983cSToomas Soome /*
290cc5983cSToomas Soome * Add version to loader bootblock file. The file should have fake
300cc5983cSToomas Soome * multiboot header and version data will be added at the end of the file.
310cc5983cSToomas Soome * MB header is fake in sense that this bootblock is *not* MB compatible,
320cc5983cSToomas Soome * and MB header will only include load_addr and load_end_addr components.
330cc5983cSToomas Soome * load_addr will be set to value 0 to indicate the beginning of the file
340cc5983cSToomas Soome * and load_end_addr will be set to the size of the original file.
350cc5983cSToomas Soome * The flags value in header must be exactly AOUT kludge.
360cc5983cSToomas Soome *
370cc5983cSToomas Soome * version data is aligned by 8 bytes and whole blootblock will be padded to
380cc5983cSToomas Soome * 512B sector size.
390cc5983cSToomas Soome *
400cc5983cSToomas Soome * To use and verify version data, first find MB header, then load_end_addr
410cc5983cSToomas Soome * will point to the end of the original file, aligned up by 8, is version
420cc5983cSToomas Soome * data implemented as bblk einfo.
430cc5983cSToomas Soome */
440cc5983cSToomas Soome
450cc5983cSToomas Soome void
add_version(const char * ifile,const char * ofile,char * version)46*b59f980dSToomas Soome add_version(const char *ifile, const char *ofile, char *version)
470cc5983cSToomas Soome {
480cc5983cSToomas Soome int fd;
490cc5983cSToomas Soome int ret;
500cc5983cSToomas Soome uint32_t buf_size;
510cc5983cSToomas Soome uint32_t mboot_off;
520cc5983cSToomas Soome uint32_t extra;
530cc5983cSToomas Soome uint32_t avail_space;
540cc5983cSToomas Soome multiboot_header_t *mboot;
550cc5983cSToomas Soome struct stat sb;
560cc5983cSToomas Soome char *buf;
570cc5983cSToomas Soome bblk_hs_t hs;
580cc5983cSToomas Soome
59*b59f980dSToomas Soome fd = open(ifile, O_RDONLY);
600cc5983cSToomas Soome if (fd == -1) {
610cc5983cSToomas Soome perror("open");
620cc5983cSToomas Soome return;
630cc5983cSToomas Soome }
640cc5983cSToomas Soome if (fstat(fd, &sb) == -1) {
650cc5983cSToomas Soome perror("fstat");
660cc5983cSToomas Soome close(fd);
670cc5983cSToomas Soome return;
680cc5983cSToomas Soome }
690cc5983cSToomas Soome
700cc5983cSToomas Soome /*
710cc5983cSToomas Soome * make sure we have enough space to append EINFO.
720cc5983cSToomas Soome */
730cc5983cSToomas Soome buf_size = P2ROUNDUP(sb.st_size + SECTOR_SIZE, SECTOR_SIZE);
740cc5983cSToomas Soome buf = malloc(buf_size);
750cc5983cSToomas Soome if (buf == NULL) {
760cc5983cSToomas Soome perror("malloc");
770cc5983cSToomas Soome close(fd);
780cc5983cSToomas Soome return;
790cc5983cSToomas Soome }
800cc5983cSToomas Soome
810cc5983cSToomas Soome /*
820cc5983cSToomas Soome * read in whole file. we need to access MB header and einfo
830cc5983cSToomas Soome * will create MD5 hash.
840cc5983cSToomas Soome */
850cc5983cSToomas Soome ret = read(fd, buf, sb.st_size);
860cc5983cSToomas Soome if (ret != sb.st_size) {
870cc5983cSToomas Soome perror("read");
880cc5983cSToomas Soome free(buf);
890cc5983cSToomas Soome close(fd);
900cc5983cSToomas Soome return;
910cc5983cSToomas Soome }
920cc5983cSToomas Soome close(fd);
930cc5983cSToomas Soome
940cc5983cSToomas Soome if (find_multiboot(buf, MBOOT_SCAN_SIZE, &mboot_off)
950cc5983cSToomas Soome != BC_SUCCESS) {
960cc5983cSToomas Soome printf("Unable to find multiboot header\n");
970cc5983cSToomas Soome free(buf);
980cc5983cSToomas Soome return;
990cc5983cSToomas Soome }
1000cc5983cSToomas Soome
1010cc5983cSToomas Soome mboot = (multiboot_header_t *)(buf + mboot_off);
1020cc5983cSToomas Soome mboot->load_addr = 0;
1030cc5983cSToomas Soome mboot->load_end_addr = sb.st_size;
1040cc5983cSToomas Soome
1050cc5983cSToomas Soome
1060cc5983cSToomas Soome hs.src_buf = (unsigned char *)buf;
1070cc5983cSToomas Soome hs.src_size = sb.st_size;
1080cc5983cSToomas Soome
1090cc5983cSToomas Soome /*
1100cc5983cSToomas Soome * this is location for EINFO data
1110cc5983cSToomas Soome */
1120cc5983cSToomas Soome extra = P2ROUNDUP(sb.st_size, 8);
1130cc5983cSToomas Soome avail_space = buf_size - extra;
1140cc5983cSToomas Soome memset(buf+sb.st_size, 0, buf_size - sb.st_size);
1150cc5983cSToomas Soome add_einfo(buf + extra, version, &hs, avail_space);
1160cc5983cSToomas Soome
117*b59f980dSToomas Soome fd = open(ofile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
1180cc5983cSToomas Soome if (fd == -1) {
1190cc5983cSToomas Soome perror("open");
1200cc5983cSToomas Soome free(buf);
1210cc5983cSToomas Soome return;
1220cc5983cSToomas Soome }
1230cc5983cSToomas Soome ret = write(fd, buf, buf_size);
1240cc5983cSToomas Soome close(fd);
1250cc5983cSToomas Soome free(buf);
1260cc5983cSToomas Soome }
127