summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Fogelstrom <pefo@cvs.openbsd.org>1997-10-13 15:35:49 +0000
committerPer Fogelstrom <pefo@cvs.openbsd.org>1997-10-13 15:35:49 +0000
commit7f00fb95b1e76edfd089d25714b87942cb7d5e5d (patch)
tree2b6286e1870e2c62181e559064a19793a8257927
parent2d876bd1a42ac9cd8562f23c50c5931afdbbc6e2 (diff)
New distrib for power pc including RAMDISK
-rw-r--r--distrib/powerpc/common/rdsetroot.c (renamed from distrib/powerpc/elfrdsetroot.c)192
1 files changed, 75 insertions, 117 deletions
diff --git a/distrib/powerpc/elfrdsetroot.c b/distrib/powerpc/common/rdsetroot.c
index 083a44e8f11..160ce12420a 100644
--- a/distrib/powerpc/elfrdsetroot.c
+++ b/distrib/powerpc/common/rdsetroot.c
@@ -1,10 +1,12 @@
+/* $OpenBSD: rdsetroot.c,v 1.1 1997/10/13 15:35:48 pefo Exp $ */
/* $NetBSD: rdsetroot.c,v 1.2 1995/10/13 16:38:39 gwr Exp $ */
/*
- * Copyright (c) 1997 Dale Rahn
* Copyright (c) 1994 Gordon W. Ross
* All rights reserved.
*
+ * ELF modifications Copyright (c) 1997 Per Fogelstrom.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -26,8 +28,6 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id: elfrdsetroot.c,v 1.1 1997/01/31 05:04:44 rahnds Exp $
*/
/*
@@ -35,18 +35,13 @@
* Kernel variables: rd_root_size, rd_root_image
*/
-/*
- * ELF version by Dale Rahn
- */
-
#include <sys/types.h>
#include <sys/file.h>
#include <sys/mman.h>
-#include <sys/stat.h>
#include <stdio.h>
-#include <sys/exec_elf.h>
#include <nlist.h>
+#include <sys/exec_elf.h>
extern off_t lseek();
@@ -62,29 +57,22 @@ long rd_root_image_off, rd_root_size_off;
int rd_root_size_val;
/* pointers to pieces of mapped file */
-char *baseptr;
-
-/* and lengths */
-int data_len;
-int data_off;
-int data_pgoff;
-
+char *dataseg;
-
-char *pexe;
+/* parameters to mmap digged out from program header */
+int mmap_offs;
+int mmap_size;
main(argc,argv)
char **argv;
{
int fd, n;
+ int found;
int *ip;
char *cp;
- struct stat sb;
- Elf32_Ehdr *pehdr;
- Elf32_Shdr *pshdr;
- Elf32_Phdr *pphdr;
- int i;
-
+ Elf32_Ehdr eh;
+ Elf32_Phdr *ph;
+ int phsize;
if (argc < 2) {
printf("%s: missing file name\n", argv[0]);
@@ -98,39 +86,54 @@ main(argc,argv)
exit(1);
}
- fstat(fd, &sb);
- pexe = mmap(0, sb.st_size, PROT_READ|PROT_WRITE,
- MAP_FILE | MAP_SHARED, fd, 0);
-
- pehdr = (Elf32_Ehdr *)pexe;
-
-#ifdef DEBUG
- printf("elf header\n");
- printf("e_type %x\n", pehdr->e_type);
- printf("e_machine %x\n", pehdr->e_machine);
- printf("e_version %x\n", pehdr->e_version);
- printf("e_entry %x\n", pehdr->e_entry);
- printf("e_phoff %x\n", pehdr->e_phoff);
- printf("e_shoff %x\n", pehdr->e_shoff);
- printf("e_flags %x\n", pehdr->e_flags);
- printf("e_ehsize %x\n", pehdr->e_ehsize);
- printf("e_phentsize %x\n", pehdr->e_phentsize);
- printf("e_phnum %x\n", pehdr->e_phnum);
- printf("e_shentsize %x\n", pehdr->e_shentsize);
- printf("e_shnum %x\n", pehdr->e_shnum);
- printf("e_shstrndx %x\n", pehdr->e_shstrndx);
-#endif
-
+ n = read(fd, &eh, sizeof(eh));
+ if (n < sizeof(eh)) {
+ printf("%s: reading header\n", file);
+ exit(1);
+ }
- find_rd_root_image(file);
+ if (!IS_ELF(eh)) {
+ printf("%s: not elf\n", file);
+ exit(1);
+ }
+ phsize = eh.e_phnum * sizeof(Elf32_Phdr);
+ ph = (Elf32_Phdr *)malloc(phsize);
+ lseek(fd, eh.e_phoff, 0);
+ if(read(fd, (char *)ph, phsize) != phsize) {
+ printf("%s: can't read phdr area\n", file);
+ exit(1);
+ }
+ found = 0;
+ for(n = 0; n < eh.e_phnum && !found; n++) {
+ if(ph[n].p_type == PT_LOAD) {
+ found = find_rd_root_image(file, &eh, &ph[n]);
+ }
+ }
+ if(!found) {
+ printf("%s: can't locate space for rd_root_image!", file);
+ exit(1);
+ }
- baseptr = pexe;
+ /*
+ * Map in the whole data segment.
+ * The file offset needs to be page aligned.
+ */
+ dataseg = mmap(NULL, /* any address is ok */
+ mmap_size, /* length */
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ fd, mmap_offs);
+ if ((long)dataseg == -1) {
+ printf("%s: can not map data seg\n", file);
+ perror(file);
+ exit(1);
+ }
/*
* Find value in the location: rd_root_size
*/
- ip = (int*) (baseptr + rd_root_size_off);
+ ip = (int*) (dataseg + rd_root_size_off);
rd_root_size_val = *ip;
#ifdef DEBUG
printf("rd_root_size val: 0x%08X (%d blocks)\n",
@@ -143,7 +146,7 @@ main(argc,argv)
#ifdef DEBUG
printf("copying root image...\n");
#endif
- n = read(0, baseptr + rd_root_image_off,
+ n = read(0, dataseg + rd_root_image_off,
rd_root_size_val);
if (n < 0) {
perror("read");
@@ -151,11 +154,7 @@ main(argc,argv)
}
#if 0
- msync(baseptr, data_len
-#ifdef sun
- ,0
-#endif
- );
+ msync(dataseg, mmap_size);
#endif
#ifdef DEBUG
@@ -175,84 +174,43 @@ struct nlist wantsyms[] = {
{ NULL, 0 },
};
-find_rd_root_image(file)
+int
+find_rd_root_image(file, eh, ph)
char *file;
+ Elf32_Ehdr *eh;
+ Elf32_Phdr *ph;
{
int data_va;
int std_entry;
+ int kernel_start;
+ int kernel_size;
if (nlist(file, wantsyms)) {
printf("%s: no rd_root_image symbols?\n", file);
exit(1);
}
-#if 0
- std_entry = N_TXTADDR(head) +
- (head.a_entry & (N_PAGSIZ(head)-1));
- data_va = N_DATADDR(head);
- if (head.a_entry != std_entry) {
- printf("%s: warning: non-standard entry point: 0x%08x\n",
- file, head.a_entry);
- printf("\texpecting entry=0x%X\n", std_entry);
- data_va += (head.a_entry - std_entry);
- }
-#endif
- {
-
- Elf32_Ehdr *pehdr;
- Elf32_Phdr *phdr;
- int i;
- pehdr = (Elf32_Ehdr *)pexe;
- phdr = (Elf32_Phdr *)(pexe + pehdr->e_phoff);
- printf("sections:\n");
- for (i = 1; i <= pehdr->e_phnum; i++, phdr++) {
- fprintf(stderr, "phseg %d addr %x size %x"
- " offset %x\n",
- i, phdr->p_vaddr, phdr->p_memsz, phdr->p_offset );
- if (wantsyms[0].n_value > phdr->p_vaddr &&
- (wantsyms[0].n_value <
- phdr->p_vaddr + phdr->p_filesz))
- {
- data_va = - (phdr->p_offset - phdr->p_vaddr);
- }
- }
- printf("esections:\n");
-
- }
-
- rd_root_size_off = wantsyms[0].n_value - data_va;
- rd_root_image_off = wantsyms[1].n_value - data_va;
-#ifdef DEBUG
- printf(".data segment va: 0x%08X\n", data_va);
- printf("rd_root_size va: 0x%08X\n", wantsyms[0].n_value);
- printf("rd_root_image va: 0x%08X\n", wantsyms[1].n_value);
- printf("rd_root_size off: 0x%08X\n", rd_root_size_off);
- printf("rd_root_image off: 0x%08X\n", rd_root_image_off);
-
- {
- char *base;
- int *iptr;
- base= (char *)pexe + rd_root_size_off;
- iptr = (int *) base;
- base= (char *)pexe + rd_root_image_off;
- printf("size %x\n", *iptr);
- printf("string [%s]\n", base);
+ kernel_start = ph->p_paddr;
+ kernel_size = ph->p_filesz;
- }
+ rd_root_size_off = wantsyms[0].n_value - kernel_start;
+ rd_root_image_off = wantsyms[1].n_value - kernel_start;
+#ifdef DEBUG
+ printf("rd_root_size_off = 0x%x\n", rd_root_size_off);
+ printf("rd_root_image_off = 0x%x\n", rd_root_image_off);
#endif
-#if 0
/*
* Sanity check locations of db_* symbols
*/
- if (rd_root_image_off < 0 || rd_root_image_off >= head.a_data) {
- printf("%s: rd_root_image not in data segment?\n", file);
- exit(1);
+ if (rd_root_image_off < 0 || rd_root_image_off >= kernel_size) {
+ return(0);
}
- if (rd_root_size_off < 0 || rd_root_size_off >= head.a_data) {
+ if (rd_root_size_off < 0 || rd_root_size_off >= kernel_size) {
printf("%s: rd_root_size not in data segment?\n", file);
- exit(1);
+ return(0);
}
-#endif
+ mmap_offs = ph->p_offset;
+ mmap_size = kernel_size;
+ return(1);
}
-