wok annotate gpxe/stuff/default_boot.u @ 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 a28a18adeab4
children 5367046716ba
rev   line source
pascal@1001 1 --- gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
pascal@1001 2 +++ gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
pascal@1001 3 @@ -96,6 +96,8 @@
pascal@1001 4 PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
pascal@1001 5 PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
pascal@1001 6 PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
pascal@1001 7 + PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * );
pascal@1001 8 + PXENV_EXIT_t ( * file_api_check ) ( struct s_PXENV_FILE_API_CHECK * );
pascal@1001 9 };
pascal@1001 10
pascal@1001 11 /**
pascal@1001 12 @@ -294,6 +296,14 @@
pascal@1001 13 pxenv_call.get_file_size = pxenv_get_file_size;
pascal@1001 14 param_len = sizeof ( pxenv_any.get_file_size );
pascal@1001 15 break;
pascal@1001 16 + case PXENV_FILE_EXEC:
pascal@1001 17 + pxenv_call.file_exec = pxenv_file_exec;
pascal@1001 18 + param_len = sizeof ( pxenv_any.file_exec );
pascal@1001 19 + break;
pascal@1001 20 + case PXENV_FILE_API_CHECK:
pascal@1001 21 + pxenv_call.file_api_check = pxenv_file_api_check;
pascal@1001 22 + param_len = sizeof ( pxenv_any.file_api_check );
pascal@1001 23 + break;
pascal@1001 24 default:
pascal@1001 25 DBG ( "PXENV_UNKNOWN_%hx", opcode );
pascal@1001 26 pxenv_call.unknown = pxenv_unknown;
pascal@1001 27
pascal@962 28 --- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
pascal@962 29 +++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
pascal@1001 30 @@ -441,6 +441,8 @@
pascal@962 31 /* Calculated lcall to _start with %cs:0000 = image start */
pascal@962 32 lret
pascal@962 33
pascal@962 34 +boot_url:
pascal@1001 35 + .space 256, 0
pascal@962 36
pascal@962 37 .org PREFIXSIZE
pascal@962 38 /*
pascal@962 39 @@ -453,6 +455,13 @@
pascal@962 40 movw %bx, %ss
pascal@962 41 movw $_estack16, %sp
pascal@962 42
pascal@962 43 + /* Copy our boot_url structure to the forced_url variable */
pascal@962 44 + movw %bx, %es
pascal@962 45 + movw $forced_url, %di
pascal@962 46 + movw $boot_url, %si
pascal@1001 47 + movw $256, %cx
pascal@962 48 + rep movsb
pascal@962 49 +
pascal@962 50 /* Jump to .text16 segment */
pascal@962 51 pushw %ax
pascal@962 52 pushw $1f
pascal@962 53
pascal@962 54 --- gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
pascal@962 55 +++ gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
pascal@1001 56 @@ -19,6 +19,9 @@
pascal@962 57 .section ".prefix"
pascal@962 58 /* Set up our non-stack segment registers */
pascal@962 59 jmp $0x7c0, $1f
pascal@1001 60 +#define PXELOADER_KEEP_UNDI
pascal@962 61 +boot_url:
pascal@1001 62 + .space 256, 0
pascal@962 63 1: movw %cs, %ax
pascal@962 64 movw %ax, %ds
pascal@962 65 movw $0x40, %ax /* BIOS data segment access */
pascal@1001 66 @@ -703,16 +706,22 @@
pascal@962 67 /* Set up real-mode stack */
pascal@962 68 movw %bx, %ss
pascal@962 69 movw $_estack16, %sp
pascal@962 70 -
pascal@962 71 + movw %bx, %es
pascal@962 72 +
pascal@962 73 #ifdef PXELOADER_KEEP_UNDI
pascal@962 74 /* Copy our undi_device structure to the preloaded_undi variable */
pascal@962 75 - movw %bx, %es
pascal@962 76 movw $preloaded_undi, %di
pascal@962 77 movw $undi_device, %si
pascal@962 78 movw $undi_device_size, %cx
pascal@962 79 rep movsb
pascal@962 80 #endif
pascal@962 81
pascal@962 82 + /* Copy our boot_url structure to the forced_url variable */
pascal@962 83 + movw $forced_url, %di
pascal@962 84 + movw $boot_url, %si
pascal@1001 85 + movw $256, %cx
pascal@962 86 + rep movsb
pascal@962 87 +
pascal@962 88 /* Jump to .text16 segment with %ds pointing to .data16 */
pascal@962 89 movw %bx, %ds
pascal@962 90 pushw %ax
pascal@962 91
pascal@1001 92 --- gpxe-0.9.3/src/include/pxe_api.h
pascal@1001 93 +++ gpxe-0.9.3/src/include/pxe_api.h
pascal@1001 94 @@ -1684,6 +1684,54 @@
pascal@1001 95
pascal@1001 96 /** @} */ /* pxenv_get_file_size */
pascal@1001 97
pascal@1001 98 +/** @defgroup pxenv_file_exec PXENV_FILE_EXEC
pascal@1001 99 + *
pascal@1001 100 + * FILE EXEC
pascal@1001 101 + *
pascal@1001 102 + * @{
pascal@1001 103 + */
pascal@1001 104 +
pascal@1001 105 +/** PXE API function code for pxenv_file_exec() */
pascal@1001 106 +#define PXENV_FILE_EXEC 0x00e5
pascal@1001 107 +
pascal@1001 108 +/** Parameter block for pxenv_file_exec() */
pascal@1001 109 +struct s_PXENV_FILE_EXEC {
pascal@1001 110 + PXENV_STATUS_t Status; /**< PXE status code */
pascal@1001 111 + SEGOFF16_t Command; /**< Command to execute */
pascal@1001 112 +} PACKED;
pascal@1001 113 +
pascal@1001 114 +typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
pascal@1001 115 +
pascal@1001 116 +extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec );
pascal@1001 117 +
pascal@1001 118 +/** @} */ /* pxenv_file_exec */
pascal@1001 119 +
pascal@1001 120 +/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK
pascal@1001 121 + *
pascal@1001 122 + * FILE API CHECK
pascal@1001 123 + *
pascal@1001 124 + * @{
pascal@1001 125 + */
pascal@1001 126 +
pascal@1001 127 +/** PXE API function code for pxenv_file_api_check() */
pascal@1001 128 +#define PXENV_FILE_API_CHECK 0x00e6
pascal@1001 129 +
pascal@1001 130 +/** Parameter block for pxenv_file_api_check() */
pascal@1001 131 +struct s_PXENV_FILE_API_CHECK {
pascal@1001 132 + PXENV_STATUS_t Status; /**< PXE status code */
pascal@1001 133 + UINT16_t Size; /**< Size of structure */
pascal@1001 134 + UINT32_t Magic; /**< Magic number */
pascal@1001 135 + UINT32_t Provider; /**< Implementation identifier */
pascal@1001 136 + UINT32_t APIMask; /**< Supported API functions */
pascal@1001 137 + UINT32_t Flags; /**< Reserved for the future */
pascal@1001 138 +} PACKED;
pascal@1001 139 +
pascal@1001 140 +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t;
pascal@1001 141 +
pascal@1001 142 +extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check );
pascal@1001 143 +
pascal@1001 144 +/** @} */ /* pxenv_file_api_check */
pascal@1001 145 +
pascal@1001 146 /** @} */ /* pxe_file_api */
pascal@1001 147
pascal@1001 148 /** @defgroup pxe_loader_api PXE Loader API
pascal@1001 149
pascal@1001 150 --- gpxe-0.9.3/src/include/pxe.h
pascal@1001 151 +++ gpxe-0.9.3/src/include/pxe.h
pascal@1001 152 @@ -63,6 +63,8 @@
pascal@1001 153 struct s_PXENV_FILE_SELECT file_select;
pascal@1001 154 struct s_PXENV_FILE_READ file_read;
pascal@1001 155 struct s_PXENV_GET_FILE_SIZE get_file_size;
pascal@1001 156 + struct s_PXENV_FILE_EXEC file_exec;
pascal@1001 157 + struct s_PXENV_FILE_API_CHECK file_api_check;
pascal@1001 158 };
pascal@1001 159
pascal@1001 160 typedef union u_PXENV_ANY PXENV_ANY_t;
pascal@1001 161
pascal@1001 162 --- gpxe-0.9.3/src/interface/pxe/pxe_file.c
pascal@1001 163 +++ gpxe-0.9.3/src/interface/pxe/pxe_file.c
pascal@1001 164 @@ -31,7 +31,7 @@
pascal@1001 165 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
pascal@1001 166 */
pascal@1001 167
pascal@1001 168 -FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
pascal@1001 169 +FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
pascal@1001 170
pascal@1001 171 /**
pascal@1001 172 * FILE OPEN
pascal@1001 173 @@ -189,3 +189,76 @@
pascal@1001 174 get_file_size->Status = PXENV_STATUS_SUCCESS;
pascal@1001 175 return PXENV_EXIT_SUCCESS;
pascal@1001 176 }
pascal@1001 177 +
pascal@1001 178 +/**
pascal@1001 179 + * FILE EXEC
pascal@1001 180 + *
pascal@1001 181 + * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC
pascal@1001 182 + * @v s_PXENV_FILE_EXEC::Command Command to execute
pascal@1001 183 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
pascal@1001 184 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
pascal@1001 185 + * @ret s_PXENV_FILE_EXEC::Status PXE status code
pascal@1001 186 + *
pascal@1001 187 + */
pascal@1001 188 +PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
pascal@1001 189 + userptr_t command;
pascal@1001 190 + size_t command_len;
pascal@1001 191 + int rc;
pascal@1001 192 +
pascal@1001 193 + DBG ( "PXENV_FILE_EXEC" );
pascal@1001 194 +
pascal@1001 195 + /* Copy name from external program, and exec it */
pascal@1001 196 + command = real_to_user ( file_exec->Command.segment,
pascal@1001 197 + file_exec->Command.offset );
pascal@1001 198 + command_len = strlen_user ( command, 0 );
pascal@1001 199 + {
pascal@1001 200 + char command_string[ command_len + 1 ];
pascal@1001 201 +
pascal@1001 202 + copy_from_user ( command_string, command, 0,
pascal@1001 203 + sizeof ( command_string ) );
pascal@1001 204 + DBG ( " %s", command_string );
pascal@1001 205 +
pascal@1001 206 + if ( ( rc = system ( command_string ) ) != 0 ) {
pascal@1001 207 + file_exec->Status = PXENV_STATUS ( rc );
pascal@1001 208 + return PXENV_EXIT_FAILURE;
pascal@1001 209 + }
pascal@1001 210 + }
pascal@1001 211 +
pascal@1001 212 + file_exec->Status = PXENV_STATUS_SUCCESS;
pascal@1001 213 + return PXENV_EXIT_SUCCESS;
pascal@1001 214 +}
pascal@1001 215 +
pascal@1001 216 +/**
pascal@1001 217 + * FILE API CHECK
pascal@1001 218 + *
pascal@1001 219 + * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK
pascal@1001 220 + * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2)
pascal@1001 221 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
pascal@1001 222 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
pascal@1001 223 + * @ret s_PXENV_FILE_API_CHECK::Status PXE status code
pascal@1001 224 + * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20)
pascal@1001 225 + * @ret s_PXENV_FILE_API_CHECK::Provider "gPXE" (0x45585067)
pascal@1001 226 + * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask
pascal@1001 227 + * @ret s_PXENV_FILE_API_CHECK::Flags Reserved
pascal@1001 228 + *
pascal@1001 229 + */
pascal@1001 230 +PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) {
pascal@1001 231 + DBG ( "PXENV_FILE_API_CHECK" );
pascal@1001 232 +
pascal@1001 233 + if ( file_api_check->Magic != 0x91d447b2 ) {
pascal@1001 234 + file_api_check->Status = PXENV_STATUS_BAD_FUNC;
pascal@1001 235 + return PXENV_EXIT_FAILURE;
pascal@1001 236 + } else if ( file_api_check->Size <
pascal@1001 237 + sizeof(struct s_PXENV_FILE_API_CHECK) ) {
pascal@1001 238 + file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
pascal@1001 239 + return PXENV_EXIT_FAILURE;
pascal@1001 240 + } else {
pascal@1001 241 + file_api_check->Status = PXENV_STATUS_SUCCESS;
pascal@1001 242 + file_api_check->Size = sizeof(struct s_PXENV_FILE_API_CHECK);
pascal@1001 243 + file_api_check->Magic = 0xe9c17b20;
pascal@1001 244 + file_api_check->Provider = 0x45585067; /* "gPXE" */
pascal@1001 245 + file_api_check->APIMask = 0x0000007f; /* Functions e0-e6 */
pascal@1001 246 + file_api_check->Flags = 0; /* None defined */
pascal@1001 247 + return PXENV_EXIT_SUCCESS;
pascal@1001 248 + }
pascal@1001 249 +}
pascal@1001 250
pascal@955 251 --- gpxe-0.9.3/src/usr/autoboot.c
pascal@955 252 +++ gpxe-0.9.3/src/usr/autoboot.c
pascal@1001 253 @@ -120,6 +120,28 @@
pascal@962 254 return -ENOTSUP;
pascal@962 255 }
pascal@962 256
pascal@1001 257 +static void set_url ( char buf[], const char url[] ) {
pascal@1001 258 + int i, d = 0;
pascal@1001 259 +
pascal@1001 260 + for (i = 0; url[i] >= ' '; i++) {
pascal@1001 261 + if (url[i] == '/') d = i;
pascal@1001 262 + buf[i] = url[i];
pascal@1001 263 + }
pascal@1001 264 + buf[i] = 0;
pascal@1001 265 + if (strstr(buf,"pxelinux")) {
pascal@1001 266 + struct dhcp_option_block *options = list_entry (
pascal@1001 267 + dhcp_option_blocks.next, typeof ( *options ), list );
pascal@1001 268 +
pascal@1001 269 + set_dhcp_option( options, 208, "\xF1\x00\x74\x7E", 4 );
pascal@1001 270 + set_dhcp_option( options, 210, buf, d+1 );
pascal@1001 271 + }
pascal@1001 272 +}
pascal@1001 273 +
pascal@962 274 +struct _forced_url {
pascal@1001 275 + char url[256];
pascal@962 276 +};
pascal@962 277 +struct _forced_url __data16 ( forced_url );
pascal@962 278 +#define forced_url __use_data16 ( forced_url )
pascal@962 279 /**
pascal@962 280 * Boot from a network device
pascal@962 281 *
pascal@1001 282 @@ -148,6 +170,12 @@
pascal@962 283 /* Try to download and boot whatever we are given as a filename */
pascal@962 284 dhcp_snprintf ( buf, sizeof ( buf ),
pascal@955 285 find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
pascal@1001 286 +
pascal@1001 287 + if ( forced_url.url[0] != 0 ) {
pascal@1001 288 + /* Try to boot a forced url if we have one */
pascal@1001 289 + set_url ( buf, forced_url.url );
pascal@1001 290 + }
pascal@962 291 + while (1) {
pascal@955 292 if ( buf[0] ) {
pascal@962 293 printf ( "Booting from filename \"%s\"\n", buf );
pascal@962 294 return boot_filename ( buf );
pascal@1001 295 @@ -162,7 +190,8 @@
pascal@962 296 }
pascal@962 297
pascal@955 298 printf ( "No filename or root path specified\n" );
pascal@955 299 - return -ENOENT;
pascal@1001 300 + set_url ( buf, "http://boot.slitaz.org/gpxe" );
pascal@962 301 + }
pascal@955 302 }
pascal@962 303
pascal@962 304 /**