8 #include <syslinux/adv.h>
9 #include <syslinux/config.h>
11 #include <linux/list.h>
12 #include <netinet/in.h>
22 #include <sys/module.h>
25 extern char __dynstr_start
[];
26 extern char __dynstr_end
[], __dynsym_end
[];
27 extern char __dynsym_start
[];
28 extern char __got_start
[];
29 extern Elf_Dyn __dynamic_start
[];
30 extern Elf_Word __gnu_hash_start
[];
31 extern char __module_start
[];
33 struct elf_module core_module
= {
36 .required
= LIST_HEAD_INIT((core_module
.required
)),
37 .dependants
= LIST_HEAD_INIT((core_module
.dependants
)),
38 .list
= LIST_HEAD_INIT((core_module
.list
)),
39 .module_addr
= (void *)0x0,
40 .ghash_table
= __gnu_hash_start
,
41 .str_table
= __dynstr_start
,
42 .sym_table
= __dynsym_start
,
44 .dyn_table
= __dynamic_start
,
45 .syment_size
= sizeof(Elf_Sym
),
49 * Initializes the module subsystem by taking the core module
50 * (preinitialized shallow module) and placing it on top of the
53 void init_module_subsystem(struct elf_module
*module
)
55 list_add(&module
->list
, &modules_head
);
58 __export
int start_ldlinux(int argc
, char **argv
)
63 rv
= spawn_load(LDLINUX
, argc
, argv
);
66 * If a COM32 module calls execute() we may need to
67 * unload all the modules loaded since ldlinux.*,
68 * and restart initialisation. This is especially
69 * important for config files.
71 * But before we do that, try our best to make sure
72 * that spawn_load() is gonna succeed, e.g. that we
73 * can find LDLINUX it in PATH.
75 struct elf_module
*ldlinux
;
78 f
= findpath(LDLINUX
);
83 ldlinux
= unload_modules_since(LDLINUX
);
86 * Finally unload LDLINUX.
88 * We'll reload it when we jump to 'again' which will
89 * cause all the initialsation steps to be executed
92 module_unload(ldlinux
);
99 /* note to self: do _*NOT*_ use static key word on this function */
100 void load_env32(com32sys_t
* regs __unused
)
102 struct file_info
*fp
;
104 char *argv
[] = { LDLINUX
, NULL
};
105 char realname
[FILENAME_MAX
];
108 static const char *search_directories
[] = {
117 static const char *filenames
[] = {
122 dprintf("Starting %s elf module subsystem...\n", ELF_MOD_SYS
);
124 if (strlen(CurrentDirName
) && !path_add(CurrentDirName
)) {
125 printf("Couldn't allocate memory for PATH\n");
129 size
= (size_t)__dynstr_end
- (size_t)__dynstr_start
;
130 core_module
.strtable_size
= size
;
131 size
= (size_t)__dynsym_end
- (size_t)__dynsym_start
;
132 core_module
.symtable_size
= size
;
133 core_module
.base_addr
= (Elf_Addr
)__module_start
;
135 init_module_subsystem(&core_module
);
137 start_ldlinux(1, argv
);
140 * If we failed to load LDLINUX it could be because our
141 * current working directory isn't the install directory. Try
142 * a bit harder to find LDLINUX. If search_dirs() succeeds
143 * in finding LDLINUX it will set the cwd.
145 fd
= opendev(&__file_dev
, NULL
, O_RDONLY
);
149 fp
= &__file_info
[fd
];
151 if (!search_dirs(&fp
->i
.fd
, search_directories
, filenames
, realname
)) {
152 char path
[FILENAME_MAX
];
155 * search_dirs() sets the current working directory if
156 * it successfully opens the file. Add the directory
157 * in which we found ldlinux.* to PATH.
159 if (!core_getcwd(path
, sizeof(path
)))
162 if (!path_add(path
)) {
163 printf("Couldn't allocate memory for PATH\n");
167 start_ldlinux(1, argv
);
171 writestr("\nFailed to load ");
175 static const char *__cmdline
;
176 __export
const char *com32_cmdline(void)
181 __export
int create_args_and_load(char *cmdline
)
190 for (argc
= 0, p
= cmdline
; *p
; argc
++) {
191 /* Find the end of this arg */
192 while(*p
&& !isspace(*p
))
196 * Now skip all whitespace between arguments.
198 while (*p
&& isspace(*p
))
203 * Generate a copy of argv on the stack as this is
204 * traditionally where process arguments go.
206 * argv[0] must be the command name. Remember to allocate
207 * space for the sentinel NULL.
209 argv
= alloca((argc
+ 1) * sizeof(char *));
211 for (i
= 0, p
= cmdline
; i
< argc
; i
++) {
217 /* Find the end of this arg */
218 while(*p
&& !isspace(*p
)) {
223 argv
[i
] = malloc(len
+ 1);
224 strncpy(argv
[i
], start
, len
);
228 * Now skip all whitespace between arguments.
230 while (*p
&& isspace(*p
))
234 * Point __cmdline at "argv[1] ... argv[argc-1]"
243 return spawn_load(argv
[0], argc
, argv
);
246 void pm_env32_run(com32sys_t
*regs
)
250 cmdline
= MK_PTR(regs
->es
, regs
->ebx
.w
[0]);
251 if (create_args_and_load(cmdline
) < 0)
252 printf("Failed to run com32 module\n");