1 /* $OpenBSD: rd.c,v 1.4 2013/03/24 19:20:35 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2010 Miodrag Vallat. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include "libsa.h" 21 #include <machine/cpu.h> 22 #include <sys/exec_elf.h> 23 24 static off_t rdoffs; 25 26 /* 27 * INITRD I/O 28 */ 29 30 int 31 rd_iostrategy(void *f, int rw, daddr32_t dblk, size_t size, void *buf, 32 size_t *rsize) 33 { 34 /* never invoked directly */ 35 return ENXIO; 36 } 37 38 int 39 rd_ioopen(struct open_file *f, ...) 40 { 41 return 0; 42 } 43 44 int 45 rd_ioclose(struct open_file *f) 46 { 47 return 0; 48 } 49 50 int 51 rd_isvalid() 52 { 53 Elf64_Ehdr *elf64 = (Elf64_Ehdr *)INITRD_BASE; 54 55 if (memcmp(elf64->e_ident, ELFMAG, SELFMAG) != 0 || 56 elf64->e_ident[EI_CLASS] != ELFCLASS64 || 57 elf64->e_ident[EI_DATA] != ELFDATA2LSB || 58 elf64->e_type != ET_EXEC || elf64->e_machine != EM_MIPS) 59 return 0; 60 61 return 1; 62 } 63 64 void 65 rd_invalidate() 66 { 67 bzero((void *)INITRD_BASE, sizeof(Elf64_Ehdr)); 68 } 69 70 /* 71 * INITRD filesystem 72 */ 73 int 74 rdfs_open(char *path, struct open_file *f) 75 { 76 if (f->f_dev->dv_open == rd_ioopen) { 77 if (strcmp(path, kernelfile) == 0) { 78 rdoffs = 0; 79 return 0; 80 } else 81 return ENOENT; 82 } 83 84 return EINVAL; 85 } 86 87 int 88 rdfs_close(struct open_file *f) 89 { 90 return 0; 91 } 92 93 int 94 rdfs_read(struct open_file *f, void *buf, size_t size, size_t *resid) 95 { 96 if (size != 0) { 97 bcopy((void *)(INITRD_BASE + rdoffs), buf, size); 98 rdoffs += size; 99 } 100 *resid = 0; 101 102 return 0; 103 } 104 105 int 106 rdfs_write(struct open_file *f, void *buf, size_t size, size_t *resid) 107 { 108 return EROFS; 109 } 110 111 off_t 112 rdfs_seek(struct open_file *f, off_t offset, int whence) 113 { 114 switch (whence) { 115 case 0: /* SEEK_SET */ 116 rdoffs = offset; 117 break; 118 case 1: /* SEEK_CUR */ 119 rdoffs += offset; 120 break; 121 default: 122 errno = EIO; 123 return -1; 124 } 125 126 return rdoffs; 127 } 128 129 int 130 rdfs_stat(struct open_file *f, struct stat *sb) 131 { 132 return EIO; 133 } 134 135 #ifndef NO_READDIR 136 int 137 rdfs_readdir(struct open_file *f, char *path) 138 { 139 return EIO; 140 } 141 #endif 142