david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Merge branch 'master' of git://git.etherboot.org/scm/gpxe

This commit is contained in:
Holger Lubitz 2007-08-05 19:02:54 +02:00
commit 4f66879653
7 changed files with 111 additions and 56 deletions

View File

@ -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,44 +194,35 @@ 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 start = user_to_phys ( module_image->data, 0 );
* modules to be in ascending order, so we end = user_to_phys ( module_image->data, module_image->len );
* have to support it. for ( insert = 0 ; insert < count ; insert++ ) {
*/ if ( start < modules[insert].mod_start )
start = user_to_phys ( module_image->data, 0 ); break;
end = user_to_phys ( module_image->data,
module_image->len );
for ( insert = 0 ; insert < count ; insert++ ) {
if ( start < modules[insert].mod_start )
break;
}
module = &modules[insert];
memmove ( ( module + 1 ), module,
( ( count - insert ) * sizeof ( *module ) ));
module->mod_start = start;
module->mod_end = end;
cmdline = ( module_image->cmdline ?
module_image->cmdline : "" );
module->string = virt_to_phys ( cmdline );
module->reserved = 0;
/* We promise to page-align modules */
assert ( ( module->mod_start & 0xfff ) == 0 );
} }
module = &modules[insert];
memmove ( ( module + 1 ), module,
( ( count - insert ) * sizeof ( *module ) ) );
module->mod_start = start;
module->mod_end = end;
module->string =
multiboot_add_cmdline ( module_image->cmdline );
module->reserved = 0;
/* We promise to page-align modules */
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 );

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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 */

View File

@ -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;
} }
/** /**

View File

@ -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;
} }

View File

@ -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;