mirror of https://github.com/ipxe/ipxe.git
Merge branch 'master' of git://git.etherboot.org/scm/gpxe
commit
4f66879653
|
@ -23,6 +23,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <realmode.h>
|
#include <realmode.h>
|
||||||
|
@ -51,6 +52,16 @@ struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT );
|
||||||
*/
|
*/
|
||||||
#define MAX_MODULES 8
|
#define MAX_MODULES 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum combined length of command lines
|
||||||
|
*
|
||||||
|
* Again; sorry. Some broken OSes zero out any non-base memory that
|
||||||
|
* isn't part of the loaded module set, so we can't just use
|
||||||
|
* virt_to_phys(cmdline) to point to the command lines, even though
|
||||||
|
* this would comply with the Multiboot spec.
|
||||||
|
*/
|
||||||
|
#define MB_MAX_CMDLINE 512
|
||||||
|
|
||||||
/** Multiboot flags that we support */
|
/** Multiboot flags that we support */
|
||||||
#define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
|
#define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
|
||||||
MB_FLAG_VIDMODE | MB_FLAG_RAW )
|
MB_FLAG_VIDMODE | MB_FLAG_RAW )
|
||||||
|
@ -77,6 +88,13 @@ struct multiboot_header_info {
|
||||||
size_t offset;
|
size_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Multiboot module command lines */
|
||||||
|
static char __bss16_array ( mb_cmdlines, [MB_MAX_CMDLINE] );
|
||||||
|
#define mb_cmdlines __use_data16 ( mb_cmdlines )
|
||||||
|
|
||||||
|
/** Offset within module command lines */
|
||||||
|
static unsigned int mb_cmdline_offset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build multiboot memory map
|
* Build multiboot memory map
|
||||||
*
|
*
|
||||||
|
@ -118,6 +136,32 @@ static void multiboot_build_memmap ( struct image *image,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add command line in base memory
|
||||||
|
*
|
||||||
|
* @v cmdline Command line
|
||||||
|
* @ret physaddr Physical address of command line
|
||||||
|
*/
|
||||||
|
physaddr_t multiboot_add_cmdline ( const char *cmdline ) {
|
||||||
|
char *mb_cmdline;
|
||||||
|
|
||||||
|
if ( ! cmdline )
|
||||||
|
cmdline = "";
|
||||||
|
|
||||||
|
/* Copy command line to base memory buffer */
|
||||||
|
mb_cmdline = ( mb_cmdlines + mb_cmdline_offset );
|
||||||
|
mb_cmdline_offset +=
|
||||||
|
( snprintf ( mb_cmdline,
|
||||||
|
( sizeof ( mb_cmdlines ) - mb_cmdline_offset ),
|
||||||
|
"%s", cmdline ) + 1 );
|
||||||
|
|
||||||
|
/* Truncate to terminating NUL in buffer if necessary */
|
||||||
|
if ( mb_cmdline_offset > sizeof ( mb_cmdlines ) )
|
||||||
|
mb_cmdline_offset = ( sizeof ( mb_cmdlines ) - 1 );
|
||||||
|
|
||||||
|
return virt_to_phys ( mb_cmdline );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build multiboot module list
|
* Build multiboot module list
|
||||||
*
|
*
|
||||||
|
@ -135,7 +179,6 @@ multiboot_build_module_list ( struct image *image,
|
||||||
unsigned int insert;
|
unsigned int insert;
|
||||||
physaddr_t start;
|
physaddr_t start;
|
||||||
physaddr_t end;
|
physaddr_t end;
|
||||||
char *cmdline;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Add each image as a multiboot module */
|
/* Add each image as a multiboot module */
|
||||||
|
@ -151,16 +194,11 @@ multiboot_build_module_list ( struct image *image,
|
||||||
if ( module_image == image )
|
if ( module_image == image )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If we don't have a data structure to populate, just count */
|
/* At least some OSes expect the multiboot modules to
|
||||||
if ( modules ) {
|
* be in ascending order, so we have to support it.
|
||||||
|
|
||||||
/* At least some OSes expect the multiboot
|
|
||||||
* modules to be in ascending order, so we
|
|
||||||
* have to support it.
|
|
||||||
*/
|
*/
|
||||||
start = user_to_phys ( module_image->data, 0 );
|
start = user_to_phys ( module_image->data, 0 );
|
||||||
end = user_to_phys ( module_image->data,
|
end = user_to_phys ( module_image->data, module_image->len );
|
||||||
module_image->len );
|
|
||||||
for ( insert = 0 ; insert < count ; insert++ ) {
|
for ( insert = 0 ; insert < count ; insert++ ) {
|
||||||
if ( start < modules[insert].mod_start )
|
if ( start < modules[insert].mod_start )
|
||||||
break;
|
break;
|
||||||
|
@ -170,26 +208,22 @@ multiboot_build_module_list ( struct image *image,
|
||||||
( ( count - insert ) * sizeof ( *module ) ) );
|
( ( count - insert ) * sizeof ( *module ) ) );
|
||||||
module->mod_start = start;
|
module->mod_start = start;
|
||||||
module->mod_end = end;
|
module->mod_end = end;
|
||||||
cmdline = ( module_image->cmdline ?
|
module->string =
|
||||||
module_image->cmdline : "" );
|
multiboot_add_cmdline ( module_image->cmdline );
|
||||||
module->string = virt_to_phys ( cmdline );
|
|
||||||
module->reserved = 0;
|
module->reserved = 0;
|
||||||
|
|
||||||
/* We promise to page-align modules */
|
/* We promise to page-align modules */
|
||||||
assert ( ( module->mod_start & 0xfff ) == 0 );
|
assert ( ( module->mod_start & 0xfff ) == 0 );
|
||||||
}
|
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump module configuration */
|
/* Dump module configuration */
|
||||||
if ( modules ) {
|
|
||||||
for ( i = 0 ; i < count ; i++ ) {
|
for ( i = 0 ; i < count ; i++ ) {
|
||||||
DBGC ( image, "MULTIBOOT %p module %d is [%lx,%lx)\n",
|
DBGC ( image, "MULTIBOOT %p module %d is [%lx,%lx)\n",
|
||||||
image, i, modules[i].mod_start,
|
image, i, modules[i].mod_start,
|
||||||
modules[i].mod_end );
|
modules[i].mod_end );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +259,6 @@ static struct multiboot_module __bss16_array ( mbmodules, [MAX_MODULES] );
|
||||||
*/
|
*/
|
||||||
static int multiboot_exec ( struct image *image ) {
|
static int multiboot_exec ( struct image *image ) {
|
||||||
physaddr_t entry = image->priv.phys;
|
physaddr_t entry = image->priv.phys;
|
||||||
char *cmdline;
|
|
||||||
|
|
||||||
/* Populate multiboot information structure */
|
/* Populate multiboot information structure */
|
||||||
memset ( &mbinfo, 0, sizeof ( mbinfo ) );
|
memset ( &mbinfo, 0, sizeof ( mbinfo ) );
|
||||||
|
@ -233,8 +266,8 @@ static int multiboot_exec ( struct image *image ) {
|
||||||
MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
|
MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
|
||||||
multiboot_build_memmap ( image, &mbinfo, mbmemmap,
|
multiboot_build_memmap ( image, &mbinfo, mbmemmap,
|
||||||
( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
|
( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
|
||||||
cmdline = ( image->cmdline ? image->cmdline : "" );
|
mb_cmdline_offset = 0;
|
||||||
mbinfo.cmdline = virt_to_phys ( cmdline );
|
mbinfo.cmdline = multiboot_add_cmdline ( image->cmdline );
|
||||||
mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
|
mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
|
||||||
( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
|
( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
|
||||||
mbinfo.mods_addr = virt_to_phys ( mbmodules );
|
mbinfo.mods_addr = virt_to_phys ( mbmodules );
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <gpxe/process.h>
|
#include <gpxe/process.h>
|
||||||
#include <console.h>
|
#include <console.h>
|
||||||
|
@ -54,11 +56,14 @@ struct job_interface monojob = {
|
||||||
/**
|
/**
|
||||||
* Wait for single foreground job to complete
|
* Wait for single foreground job to complete
|
||||||
*
|
*
|
||||||
|
* @v string Job description to display
|
||||||
* @ret rc Job final status code
|
* @ret rc Job final status code
|
||||||
*/
|
*/
|
||||||
int monojob_wait ( void ) {
|
int monojob_wait ( const char *string ) {
|
||||||
int key;
|
int key;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
printf ( "%s... ", string );
|
||||||
monojob_rc = -EINPROGRESS;
|
monojob_rc = -EINPROGRESS;
|
||||||
while ( monojob_rc == -EINPROGRESS ) {
|
while ( monojob_rc == -EINPROGRESS ) {
|
||||||
step();
|
step();
|
||||||
|
@ -67,12 +72,20 @@ int monojob_wait ( void ) {
|
||||||
switch ( key ) {
|
switch ( key ) {
|
||||||
case CTRL_C:
|
case CTRL_C:
|
||||||
job_kill ( &monojob );
|
job_kill ( &monojob );
|
||||||
return -ECANCELED;
|
rc = -ECANCELED;
|
||||||
break;
|
goto done;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return monojob_rc;
|
rc = monojob_rc;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if ( rc ) {
|
||||||
|
printf ( "%s\n", strerror ( rc ) );
|
||||||
|
} else {
|
||||||
|
printf ( "ok\n" );
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,12 +62,22 @@ struct command exit_command __command = {
|
||||||
/** "help" command body */
|
/** "help" command body */
|
||||||
static int help_exec ( int argc __unused, char **argv __unused ) {
|
static int help_exec ( int argc __unused, char **argv __unused ) {
|
||||||
struct command *command;
|
struct command *command;
|
||||||
|
unsigned int hpos = 0;
|
||||||
|
|
||||||
printf ( "\nAvailable commands:\n\n" );
|
printf ( "\nAvailable commands:\n\n" );
|
||||||
for ( command = commands ; command < commands_end ; command++ ) {
|
for ( command = commands ; command < commands_end ; command++ ) {
|
||||||
printf ( " %s\n", command->name );
|
hpos += printf ( " %s", command->name );
|
||||||
|
if ( hpos > ( 16 * 4 ) ) {
|
||||||
|
printf ( "\n" );
|
||||||
|
hpos = 0;
|
||||||
|
} else {
|
||||||
|
while ( hpos % 16 ) {
|
||||||
|
printf ( " " );
|
||||||
|
hpos++;
|
||||||
}
|
}
|
||||||
printf ( "\nType \"<command> --help\" for further information\n\n" );
|
}
|
||||||
|
}
|
||||||
|
printf ( "\n\nType \"<command> --help\" for further information\n\n" );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
struct job_interface;
|
struct job_interface;
|
||||||
|
|
||||||
extern struct job_interface monojob;
|
extern struct job_interface monojob;
|
||||||
extern int monojob_wait ( void );
|
extern int monojob_wait ( const char *string );
|
||||||
|
|
||||||
#endif /* _GPXE_MONOJOB_H */
|
#endif /* _GPXE_MONOJOB_H */
|
||||||
|
|
|
@ -61,15 +61,20 @@ static int boot_filename ( const char *filename ) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
if ( ( rc = imgfetch ( image, filename,
|
if ( ( rc = imgfetch ( image, filename,
|
||||||
register_and_autoexec_image ) ) != 0 ) {
|
register_and_autoload_image ) ) != 0 ) {
|
||||||
|
printf ( "Could not load %s: %s\n",
|
||||||
|
filename, strerror ( rc ) );
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ( ( rc = imgexec ( image ) ) != 0 ) {
|
||||||
printf ( "Could not boot %s: %s\n",
|
printf ( "Could not boot %s: %s\n",
|
||||||
filename, strerror ( rc ) );
|
filename, strerror ( rc ) );
|
||||||
image_put ( image );
|
goto done;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
image_put ( image );
|
image_put ( image );
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,15 +56,9 @@ int dhcp ( struct net_device *netdev ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform DHCP */
|
/* Perform DHCP */
|
||||||
printf ( "DHCP (%s %s)...", netdev->name, netdev_hwaddr ( netdev ) );
|
printf ( "DHCP (%s %s)", netdev->name, netdev_hwaddr ( netdev ) );
|
||||||
if ( ( rc = start_dhcp ( &monojob, netdev, dhcp_success ) ) == 0 )
|
if ( ( rc = start_dhcp ( &monojob, netdev, dhcp_success ) ) == 0 )
|
||||||
rc = monojob_wait();
|
rc = monojob_wait ( "" );
|
||||||
|
|
||||||
if ( rc == 0 ) {
|
|
||||||
printf ( "done\n" );
|
|
||||||
} else {
|
|
||||||
printf ( "failed (%s)\n", strerror ( rc ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ int imgfetch ( struct image *image, const char *uri_string,
|
||||||
|
|
||||||
if ( ( rc = create_downloader ( &monojob, image, image_register,
|
if ( ( rc = create_downloader ( &monojob, image, image_register,
|
||||||
LOCATION_URI, uri ) ) == 0 )
|
LOCATION_URI, uri ) ) == 0 )
|
||||||
rc = monojob_wait();
|
rc = monojob_wait ( uri_string );
|
||||||
|
|
||||||
uri_put ( uri );
|
uri_put ( uri );
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in New Issue