diff options
-rw-r--r-- | com32/include/syslinux/boot.h | 3 | ||||
-rw-r--r-- | com32/lib/syslinux/biosboot.c | 39 | ||||
-rw-r--r-- | com32/lib/syslinux/shuffle.c | 11 | ||||
-rw-r--r-- | core/bcopyxx.inc | 8 | ||||
-rw-r--r-- | core/bios.c | 25 | ||||
-rw-r--r-- | core/cleanup.c | 22 | ||||
-rw-r--r-- | core/comboot.inc | 24 | ||||
-rw-r--r-- | core/diskboot.inc | 1 | ||||
-rw-r--r-- | core/include/bios.h | 1 | ||||
-rw-r--r-- | core/isolinux.asm | 4 | ||||
-rw-r--r-- | core/pxelinux.asm | 4 |
11 files changed, 89 insertions, 53 deletions
diff --git a/com32/include/syslinux/boot.h b/com32/include/syslinux/boot.h index 74a311df..6079e7c1 100644 --- a/com32/include/syslinux/boot.h +++ b/com32/include/syslinux/boot.h @@ -48,6 +48,9 @@ void syslinux_chain_bootstrap(uint16_t flags, const void *bootstrap, uint32_t bootstrap_len, uint32_t edx, uint32_t esi, uint16_t ds); +void bios_do_shuffle_and_boot(uint16_t bootflags, uint32_t descaddr, + const void *descbuf, uint32_t dsize); + struct image_types { const char *name; uint32_t type; diff --git a/com32/lib/syslinux/biosboot.c b/com32/lib/syslinux/biosboot.c new file mode 100644 index 00000000..9bdf84fb --- /dev/null +++ b/com32/lib/syslinux/biosboot.c @@ -0,0 +1,39 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2014 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <syslinux/boot.h> +#include <syslinux/movebits.h> + +void bios_do_shuffle_and_boot(uint16_t bootflags, uint32_t descaddr, + const void *descbuf, uint32_t dsize) +{ + extern void do_raw_shuffle_and_boot(addr_t, const void *, addr_t); + + syslinux_final_cleanup(bootflags); + do_raw_shuffle_and_boot(descaddr, descbuf, dsize); + /* Should not return */ +} diff --git a/com32/lib/syslinux/shuffle.c b/com32/lib/syslinux/shuffle.c index ce85a5c4..2752c881 100644 --- a/com32/lib/syslinux/shuffle.c +++ b/com32/lib/syslinux/shuffle.c @@ -43,6 +43,7 @@ #include <dprintf.h> #include <syslinux/movebits.h> #include <klibc/compiler.h> +#include <syslinux/boot.h> struct shuffle_descriptor { uint32_t dst, src, len; @@ -78,7 +79,6 @@ int syslinux_do_shuffle(struct syslinux_movelist *fraglist, int need_ptrs; addr_t desczone, descfree, descaddr; int nmoves, nzero; - com32sys_t ireg; descaddr = 0; dp = dbuf = NULL; @@ -224,13 +224,8 @@ bail: return rv; /* Actually do it... */ - memset(&ireg, 0, sizeof ireg); - ireg.edi.l = descaddr; - ireg.esi.l = (addr_t) dbuf; - ireg.ecx.l = (addr_t) dp - (addr_t) dbuf; - ireg.edx.w[0] = bootflags; - ireg.eax.w[0] = 0x0024; - __intcall(0x22, &ireg, NULL); + bios_do_shuffle_and_boot(bootflags, descaddr, dbuf, + (addr_t)dp - (addr_t)dbuf); return -1; /* Shouldn't have returned! */ } diff --git a/core/bcopyxx.inc b/core/bcopyxx.inc index cfdda0bc..7a8c6496 100644 --- a/core/bcopyxx.inc +++ b/core/bcopyxx.inc @@ -207,6 +207,14 @@ pm_bcopy: ; ; (*) dst, src, and len are four bytes each ; +; do_raw_shuffle_and_boot is the same entry point, but with a C ABI: +; do_raw_shuffle_and_boot(safearea, descriptors, bytecount) +; + global do_raw_shuffle_and_boot +do_raw_shuffle_and_boot: + mov edi,eax + mov esi,edx + pm_shuffle: cli ; End interrupt service (for good) mov ebx,edi ; EBX <- descriptor list diff --git a/core/bios.c b/core/bios.c index ac1f48bc..9cfb94be 100644 --- a/core/bios.c +++ b/core/bios.c @@ -665,6 +665,31 @@ void bios_init(void) dmi_init(); } +extern void comboot_cleanup_api(void); +extern void bios_timer_cleanup(void); + +extern uint32_t OrigFDCTabPtr; + +static void bios_cleanup_hardware(void) +{ + /* Restore the original pointer to the floppy descriptor table */ + if (OrigFDCTabPtr) + *((uint32_t *)(4 * 0x1e)) = OrigFDCTabPtr; + + /* + * Linux wants the floppy motor shut off before starting the + * kernel, at least bootsect.S seems to imply so. If we don't + * load the floppy driver, this is *definitely* so! + */ + __intcall(0x13, &zero_regs, NULL); + + call16(comboot_cleanup_api, &zero_regs, NULL); + call16(bios_timer_cleanup, &zero_regs, NULL); + + /* If we enabled serial port interrupts, clean them up now */ + sirq_cleanup(); +} + extern void *bios_malloc(size_t, enum heap, size_t); extern void *bios_realloc(void *, size_t); extern void bios_free(void *); diff --git a/core/cleanup.c b/core/cleanup.c index de318d98..eceb8e94 100644 --- a/core/cleanup.c +++ b/core/cleanup.c @@ -15,38 +15,18 @@ #include <syslinux/memscan.h> #include <syslinux/firmware.h> -extern void comboot_cleanup_api(void); -extern void bios_timer_cleanup(void); - /* * cleanup.c * * Some final tidying before jumping to a kernel or bootsector */ -void bios_cleanup_hardware(void) -{ - /* - * TODO - * - * Linux wants the floppy motor shut off before starting the - * kernel, at least bootsect.S seems to imply so. If we don't - * load the floppy driver, this is *definitely* so! - */ - __intcall(0x13, &zero_regs, NULL); - - call16(comboot_cleanup_api, &zero_regs, NULL); - call16(bios_timer_cleanup, &zero_regs, NULL); - - /* If we enabled serial port interrupts, clean them up now */ - sirq_cleanup(); -} - /* * cleanup_hardware: * * Shut down anything transient. */ + __export void cleanup_hardware(void) { firmware->cleanup(); diff --git a/core/comboot.inc b/core/comboot.inc index c6514837..4b64d086 100644 --- a/core/comboot.inc +++ b/core/comboot.inc @@ -342,28 +342,6 @@ comapi_err: stc ret -; -; INT 22h AX=0024h Cleanup, shuffle and boot raw -; -comapi_shufraw: -%if IS_PXELINUX - ; Unload PXE if requested - test dl,3 - setnz [KeepPXE] - sub bp,sp ; unload_pxe may move the stack around - pm_call unload_pxe - add bp,sp ; restore frame pointer... -%elif IS_SYSLINUX || IS_EXTLINUX - ; Restore original FDC table - mov eax,[OrigFDCTabPtr] - mov [fdctab],eax -%endif - pm_call cleanup_hardware - mov edi,P_EDI - mov esi,P_ESI - mov ecx,P_ECX - jmp shuffle_and_boot_raw - section .data16 alignz 2 @@ -404,7 +382,7 @@ int22_table: dw comapi_err ; 0021 read directory dw comapi_err ; 0022 close directory dw comapi_err ; 0023 query shuffler size - dw comapi_shufraw ; 0024 cleanup, shuffle and boot raw + dw comapi_err ; 0024 cleanup, shuffle and boot raw dw comapi_err ; 0025 initialize adv structure int22_count equ ($-int22_table)/2 diff --git a/core/diskboot.inc b/core/diskboot.inc index ce75b8c9..9dea6f9a 100644 --- a/core/diskboot.inc +++ b/core/diskboot.inc @@ -29,6 +29,7 @@ ; global StackBuf, PartInfo, Hidden, OrigESDI, DriveNumber + global OrigFDCTabPtr StackBuf equ STACK_TOP-44-92 ; Start the stack here (grow down - 4K) PartInfo equ StackBuf .mbr equ PartInfo diff --git a/core/include/bios.h b/core/include/bios.h index 0a68f5d3..a9f4ef17 100644 --- a/core/include/bios.h +++ b/core/include/bios.h @@ -88,7 +88,6 @@ extern char *SerialHead; extern char *SerialTail; extern void bios_init(void); -extern void bios_cleanup_hardware(void); static inline uint16_t get_serial_port(uint16_t port) { diff --git a/core/isolinux.asm b/core/isolinux.asm index f1512611..94a5b0b4 100644 --- a/core/isolinux.asm +++ b/core/isolinux.asm @@ -1236,3 +1236,7 @@ KernelName resb FILENAME_MAX ; Mangled name for kernel section .data16 err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0 + + section .bss16 + global OrigFDCTabPtr +OrigFDCTabPtr dd 0 ; Keep bios_cleanup_hardware() honest diff --git a/core/pxelinux.asm b/core/pxelinux.asm index f4c52c2b..029e4004 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -575,3 +575,7 @@ syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', MY_TYPE, ' ' section .data16 global KeepPXE KeepPXE db 0 ; Should PXE be kept around? + + section .bss16 + global OrigFDCTabPtr +OrigFDCTabPtr dd 0 ; Keep bios_cleanup_hardware() honest |