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 #define LDLINUX "ldlinux.c32"
27 extern char __dynstr_start
[];
28 extern char __dynstr_len
[], __dynsym_len
[];
29 extern char __dynsym_start
[];
30 extern char __got_start
[];
31 extern Elf32_Dyn __dynamic_start
[];
32 extern Elf32_Word __gnu_hash_start
[];
34 struct elf_module core_module
= {
37 .required
= LIST_HEAD_INIT((core_module
.required
)),
38 .dependants
= LIST_HEAD_INIT((core_module
.dependants
)),
39 .list
= LIST_HEAD_INIT((core_module
.list
)),
40 .module_addr
= (void *)0x0,
41 .base_addr
= (Elf32_Addr
) 0x0,
42 .ghash_table
= __gnu_hash_start
,
43 .str_table
= __dynstr_start
,
44 .sym_table
= __dynsym_start
,
46 .dyn_table
= __dynamic_start
,
47 .strtable_size
= (size_t) __dynstr_len
,
48 .syment_size
= sizeof(Elf32_Sym
),
49 .symtable_size
= (size_t) __dynsym_len
53 * Initializes the module subsystem by taking the core module
54 * (preinitialized shallow module) and placing it on top of the
57 void init_module_subsystem(struct elf_module
*module
)
59 list_add(&module
->list
, &modules_head
);
62 __export
int start_ldlinux(char **argv
)
67 rv
= spawn_load(LDLINUX
, 1, argv
);
70 * If a COM32 module calls execute() we may need to
71 * unload all the modules loaded since ldlinux.c32,
72 * and restart initialisation. This is especially
73 * important for config files.
75 * But before we do that, try our best to make sure
76 * that spawn_load() is gonna succeed, e.g. that we
77 * can find LDLINUX it in PATH.
79 struct elf_module
*ldlinux
;
82 f
= findpath(LDLINUX
);
87 ldlinux
= unload_modules_since(LDLINUX
);
90 * Finally unload LDLINUX.
92 * We'll reload it when we jump to 'again' which will
93 * cause all the initialsation steps to be executed
96 module_unload(ldlinux
);
103 /* note to self: do _*NOT*_ use static key word on this function */
104 void load_env32(com32sys_t
* regs __unused
)
106 struct file_info
*fp
;
108 char *argv
[] = { LDLINUX
, NULL
};
109 char realname
[FILENAME_MAX
];
111 static const char *search_directories
[] = {
120 static const char *filenames
[] = {
125 dprintf("Starting 32 bit elf module subsystem...\n");
127 PATH
= malloc(strlen(CurrentDirName
) + 1);
129 printf("Couldn't allocate memory for PATH\n");
133 strcpy(PATH
, CurrentDirName
);
135 init_module_subsystem(&core_module
);
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.
146 fd
= opendev(&__file_dev
, NULL
, O_RDONLY
);
150 fp
= &__file_info
[fd
];
152 if (!search_dirs(&fp
->i
.fd
, search_directories
, filenames
, realname
)) {
153 char path
[FILENAME_MAX
];
156 * search_dirs() sets the current working directory if
157 * it successfully opens the file. Set PATH to the
158 * directory in which we found ldlinux.c32.
160 if (!core_getcwd(path
, sizeof(path
)))
163 PATH
= malloc(strlen(path
) + 1);
165 printf("Couldn't allocate memory for PATH\n");
175 writestr("\nFailed to load ldlinux.c32");
178 __export
int create_args_and_load(char *cmdline
)
187 for (argc
= 0, p
= cmdline
; *p
; argc
++) {
188 /* Find the end of this arg */
189 while(*p
&& !isspace(*p
))
193 * Now skip all whitespace between arguments.
195 while (*p
&& isspace(*p
))
200 * Generate a copy of argv on the stack as this is
201 * traditionally where process arguments go.
203 * argv[0] must be the command name. Remember to allocate
204 * space for the sentinel NULL.
206 argv
= alloca((argc
+ 1) * sizeof(char *));
208 for (i
= 0, p
= cmdline
; i
< argc
; i
++) {
214 /* Find the end of this arg */
215 while(*p
&& !isspace(*p
)) {
220 argv
[i
] = malloc(len
+ 1);
221 strncpy(argv
[i
], start
, len
);
225 * Now skip all whitespace between arguments.
227 while (*p
&& isspace(*p
))
234 return spawn_load(argv
[0], argc
, argv
);
237 void pm_env32_run(com32sys_t
*regs
)
241 cmdline
= MK_PTR(regs
->es
, regs
->ebx
.w
[0]);
242 if (create_args_and_load(cmdline
) < 0)
243 printf("Failed to run com32 module\n");