1*af28f636SEnrico Perla - Sun Microsystems /* 2*af28f636SEnrico Perla - Sun Microsystems * CDDL HEADER START 3*af28f636SEnrico Perla - Sun Microsystems * 4*af28f636SEnrico Perla - Sun Microsystems * The contents of this file are subject to the terms of the 5*af28f636SEnrico Perla - Sun Microsystems * Common Development and Distribution License (the "License"). 6*af28f636SEnrico Perla - Sun Microsystems * You may not use this file except in compliance with the License. 7*af28f636SEnrico Perla - Sun Microsystems * 8*af28f636SEnrico Perla - Sun Microsystems * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*af28f636SEnrico Perla - Sun Microsystems * or http://www.opensolaris.org/os/licensing. 10*af28f636SEnrico Perla - Sun Microsystems * See the License for the specific language governing permissions 11*af28f636SEnrico Perla - Sun Microsystems * and limitations under the License. 12*af28f636SEnrico Perla - Sun Microsystems * 13*af28f636SEnrico Perla - Sun Microsystems * When distributing Covered Code, include this CDDL HEADER in each 14*af28f636SEnrico Perla - Sun Microsystems * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*af28f636SEnrico Perla - Sun Microsystems * If applicable, add the following below this CDDL HEADER, with the 16*af28f636SEnrico Perla - Sun Microsystems * fields enclosed by brackets "[]" replaced with your own identifying 17*af28f636SEnrico Perla - Sun Microsystems * information: Portions Copyright [yyyy] [name of copyright owner] 18*af28f636SEnrico Perla - Sun Microsystems * 19*af28f636SEnrico Perla - Sun Microsystems * CDDL HEADER END 20*af28f636SEnrico Perla - Sun Microsystems */ 21*af28f636SEnrico Perla - Sun Microsystems /* 22*af28f636SEnrico Perla - Sun Microsystems * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23*af28f636SEnrico Perla - Sun Microsystems */ 24*af28f636SEnrico Perla - Sun Microsystems 25*af28f636SEnrico Perla - Sun Microsystems #include <stdio.h> 26*af28f636SEnrico Perla - Sun Microsystems #include <stdlib.h> 27*af28f636SEnrico Perla - Sun Microsystems #include <unistd.h> 28*af28f636SEnrico Perla - Sun Microsystems #include <sys/param.h> 29*af28f636SEnrico Perla - Sun Microsystems #include <sys/bootvfs.h> 30*af28f636SEnrico Perla - Sun Microsystems #include <sys/filep.h> 31*af28f636SEnrico Perla - Sun Microsystems 32*af28f636SEnrico Perla - Sun Microsystems #include <libintl.h> 33*af28f636SEnrico Perla - Sun Microsystems #include <locale.h> 34*af28f636SEnrico Perla - Sun Microsystems #include "message.h" 35*af28f636SEnrico Perla - Sun Microsystems 36*af28f636SEnrico Perla - Sun Microsystems /* 37*af28f636SEnrico Perla - Sun Microsystems * This file is glue layer to pcfs module in usr/src/common/fs/pcfs.c. 38*af28f636SEnrico Perla - Sun Microsystems * It's main functionality is to get the stage file blocklist. It's 39*af28f636SEnrico Perla - Sun Microsystems * used for installing grub on a Solaris boot partition. 40*af28f636SEnrico Perla - Sun Microsystems */ 41*af28f636SEnrico Perla - Sun Microsystems extern struct boot_fs_ops bpcfs_ops; 42*af28f636SEnrico Perla - Sun Microsystems struct boot_fs_ops *bfs_ops; 43*af28f636SEnrico Perla - Sun Microsystems struct boot_fs_ops *bfs_tab[] = {&bpcfs_ops, NULL}; 44*af28f636SEnrico Perla - Sun Microsystems static int dev_fd; 45*af28f636SEnrico Perla - Sun Microsystems int bootrd_debug = 0; 46*af28f636SEnrico Perla - Sun Microsystems 47*af28f636SEnrico Perla - Sun Microsystems #define DEV_BSIZE 512 48*af28f636SEnrico Perla - Sun Microsystems #define MAX_CHUNK 64 49*af28f636SEnrico Perla - Sun Microsystems 50*af28f636SEnrico Perla - Sun Microsystems static unsigned int *blocklist; 51*af28f636SEnrico Perla - Sun Microsystems 52*af28f636SEnrico Perla - Sun Microsystems /* diskread_callback is set in filesytem module (pcfs.c) */ 53*af28f636SEnrico Perla - Sun Microsystems int (*diskread_callback)(int, int); 54*af28f636SEnrico Perla - Sun Microsystems int (*fileread_callback)(int, int); 55*af28f636SEnrico Perla - Sun Microsystems 56*af28f636SEnrico Perla - Sun Microsystems static int 57*af28f636SEnrico Perla - Sun Microsystems add_stage2_block(int blocknum, int nblk) 58*af28f636SEnrico Perla - Sun Microsystems { 59*af28f636SEnrico Perla - Sun Microsystems static int i = -2; 60*af28f636SEnrico Perla - Sun Microsystems 61*af28f636SEnrico Perla - Sun Microsystems if (i >= 0 && (blocklist[i] + blocklist[i + 1] == blocknum)) { 62*af28f636SEnrico Perla - Sun Microsystems blocklist[i + 1] += nblk; 63*af28f636SEnrico Perla - Sun Microsystems return (0); 64*af28f636SEnrico Perla - Sun Microsystems } 65*af28f636SEnrico Perla - Sun Microsystems 66*af28f636SEnrico Perla - Sun Microsystems i += 2; 67*af28f636SEnrico Perla - Sun Microsystems if (i >= DEV_BSIZE / 8) { 68*af28f636SEnrico Perla - Sun Microsystems fprintf(stderr, PCFS_FRAGMENTED); 69*af28f636SEnrico Perla - Sun Microsystems exit(-1); 70*af28f636SEnrico Perla - Sun Microsystems } 71*af28f636SEnrico Perla - Sun Microsystems blocklist[i] = blocknum; 72*af28f636SEnrico Perla - Sun Microsystems blocklist[i + 1] = nblk; 73*af28f636SEnrico Perla - Sun Microsystems return (0); 74*af28f636SEnrico Perla - Sun Microsystems } 75*af28f636SEnrico Perla - Sun Microsystems 76*af28f636SEnrico Perla - Sun Microsystems /* 77*af28f636SEnrico Perla - Sun Microsystems * This one reads the ramdisk. If fi_memp is set, we copy the 78*af28f636SEnrico Perla - Sun Microsystems * ramdisk content to the designated buffer. Otherwise, we 79*af28f636SEnrico Perla - Sun Microsystems * do a "cached" read (set fi_memp to the actual ramdisk buffer). 80*af28f636SEnrico Perla - Sun Microsystems */ 81*af28f636SEnrico Perla - Sun Microsystems int 82*af28f636SEnrico Perla - Sun Microsystems diskread(fileid_t *filep) 83*af28f636SEnrico Perla - Sun Microsystems { 84*af28f636SEnrico Perla - Sun Microsystems int ret; 85*af28f636SEnrico Perla - Sun Microsystems uint_t blocknum, diskloc; 86*af28f636SEnrico Perla - Sun Microsystems 87*af28f636SEnrico Perla - Sun Microsystems blocknum = filep->fi_blocknum; 88*af28f636SEnrico Perla - Sun Microsystems 89*af28f636SEnrico Perla - Sun Microsystems if (diskread_callback) { 90*af28f636SEnrico Perla - Sun Microsystems diskread_callback(blocknum, filep->fi_count / DEV_BSIZE); 91*af28f636SEnrico Perla - Sun Microsystems return (0); 92*af28f636SEnrico Perla - Sun Microsystems } 93*af28f636SEnrico Perla - Sun Microsystems 94*af28f636SEnrico Perla - Sun Microsystems diskloc = blocknum * DEV_BSIZE; 95*af28f636SEnrico Perla - Sun Microsystems if (filep->fi_memp == NULL) { 96*af28f636SEnrico Perla - Sun Microsystems filep->fi_memp = malloc(filep->fi_count); 97*af28f636SEnrico Perla - Sun Microsystems } 98*af28f636SEnrico Perla - Sun Microsystems if (filep->fi_memp == NULL) { 99*af28f636SEnrico Perla - Sun Microsystems fprintf(stderr, OUT_OF_MEMORY); 100*af28f636SEnrico Perla - Sun Microsystems return (-1); 101*af28f636SEnrico Perla - Sun Microsystems } 102*af28f636SEnrico Perla - Sun Microsystems 103*af28f636SEnrico Perla - Sun Microsystems ret = pread(dev_fd, filep->fi_memp, filep->fi_count, diskloc); 104*af28f636SEnrico Perla - Sun Microsystems if (ret < 0) 105*af28f636SEnrico Perla - Sun Microsystems perror("diskread: pread"); 106*af28f636SEnrico Perla - Sun Microsystems return (ret >= 0 ? 0 : -1); 107*af28f636SEnrico Perla - Sun Microsystems } 108*af28f636SEnrico Perla - Sun Microsystems 109*af28f636SEnrico Perla - Sun Microsystems void * 110*af28f636SEnrico Perla - Sun Microsystems bkmem_alloc(size_t s) 111*af28f636SEnrico Perla - Sun Microsystems { 112*af28f636SEnrico Perla - Sun Microsystems return (malloc(s)); 113*af28f636SEnrico Perla - Sun Microsystems } 114*af28f636SEnrico Perla - Sun Microsystems 115*af28f636SEnrico Perla - Sun Microsystems /*ARGSUSED*/ 116*af28f636SEnrico Perla - Sun Microsystems void 117*af28f636SEnrico Perla - Sun Microsystems bkmem_free(void *p, size_t s) 118*af28f636SEnrico Perla - Sun Microsystems { 119*af28f636SEnrico Perla - Sun Microsystems free(p); 120*af28f636SEnrico Perla - Sun Microsystems } 121*af28f636SEnrico Perla - Sun Microsystems 122*af28f636SEnrico Perla - Sun Microsystems static int 123*af28f636SEnrico Perla - Sun Microsystems mountroot(char *name) 124*af28f636SEnrico Perla - Sun Microsystems { 125*af28f636SEnrico Perla - Sun Microsystems int i; 126*af28f636SEnrico Perla - Sun Microsystems 127*af28f636SEnrico Perla - Sun Microsystems /* try ops in bfs_tab and return the first successful one */ 128*af28f636SEnrico Perla - Sun Microsystems for (i = 0; bfs_tab[i] != NULL; i++) { 129*af28f636SEnrico Perla - Sun Microsystems bfs_ops = bfs_tab[i]; 130*af28f636SEnrico Perla - Sun Microsystems if (BRD_MOUNTROOT(bfs_ops, name) == 0) 131*af28f636SEnrico Perla - Sun Microsystems return (0); 132*af28f636SEnrico Perla - Sun Microsystems } 133*af28f636SEnrico Perla - Sun Microsystems return (-1); 134*af28f636SEnrico Perla - Sun Microsystems } 135*af28f636SEnrico Perla - Sun Microsystems 136*af28f636SEnrico Perla - Sun Microsystems static int 137*af28f636SEnrico Perla - Sun Microsystems unmountroot() 138*af28f636SEnrico Perla - Sun Microsystems { 139*af28f636SEnrico Perla - Sun Microsystems return (BRD_UNMOUNTROOT(bfs_ops)); 140*af28f636SEnrico Perla - Sun Microsystems } 141*af28f636SEnrico Perla - Sun Microsystems 142*af28f636SEnrico Perla - Sun Microsystems static int 143*af28f636SEnrico Perla - Sun Microsystems pcfs_glue_open(const char *filename, int flags) 144*af28f636SEnrico Perla - Sun Microsystems { 145*af28f636SEnrico Perla - Sun Microsystems return (BRD_OPEN(bfs_ops, (char *)filename, flags)); 146*af28f636SEnrico Perla - Sun Microsystems } 147*af28f636SEnrico Perla - Sun Microsystems 148*af28f636SEnrico Perla - Sun Microsystems static int 149*af28f636SEnrico Perla - Sun Microsystems pcfs_glue_close(int fd) 150*af28f636SEnrico Perla - Sun Microsystems { 151*af28f636SEnrico Perla - Sun Microsystems return (BRD_CLOSE(bfs_ops, fd)); 152*af28f636SEnrico Perla - Sun Microsystems } 153*af28f636SEnrico Perla - Sun Microsystems 154*af28f636SEnrico Perla - Sun Microsystems static ssize_t 155*af28f636SEnrico Perla - Sun Microsystems pcfs_glue_read(int fd, void *buf, size_t size) 156*af28f636SEnrico Perla - Sun Microsystems { 157*af28f636SEnrico Perla - Sun Microsystems return (BRD_READ(bfs_ops, fd, buf, size)); 158*af28f636SEnrico Perla - Sun Microsystems } 159*af28f636SEnrico Perla - Sun Microsystems 160*af28f636SEnrico Perla - Sun Microsystems /* 161*af28f636SEnrico Perla - Sun Microsystems * Get the blocklist for stage2 162*af28f636SEnrico Perla - Sun Microsystems */ 163*af28f636SEnrico Perla - Sun Microsystems int 164*af28f636SEnrico Perla - Sun Microsystems read_stage2_blocklist(int device_fd, unsigned int *blkbuf) 165*af28f636SEnrico Perla - Sun Microsystems { 166*af28f636SEnrico Perla - Sun Microsystems int i, fd, stage2_block; 167*af28f636SEnrico Perla - Sun Microsystems char buf[DEV_BSIZE]; 168*af28f636SEnrico Perla - Sun Microsystems ssize_t size; 169*af28f636SEnrico Perla - Sun Microsystems 170*af28f636SEnrico Perla - Sun Microsystems dev_fd = device_fd; 171*af28f636SEnrico Perla - Sun Microsystems if (mountroot("dummy") != 0) { 172*af28f636SEnrico Perla - Sun Microsystems fprintf(stderr, MOUNT_FAIL_PCFS); 173*af28f636SEnrico Perla - Sun Microsystems return (-1); 174*af28f636SEnrico Perla - Sun Microsystems } 175*af28f636SEnrico Perla - Sun Microsystems 176*af28f636SEnrico Perla - Sun Microsystems if ((fd = pcfs_glue_open("/boot/grub/stage2", 0)) == -1) { 177*af28f636SEnrico Perla - Sun Microsystems fprintf(stderr, OPEN_FAIL_PCFS); 178*af28f636SEnrico Perla - Sun Microsystems return (-1); 179*af28f636SEnrico Perla - Sun Microsystems } 180*af28f636SEnrico Perla - Sun Microsystems 181*af28f636SEnrico Perla - Sun Microsystems if (bootrd_debug) 182*af28f636SEnrico Perla - Sun Microsystems (void) printf("start reading stage2:\n"); 183*af28f636SEnrico Perla - Sun Microsystems stage2_block = 0; 184*af28f636SEnrico Perla - Sun Microsystems blocklist = blkbuf; 185*af28f636SEnrico Perla - Sun Microsystems fileread_callback = add_stage2_block; 186*af28f636SEnrico Perla - Sun Microsystems for (;;) { 187*af28f636SEnrico Perla - Sun Microsystems size = pcfs_glue_read(fd, buf, DEV_BSIZE); 188*af28f636SEnrico Perla - Sun Microsystems if (size != DEV_BSIZE) 189*af28f636SEnrico Perla - Sun Microsystems break; 190*af28f636SEnrico Perla - Sun Microsystems stage2_block++; 191*af28f636SEnrico Perla - Sun Microsystems } 192*af28f636SEnrico Perla - Sun Microsystems fileread_callback = NULL; 193*af28f636SEnrico Perla - Sun Microsystems (void) pcfs_glue_close(fd); 194*af28f636SEnrico Perla - Sun Microsystems 195*af28f636SEnrico Perla - Sun Microsystems if (bootrd_debug) { 196*af28f636SEnrico Perla - Sun Microsystems (void) printf("last block size = %d\n", size); 197*af28f636SEnrico Perla - Sun Microsystems for (i = 0; blocklist[i] != 0; i += 2) { 198*af28f636SEnrico Perla - Sun Microsystems (void) printf("sectors: %d-%d\n", 199*af28f636SEnrico Perla - Sun Microsystems blocklist[i], 200*af28f636SEnrico Perla - Sun Microsystems blocklist[i] + blocklist[i + 1] - 1); 201*af28f636SEnrico Perla - Sun Microsystems } 202*af28f636SEnrico Perla - Sun Microsystems (void) printf("total blocks in stage 2: %d\n", stage2_block); 203*af28f636SEnrico Perla - Sun Microsystems } 204*af28f636SEnrico Perla - Sun Microsystems 205*af28f636SEnrico Perla - Sun Microsystems (void) unmountroot(); 206*af28f636SEnrico Perla - Sun Microsystems return (0); 207*af28f636SEnrico Perla - Sun Microsystems } 208