wok-current rev 1001

gpxe: set pxelinux TFTP prefix
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Jul 06 17:25:17 2008 +0000 (2008-07-06)
parents 0129fe2dcb90
children 5367046716ba
files gpxe/stuff/default_boot.u
line diff
     1.1 --- a/gpxe/stuff/default_boot.u	Sun Jul 06 16:51:32 2008 +0200
     1.2 +++ b/gpxe/stuff/default_boot.u	Sun Jul 06 17:25:17 2008 +0000
     1.3 @@ -1,11 +1,38 @@
     1.4 +--- gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
     1.5 ++++ gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
     1.6 +@@ -96,6 +96,8 @@
     1.7 + 	PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
     1.8 + 	PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
     1.9 + 	PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
    1.10 ++	PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * );
    1.11 ++	PXENV_EXIT_t ( * file_api_check ) ( struct s_PXENV_FILE_API_CHECK * );
    1.12 + };
    1.13 + 
    1.14 + /**
    1.15 +@@ -294,6 +296,14 @@
    1.16 + 		pxenv_call.get_file_size = pxenv_get_file_size;
    1.17 + 		param_len = sizeof ( pxenv_any.get_file_size );
    1.18 + 		break;
    1.19 ++	case PXENV_FILE_EXEC:
    1.20 ++		pxenv_call.file_exec = pxenv_file_exec;
    1.21 ++		param_len = sizeof ( pxenv_any.file_exec );
    1.22 ++		break;
    1.23 ++	case PXENV_FILE_API_CHECK:
    1.24 ++		pxenv_call.file_api_check = pxenv_file_api_check;
    1.25 ++		param_len = sizeof ( pxenv_any.file_api_check );
    1.26 ++		break;
    1.27 + 	default:
    1.28 + 		DBG ( "PXENV_UNKNOWN_%hx", opcode );
    1.29 + 		pxenv_call.unknown = pxenv_unknown;
    1.30 +
    1.31  --- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
    1.32  +++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
    1.33 -@@ -441,6 +441,8 @@
    1.34 +@@ -441,6 +441,8 @@ 
    1.35   	/* Calculated lcall to _start with %cs:0000 = image start */
    1.36   	lret
    1.37   
    1.38  +boot_url:
    1.39 -+	.space	128, 0
    1.40 ++	.space	256, 0
    1.41   
    1.42   	.org	PREFIXSIZE
    1.43   /*
    1.44 @@ -17,7 +44,7 @@
    1.45  +	movw	%bx, %es
    1.46  +	movw	$forced_url, %di
    1.47  +	movw	$boot_url, %si
    1.48 -+	movw	$128, %cx
    1.49 ++	movw	$256, %cx
    1.50  +	rep movsb
    1.51  +	
    1.52   	/* Jump to .text16 segment */
    1.53 @@ -26,16 +53,17 @@
    1.54  
    1.55  --- gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
    1.56  +++ gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
    1.57 -@@ -19,6 +19,8 @@
    1.58 +@@ -19,6 +19,9 @@
    1.59   	.section ".prefix"
    1.60   	/* Set up our non-stack segment registers */
    1.61   	jmp	$0x7c0, $1f
    1.62 ++#define PXELOADER_KEEP_UNDI
    1.63  +boot_url:
    1.64 -+	.space	128, 0
    1.65 ++	.space	256, 0
    1.66   1:	movw	%cs, %ax
    1.67   	movw	%ax, %ds
    1.68   	movw	$0x40, %ax		/* BIOS data segment access */
    1.69 -@@ -703,16 +705,22 @@
    1.70 +@@ -703,16 +706,22 @@
    1.71   	/* Set up real-mode stack */
    1.72   	movw	%bx, %ss
    1.73   	movw	$_estack16, %sp
    1.74 @@ -54,56 +82,222 @@
    1.75  +	/* Copy our boot_url structure to the forced_url variable */
    1.76  +	movw	$forced_url, %di
    1.77  +	movw	$boot_url, %si
    1.78 -+	movw	$128, %cx
    1.79 ++	movw	$256, %cx
    1.80  +	rep movsb
    1.81  +	
    1.82   	/* Jump to .text16 segment with %ds pointing to .data16 */
    1.83   	movw	%bx, %ds
    1.84   	pushw	%ax
    1.85  
    1.86 +--- gpxe-0.9.3/src/include/pxe_api.h
    1.87 ++++ gpxe-0.9.3/src/include/pxe_api.h
    1.88 +@@ -1684,6 +1684,54 @@
    1.89 + 
    1.90 + /** @} */ /* pxenv_get_file_size */
    1.91 + 
    1.92 ++/** @defgroup pxenv_file_exec PXENV_FILE_EXEC
    1.93 ++ *
    1.94 ++ * FILE EXEC
    1.95 ++ *
    1.96 ++ * @{
    1.97 ++ */
    1.98 ++
    1.99 ++/** PXE API function code for pxenv_file_exec() */
   1.100 ++#define PXENV_FILE_EXEC			0x00e5
   1.101 ++
   1.102 ++/** Parameter block for pxenv_file_exec() */
   1.103 ++struct s_PXENV_FILE_EXEC {
   1.104 ++	PXENV_STATUS_t Status;		/**< PXE status code */
   1.105 ++	SEGOFF16_t Command;		/**< Command to execute */
   1.106 ++} PACKED;
   1.107 ++
   1.108 ++typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
   1.109 ++
   1.110 ++extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec );
   1.111 ++
   1.112 ++/** @} */ /* pxenv_file_exec */
   1.113 ++
   1.114 ++/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK
   1.115 ++ *
   1.116 ++ * FILE API CHECK
   1.117 ++ *
   1.118 ++ * @{
   1.119 ++ */
   1.120 ++
   1.121 ++/** PXE API function code for pxenv_file_api_check() */
   1.122 ++#define PXENV_FILE_API_CHECK		0x00e6
   1.123 ++
   1.124 ++/** Parameter block for pxenv_file_api_check() */
   1.125 ++struct s_PXENV_FILE_API_CHECK {
   1.126 ++	PXENV_STATUS_t Status;		/**< PXE status code */
   1.127 ++	UINT16_t Size;			/**< Size of structure  */
   1.128 ++	UINT32_t Magic;			/**< Magic number */
   1.129 ++	UINT32_t Provider;		/**< Implementation identifier */
   1.130 ++	UINT32_t APIMask;		/**< Supported API functions */
   1.131 ++	UINT32_t Flags;			/**< Reserved for the future */
   1.132 ++} PACKED;
   1.133 ++
   1.134 ++typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t;
   1.135 ++
   1.136 ++extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check );
   1.137 ++
   1.138 ++/** @} */ /* pxenv_file_api_check */
   1.139 ++
   1.140 + /** @} */ /* pxe_file_api */
   1.141 + 
   1.142 + /** @defgroup pxe_loader_api PXE Loader API
   1.143 +
   1.144 +--- gpxe-0.9.3/src/include/pxe.h
   1.145 ++++ gpxe-0.9.3/src/include/pxe.h
   1.146 +@@ -63,6 +63,8 @@
   1.147 + 	struct s_PXENV_FILE_SELECT		file_select;
   1.148 + 	struct s_PXENV_FILE_READ		file_read;
   1.149 + 	struct s_PXENV_GET_FILE_SIZE		get_file_size;
   1.150 ++	struct s_PXENV_FILE_EXEC		file_exec;
   1.151 ++	struct s_PXENV_FILE_API_CHECK		file_api_check;
   1.152 + };
   1.153 + 
   1.154 + typedef union u_PXENV_ANY PXENV_ANY_t;
   1.155 +
   1.156 +--- gpxe-0.9.3/src/interface/pxe/pxe_file.c
   1.157 ++++ gpxe-0.9.3/src/interface/pxe/pxe_file.c
   1.158 +@@ -31,7 +31,7 @@
   1.159 +  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   1.160 +  */
   1.161 + 
   1.162 +-FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
   1.163 ++FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
   1.164 + 
   1.165 + /**
   1.166 +  * FILE OPEN
   1.167 +@@ -189,3 +189,76 @@
   1.168 + 	get_file_size->Status = PXENV_STATUS_SUCCESS;
   1.169 + 	return PXENV_EXIT_SUCCESS;
   1.170 + }
   1.171 ++
   1.172 ++/**
   1.173 ++ * FILE EXEC
   1.174 ++ *
   1.175 ++ * @v file_exec				Pointer to a struct s_PXENV_FILE_EXEC
   1.176 ++ * @v s_PXENV_FILE_EXEC::Command	Command to execute
   1.177 ++ * @ret #PXENV_EXIT_SUCCESS		Command was executed successfully
   1.178 ++ * @ret #PXENV_EXIT_FAILURE		Command was not executed successfully
   1.179 ++ * @ret s_PXENV_FILE_EXEC::Status	PXE status code
   1.180 ++ *
   1.181 ++ */
   1.182 ++PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
   1.183 ++	userptr_t command;
   1.184 ++	size_t command_len;
   1.185 ++	int rc;
   1.186 ++
   1.187 ++	DBG ( "PXENV_FILE_EXEC" );
   1.188 ++
   1.189 ++	/* Copy name from external program, and exec it */
   1.190 ++	command = real_to_user ( file_exec->Command.segment,
   1.191 ++				 file_exec->Command.offset );
   1.192 ++	command_len = strlen_user ( command, 0 );
   1.193 ++	{
   1.194 ++		char command_string[ command_len + 1 ];
   1.195 ++
   1.196 ++		copy_from_user ( command_string, command, 0,
   1.197 ++				 sizeof ( command_string ) );
   1.198 ++		DBG ( " %s", command_string );
   1.199 ++
   1.200 ++		if ( ( rc = system ( command_string ) ) != 0 ) {
   1.201 ++			file_exec->Status = PXENV_STATUS ( rc );
   1.202 ++			return PXENV_EXIT_FAILURE;
   1.203 ++		}
   1.204 ++	}
   1.205 ++
   1.206 ++	file_exec->Status = PXENV_STATUS_SUCCESS;
   1.207 ++	return PXENV_EXIT_SUCCESS;
   1.208 ++}
   1.209 ++
   1.210 ++/**
   1.211 ++ * FILE API CHECK
   1.212 ++ *
   1.213 ++ * @v file_exec				Pointer to a struct s_PXENV_FILE_API_CHECK
   1.214 ++ * @v s_PXENV_FILE_API_CHECK::Magic     Inbound magic number (0x91d447b2)
   1.215 ++ * @ret #PXENV_EXIT_SUCCESS		Command was executed successfully
   1.216 ++ * @ret #PXENV_EXIT_FAILURE		Command was not executed successfully
   1.217 ++ * @ret s_PXENV_FILE_API_CHECK::Status	PXE status code
   1.218 ++ * @ret s_PXENV_FILE_API_CHECK::Magic	Outbound magic number (0xe9c17b20)
   1.219 ++ * @ret s_PXENV_FILE_API_CHECK::Provider "gPXE" (0x45585067)
   1.220 ++ * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask
   1.221 ++ * @ret s_PXENV_FILE_API_CHECK::Flags	Reserved
   1.222 ++ *
   1.223 ++ */
   1.224 ++PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) {
   1.225 ++	DBG ( "PXENV_FILE_API_CHECK" );
   1.226 ++
   1.227 ++	if ( file_api_check->Magic != 0x91d447b2 ) {
   1.228 ++		file_api_check->Status = PXENV_STATUS_BAD_FUNC;
   1.229 ++		return PXENV_EXIT_FAILURE;
   1.230 ++	} else if ( file_api_check->Size <
   1.231 ++		    sizeof(struct s_PXENV_FILE_API_CHECK) ) {
   1.232 ++		file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
   1.233 ++		return PXENV_EXIT_FAILURE;
   1.234 ++	} else {
   1.235 ++		file_api_check->Status   = PXENV_STATUS_SUCCESS;
   1.236 ++		file_api_check->Size     = sizeof(struct s_PXENV_FILE_API_CHECK);
   1.237 ++		file_api_check->Magic    = 0xe9c17b20;
   1.238 ++		file_api_check->Provider = 0x45585067; /* "gPXE" */
   1.239 ++		file_api_check->APIMask  = 0x0000007f; /* Functions e0-e6 */
   1.240 ++		file_api_check->Flags    = 0;	       /* None defined */
   1.241 ++		return PXENV_EXIT_SUCCESS;
   1.242 ++	}
   1.243 ++}
   1.244 +
   1.245  --- gpxe-0.9.3/src/usr/autoboot.c
   1.246  +++ gpxe-0.9.3/src/usr/autoboot.c
   1.247 -@@ -120,6 +120,11 @@
   1.248 +@@ -120,6 +120,28 @@
   1.249   	return -ENOTSUP;
   1.250   }
   1.251   
   1.252 ++static void set_url ( char buf[], const char url[] ) {
   1.253 ++	int i, d = 0;
   1.254 ++	
   1.255 ++	for (i = 0; url[i] >= ' '; i++) {
   1.256 ++		if (url[i] == '/') d = i;
   1.257 ++		buf[i] = url[i];
   1.258 ++	}
   1.259 ++	buf[i] = 0;
   1.260 ++	if (strstr(buf,"pxelinux")) {
   1.261 ++		struct dhcp_option_block *options = list_entry ( 
   1.262 ++			dhcp_option_blocks.next, typeof ( *options ), list );
   1.263 ++
   1.264 ++		set_dhcp_option( options, 208, "\xF1\x00\x74\x7E", 4 );
   1.265 ++		set_dhcp_option( options, 210, buf, d+1 );
   1.266 ++	}
   1.267 ++}
   1.268 ++
   1.269  +struct _forced_url {
   1.270 -+	char url[128];
   1.271 ++	char url[256];
   1.272  +};
   1.273  +struct _forced_url __data16 ( forced_url );
   1.274  +#define forced_url __use_data16 ( forced_url )
   1.275   /**
   1.276    * Boot from a network device
   1.277    *
   1.278 -@@ -139,15 +144,21 @@
   1.279 - 	if ( ( rc = dhcp ( netdev ) ) != 0 )
   1.280 - 		return rc;
   1.281 - 	route();
   1.282 --
   1.283 -+	
   1.284 - 	/* Try to boot an embedded image if we have one */
   1.285 - 	rc = boot_embedded_image ();
   1.286 - 	if ( rc != ENOENT )
   1.287 - 		return rc;
   1.288 - 
   1.289 -+    /* Try to boot a forced url if we have one */
   1.290 -+    strcpy ( buf, forced_url.url );
   1.291 -+    if ( forced_url.url[0] == 0 ) {
   1.292 -+
   1.293 +@@ -148,6 +170,12 @@
   1.294   	/* Try to download and boot whatever we are given as a filename */
   1.295   	dhcp_snprintf ( buf, sizeof ( buf ),
   1.296   			find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
   1.297 -+    }
   1.298 ++	
   1.299 ++	if ( forced_url.url[0] != 0 ) {
   1.300 ++		/* Try to boot a forced url if we have one */
   1.301 ++		set_url ( buf, forced_url.url );
   1.302 ++	}
   1.303  +    while (1) {
   1.304   	if ( buf[0] ) {
   1.305   		printf ( "Booting from filename \"%s\"\n", buf );
   1.306   		return boot_filename ( buf );
   1.307 -@@ -162,7 +173,8 @@
   1.308 +@@ -162,7 +190,8 @@
   1.309   	}
   1.310   
   1.311   	printf ( "No filename or root path specified\n" );
   1.312  -	return -ENOENT;
   1.313 -+	strcpy ( buf, "http://boot.slitaz.org/gpxe" );
   1.314 ++	set_url ( buf, "http://boot.slitaz.org/gpxe" );
   1.315  +    }
   1.316   }
   1.317