|
@@ -24,6 +24,9 @@ FILE_LICENCE ( GPL2_OR_LATER )
|
24
|
24
|
/* Image compression enabled */
|
25
|
25
|
#define COMPRESS 1
|
26
|
26
|
|
|
27
|
+/* Protected mode flag */
|
|
28
|
+#define CR0_PE 1
|
|
29
|
+
|
27
|
30
|
/*****************************************************************************
|
28
|
31
|
* Utility function: print character (with LF -> LF,CR translation)
|
29
|
32
|
*
|
|
@@ -229,41 +232,153 @@ print_kill_line:
|
229
|
232
|
* None
|
230
|
233
|
****************************************************************************
|
231
|
234
|
*/
|
232
|
|
-#if ! COMPRESS
|
233
|
235
|
.section ".prefix.lib", "awx", @progbits
|
234
|
236
|
.code16
|
235
|
237
|
copy_bytes:
|
236
|
|
- pushl %ecx
|
|
238
|
+ pushl %ecx
|
237
|
239
|
rep addr32 movsb
|
238
|
|
- popl %ecx
|
|
240
|
+ popl %ecx
|
239
|
241
|
ret
|
240
|
|
- .size copy_bytes, . - copy_bytes
|
241
|
|
-#endif /* COMPRESS */
|
|
242
|
+ .size copy_bytes, . - copy_bytes
|
242
|
243
|
|
243
|
244
|
/****************************************************************************
|
244
|
|
- * install_block
|
|
245
|
+ * zero_bytes
|
245
|
246
|
*
|
246
|
|
- * Install block to specified address
|
|
247
|
+ * Zero bytes
|
247
|
248
|
*
|
248
|
249
|
* Parameters:
|
249
|
|
- * %esi : source physical address (must be a multiple of 16)
|
250
|
|
- * %edi : destination physical address (must be a multiple of 16)
|
251
|
|
- * %ecx : length of (decompressed) data
|
252
|
|
- * %edx : total length of block (including any uninitialised data portion)
|
|
250
|
+ * %ds:esi : source address
|
|
251
|
+ * %es:edi : destination address
|
|
252
|
+ * %ecx : length
|
253
|
253
|
* Returns:
|
254
|
|
- * %esi : next source physical address (will be a multiple of 16)
|
255
|
|
- * %edi : next destination physical address (will be a multiple of 16)
|
|
254
|
+ * %ds:esi : next source address
|
|
255
|
+ * %es:edi : next destination address
|
256
|
256
|
* Corrupts:
|
257
|
|
- * none
|
|
257
|
+ * None
|
258
|
258
|
****************************************************************************
|
259
|
259
|
*/
|
260
|
260
|
.section ".prefix.lib", "awx", @progbits
|
261
|
261
|
.code16
|
262
|
|
-install_block:
|
|
262
|
+zero_bytes:
|
|
263
|
+ pushl %ecx
|
|
264
|
+ pushw %ax
|
|
265
|
+ xorw %ax, %ax
|
|
266
|
+ rep addr32 stosb
|
|
267
|
+ popw %ax
|
|
268
|
+ popl %ecx
|
|
269
|
+ ret
|
|
270
|
+ .size zero_bytes, . - zero_bytes
|
|
271
|
+
|
|
272
|
+/****************************************************************************
|
|
273
|
+ * process_bytes
|
|
274
|
+ *
|
|
275
|
+ * Call memcpy()-like function
|
|
276
|
+ *
|
|
277
|
+ * Parameters:
|
|
278
|
+ * %esi : source physical address
|
|
279
|
+ * %edi : destination physical address
|
|
280
|
+ * %ecx : length
|
|
281
|
+ * %bx : memcpy()-like function to call, passing parameters:
|
|
282
|
+ * %ds:esi : source address
|
|
283
|
+ * %es:edi : destination address
|
|
284
|
+ * %ecx : length
|
|
285
|
+ * and returning:
|
|
286
|
+ * %ds:esi : next source address
|
|
287
|
+ * %es:edi : next destination address
|
|
288
|
+ * Returns:
|
|
289
|
+ * %esi : next source physical address
|
|
290
|
+ * %edi : next destination physical address
|
|
291
|
+ * Corrupts:
|
|
292
|
+ * None
|
|
293
|
+ ****************************************************************************
|
|
294
|
+ */
|
|
295
|
+ .section ".prefix.lib", "awx", @progbits
|
|
296
|
+ .code16
|
|
297
|
+process_bytes:
|
|
298
|
+
|
|
299
|
+#ifndef KEEP_IT_REAL
|
|
300
|
+
|
263
|
301
|
/* Preserve registers */
|
|
302
|
+ pushfw
|
|
303
|
+ pushl %eax
|
|
304
|
+ pushl %ebp
|
|
305
|
+
|
|
306
|
+ /* Construct GDT on stack (since .prefix may not be writable) */
|
|
307
|
+ .equ PM_DS, 0x18 /* Flat data segment */
|
|
308
|
+ pushl $0x008f9300
|
|
309
|
+ pushl $0x0000ffff
|
|
310
|
+ .equ PM_SS, 0x10 /* Stack segment based at %ss:0000 */
|
|
311
|
+ pushl $0x008f0930
|
|
312
|
+ pushw %ss
|
|
313
|
+ pushw $0xffff
|
|
314
|
+ .equ PM_CS, 0x08 /* Code segment based at %cs:0000 */
|
|
315
|
+ pushl $0x008f09b0
|
|
316
|
+ pushw %cs
|
|
317
|
+ pushw $0xffff
|
|
318
|
+ pushl $0 /* Base and length */
|
|
319
|
+ pushw %ss
|
|
320
|
+ pushw $0x1f
|
|
321
|
+ movzwl %sp, %ebp
|
|
322
|
+ shll $4, 0x02(%bp)
|
|
323
|
+ addl %ebp, 0x02(%bp)
|
|
324
|
+ shll $4, 0x0a(%bp)
|
|
325
|
+ shll $4, 0x12(%bp)
|
|
326
|
+ subw $8, %sp
|
|
327
|
+ sgdt -8(%bp)
|
|
328
|
+
|
|
329
|
+ /* Switch to protected mode */
|
|
330
|
+ pushw %gs
|
|
331
|
+ pushw %fs
|
|
332
|
+ pushw %es
|
|
333
|
+ pushw %ds
|
|
334
|
+ pushw %ss
|
|
335
|
+ pushw %cs
|
|
336
|
+ pushw $2f
|
|
337
|
+ cli
|
|
338
|
+ data32 lgdt (%bp)
|
|
339
|
+ movl %cr0, %eax
|
|
340
|
+ orb $CR0_PE, %al
|
|
341
|
+ movl %eax, %cr0
|
|
342
|
+ ljmp $PM_CS, $1f
|
|
343
|
+1: movw $PM_SS, %ax
|
|
344
|
+ movw %ax, %ss
|
|
345
|
+ movw $PM_DS, %ax
|
|
346
|
+ movw %ax, %ds
|
|
347
|
+ movw %ax, %es
|
|
348
|
+ movw %ax, %fs
|
|
349
|
+ movw %ax, %gs
|
|
350
|
+
|
|
351
|
+ /* Call memcpy()-like function */
|
|
352
|
+ call *%bx
|
|
353
|
+
|
|
354
|
+ /* Return to (flat) real mode */
|
|
355
|
+ movl %cr0, %eax
|
|
356
|
+ andb $0!CR0_PE, %al
|
|
357
|
+ movl %eax, %cr0
|
|
358
|
+ lret
|
|
359
|
+2: /* lret will ljmp to here */
|
|
360
|
+ popw %ss
|
|
361
|
+ popw %ds
|
|
362
|
+ popw %es
|
|
363
|
+ popw %fs
|
|
364
|
+ popw %gs
|
|
365
|
+
|
|
366
|
+ /* Restore GDT */
|
|
367
|
+ data32 lgdt -8(%bp)
|
|
368
|
+ addw $( 8 /* saved GDT */ + ( PM_DS + 8 ) /* GDT on stack */ ), %sp
|
|
369
|
+
|
|
370
|
+ /* Restore registers and return */
|
|
371
|
+ popl %ebp
|
|
372
|
+ popl %eax
|
|
373
|
+ popfw
|
|
374
|
+ ret
|
|
375
|
+
|
|
376
|
+#else /* KEEP_IT_REAL */
|
|
377
|
+
|
|
378
|
+ /* Preserve registers */
|
|
379
|
+ pushl %eax
|
264
|
380
|
pushw %ds
|
265
|
381
|
pushw %es
|
266
|
|
- pushl %ecx
|
267
|
382
|
|
268
|
383
|
/* Convert %esi and %edi to %ds:esi and %es:edi */
|
269
|
384
|
shrl $4, %esi
|
|
@@ -275,21 +390,66 @@ install_block:
|
275
|
390
|
xorw %di, %di
|
276
|
391
|
shll $4, %edi
|
277
|
392
|
|
|
393
|
+ /* Call memcpy()-like function */
|
|
394
|
+ call *%bx
|
|
395
|
+
|
|
396
|
+ /* Convert %ds:esi and %es:edi back to physical addresses */
|
|
397
|
+ xorl %eax, %eax
|
|
398
|
+ movw %ds, %cx
|
|
399
|
+ shll $4, %eax
|
|
400
|
+ addl %eax, %esi
|
|
401
|
+ xorl %eax, %eax
|
|
402
|
+ movw %es, %cx
|
|
403
|
+ shll $4, %eax
|
|
404
|
+ addl %eax, %edi
|
|
405
|
+
|
|
406
|
+ /* Restore registers and return */
|
|
407
|
+ popw %es
|
|
408
|
+ popw %ds
|
|
409
|
+ popl %eax
|
|
410
|
+ ret
|
|
411
|
+
|
|
412
|
+#endif /* KEEP_IT_REAL */
|
|
413
|
+
|
|
414
|
+ .size process_bytes, . - process_bytes
|
|
415
|
+
|
|
416
|
+/****************************************************************************
|
|
417
|
+ * install_block
|
|
418
|
+ *
|
|
419
|
+ * Install block to specified address
|
|
420
|
+ *
|
|
421
|
+ * Parameters:
|
|
422
|
+ * %esi : source physical address (must be a multiple of 16)
|
|
423
|
+ * %edi : destination physical address (must be a multiple of 16)
|
|
424
|
+ * %ecx : length of (decompressed) data
|
|
425
|
+ * %edx : total length of block (including any uninitialised data portion)
|
|
426
|
+ * Returns:
|
|
427
|
+ * %esi : next source physical address (will be a multiple of 16)
|
|
428
|
+ * %edi : next destination physical address (will be a multiple of 16)
|
|
429
|
+ * Corrupts:
|
|
430
|
+ * none
|
|
431
|
+ ****************************************************************************
|
|
432
|
+ */
|
|
433
|
+ .section ".prefix.lib", "awx", @progbits
|
|
434
|
+ .code16
|
|
435
|
+install_block:
|
|
436
|
+ /* Preserve registers */
|
|
437
|
+ pushl %ecx
|
|
438
|
+ pushw %bx
|
|
439
|
+
|
|
440
|
+ /* Decompress (or copy) source to destination */
|
278
|
441
|
#if COMPRESS
|
279
|
|
- /* Decompress source to destination */
|
280
|
|
- call decompress16
|
|
442
|
+ movw $decompress16, %bx
|
281
|
443
|
#else
|
282
|
|
- /* Copy source to destination */
|
283
|
|
- call copy_bytes
|
|
444
|
+ movw $copy_bytes, %bx
|
284
|
445
|
#endif
|
|
446
|
+ call process_bytes
|
285
|
447
|
|
286
|
448
|
/* Zero .bss portion */
|
287
|
449
|
negl %ecx
|
288
|
450
|
addl %edx, %ecx
|
289
|
|
- pushw %ax
|
290
|
|
- xorw %ax, %ax
|
291
|
|
- rep addr32 stosb
|
292
|
|
- popw %ax
|
|
451
|
+ movw $zero_bytes, %bx
|
|
452
|
+ call process_bytes
|
293
|
453
|
|
294
|
454
|
/* Round up %esi and %edi to start of next blocks */
|
295
|
455
|
addl $0xf, %esi
|
|
@@ -297,20 +457,9 @@ install_block:
|
297
|
457
|
addl $0xf, %edi
|
298
|
458
|
andl $~0xf, %edi
|
299
|
459
|
|
300
|
|
- /* Convert %ds:esi and %es:edi back to physical addresses */
|
301
|
|
- xorl %ecx, %ecx
|
302
|
|
- movw %ds, %cx
|
303
|
|
- shll $4, %ecx
|
304
|
|
- addl %ecx, %esi
|
305
|
|
- xorl %ecx, %ecx
|
306
|
|
- movw %es, %cx
|
307
|
|
- shll $4, %ecx
|
308
|
|
- addl %ecx, %edi
|
309
|
|
-
|
310
|
460
|
/* Restore registers and return */
|
|
461
|
+ popw %bx
|
311
|
462
|
popl %ecx
|
312
|
|
- popw %es
|
313
|
|
- popw %ds
|
314
|
463
|
ret
|
315
|
464
|
.size install_block, . - install_block
|
316
|
465
|
|
|
@@ -612,11 +761,10 @@ payload_death_message:
|
612
|
761
|
|
613
|
762
|
/* Copy code to new location */
|
614
|
763
|
pushl %edi
|
615
|
|
- pushw %ax
|
616
|
|
- xorw %ax, %ax
|
617
|
|
- movw %ax, %es
|
618
|
|
- es rep addr32 movsb
|
619
|
|
- popw %ax
|
|
764
|
+ pushw %bx
|
|
765
|
+ movw $copy_bytes, %bx
|
|
766
|
+ call process_bytes
|
|
767
|
+ popw %bx
|
620
|
768
|
popl %edi
|
621
|
769
|
|
622
|
770
|
/* Initialise librm at new location */
|