Import of openhackware-0.4.1
[openhackware.git] / src / libexec / core.c
blob222a29a8ce2a5b24b744f235ecb8da474cfc9c5c
1 /*
2 * <file.c>
4 * Open Hack'Ware BIOS executable file loader
5 *
6 * Copyright (c) 2004-2005 Jocelyn Mayer
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License V2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include "bios.h"
25 #include "exec.h"
27 /*****************************************************************************/
28 uint32_t file_seek (inode_t *file, uint32_t pos)
30 uint32_t blocsize, bloc, offset;
32 if (file == NULL)
33 return -1;
34 blocsize = part_blocsize(fs_inode_get_part(file));
35 bloc = pos / blocsize;
36 offset = pos % blocsize;
38 return fs_seek(file, bloc, offset);
41 /*****************************************************************************/
42 /* Executable file loaders */
44 enum {
45 FILE_TYPE_ELF = 0,
46 FILE_TYPE_XCOFF,
47 FILE_TYPE_MACHO,
48 FILE_TYPE_PEF,
49 FILE_TYPE_CHRP,
50 FILE_TYPE_PREP,
51 FILE_TYPE_FLAT,
54 uint32_t fs_inode_get_size (inode_t *inode);
55 unsigned int part_get_entry (part_t *part);
56 /*****************************************************************************/
57 /* Generic boot file loader */
58 int _bootfile_load (inode_t *file, void **dest, void **entry, void **end,
59 uint32_t loffset, int type)
61 int (*do_load)(inode_t *file, void **dest, void **entry, void **end,
62 uint32_t loffset);
63 uint32_t size;
64 int ret;
65 int i;
67 if (type == -1)
68 i = 0;
69 else
70 i = type;
71 for (;; i++) {
72 switch (i) {
73 case FILE_TYPE_ELF:
74 do_load = &exec_load_elf;
75 break;
76 case FILE_TYPE_XCOFF:
77 do_load = &exec_load_xcoff;
78 break;
79 case FILE_TYPE_MACHO:
80 do_load = &exec_load_macho;
81 break;
82 case FILE_TYPE_PEF:
83 do_load = &exec_load_pef;
84 break;
85 case FILE_TYPE_CHRP:
86 do_load = &exec_load_chrp;
87 break;
88 case FILE_TYPE_PREP:
89 do_load = &exec_load_prep;
90 break;
91 default:
92 if (*dest == NULL)
93 *dest = (void *)DEFAULT_LOAD_DEST;
94 if (*entry == NULL) {
95 if (part_get_entry(fs_inode_get_part(file)) != 0 || 1) {
96 *entry = (char *)*dest +
97 part_get_entry(fs_inode_get_part(file));
98 dprintf("dest %p entry %08x => %p\n",
99 *dest, part_get_entry(fs_inode_get_part(file)),
100 *entry);
101 } else {
102 *entry = *dest + 0xC;
105 size = fs_inode_get_size(file);
106 *end = (char *)*dest + size - loffset;
107 printf("Load raw file into memory at %p %d (%08x) %d (%08x)\n",
108 *dest, size, size, loffset, loffset);
109 file_seek(file, loffset);
110 set_loadinfo(*dest, size);
111 if ((uint32_t)fs_read(file, *dest, size) != size) {
112 ERROR("Error loading file...\n");
113 ret = -1;
114 } else {
115 ret = 0;
117 goto out;
119 DPRINTF("Check file type %d at offset %d %p\n", i, loffset, do_load);
120 ret = (*do_load)(file, dest, entry, end, loffset);
121 if (ret >= -1 || type == i) {
122 if (type == i)
123 ret = -2;
124 break;
127 out:
129 return ret;
132 int bootfile_load (void **dest, void **entry, void **end,
133 part_t *part, int type, const unsigned char *fname,
134 uint32_t loffset)
136 inode_t *file;
137 int ret;
139 DPRINTF("Load file '%s' %p %p type: %d offset: %0x => %d %p\n",
140 fname, part, part_fs(part), type, loffset, part_blocsize(part), *dest);
141 if (fname == NULL)
142 file = fs_get_bootfile(part_fs(part));
143 else
144 file = fs_open(part_fs(part), fname);
145 if (file == NULL)
146 return -1;
147 ret = _bootfile_load(file, dest, entry, end, loffset, type);
148 fs_close(file);
150 return ret;