Home | History | Annotate | Download | only in modules
      1 /* ----------------------------------------------------------------------- *
      2  *
      3  *   Copyright 2010 Gert Hulselmans - All Rights Reserved
      4  *
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
      8  *   Boston MA 02110-1301, USA; either version 2 of the License, or
      9  *   (at your option) any later version; incorporated herein by reference.
     10  *
     11  * ----------------------------------------------------------------------- */
     12 
     13 /*
     14  * ifplop.c
     15  *
     16  * This COM32 module detects if the PLoP Boot Manager was used to boot a CDROM
     17  * drive or USB drive, by checking for the presence of the PLoP INT13h hook.
     18  *
     19  * Usage:    ifplop.c32 [<plop_detected>] -- [<plop_not_detected>]
     20  * Examples: ifplop.c32 menu.c32 another.cfg -- plpbt hiddenusb usb1=2
     21  *              You need to remove the ".bin" extension of the plpbt.bin file
     22  *              if you use it this way.
     23  *           ifplop.c32 plop_detected -- plop_not_detected
     24  *
     25  * A possible config file could be:
     26  *
     27  * ===========================================================================
     28  *  DEFAULT plopcheck
     29  *
     30  *  # Check for the presence of PLoP (run by default)
     31  *  #   When PLoP INT13h hook is found, run the first command (plop_detected)
     32  *  #   When PLoP INT13h hook isn't found, run the second command (plop_not_detected)
     33  *  LABEL plopcheck
     34  *      COM32 ifplop.c32
     35  *      APPEND plop_detected -- plop_not_detected
     36  *
     37  *  # When PLoP INT13h hook was found, boot the menu system.
     38  *  # PLoP can have added USB 2.0 speed, so the entries we want to boot
     39  *  # will be read from disk much faster (supposing that we have a BIOS
     40  *  # that only supports USB 1.1 speed, but a mobo with USB 2.0 controllers).
     41  *  LABEL plop_detected
     42  *      COM32 menu.c32
     43  *      APPEND another.cfg
     44  *
     45  *  # PLoP INT13h hook wasn't found, so we boot PLoP, so it can add USB 2.0 support
     46  *  # When using "LINUX plpbt.bin", you don't need to remove the .bin extension.
     47  *  LABEL plop_not_detected
     48  *      LINUX plpbt.bin
     49  *      APPEND hiddenusb usb1=2
     50  *
     51  * ===========================================================================
     52  *
     53  * Why is/can this module be useful?
     54  *
     55  * You may want to boot PLoP by default from Syslinux when you boot from your
     56  * USB stick/drive:
     57  *   1. PLoP can upgrade USB 1.1 speed offered by the BIOS to USB 2.0 speed
     58  *      if you have USB 2.0 controllers on your mobo.
     59  *   2. Some BIOSes only can access the first 128GiB (137GB) on USB drives, while
     60  *      internal hard drives don't necessarily suffer from this 128GiB problem.
     61  *      Using PLoPs USB capabilities, you can access the whole drive.
     62  *
     63  * When you select the "USB" entry in PLoP, it will boot your USB stick/drive
     64  * again and it will boot PLoP again when you have set booting PLoP as DEFAULT
     65  * boot option in your Syslinux configuration file.
     66  *
     67  * By using ifplop.c32 you can specify which action you want to do the second
     68  * time your USB stick/drive is booted. So you can load another config file or
     69  * boot a large hard disk image or whatever you want.
     70  *
     71  * PLoP Boot Manager website: http://www.plop.at/en/bootmanager.html
     72  */
     73 
     74 #include <com32.h>
     75 #include <stdlib.h>
     76 #include <stdio.h>
     77 #include <string.h>
     78 #include <alloca.h>
     79 #include <console.h>
     80 #include <syslinux/boot.h>
     81 
     82 static bool plop_INT13h_check(void)
     83 {
     84     com32sys_t inregs, outregs;
     85 
     86     /* Prepare the register set */
     87     memset(&inregs, 0, sizeof inregs);
     88 
     89     /*
     90      * Check if PLoP already has booted a CDROM or USB drive by checking
     91      * for the presence of the PLoP INT13h hook.
     92      *
     93      * The following assembly code (NASM) can detect the PLoP INT13h hook:
     94      *
     95      *   mov eax,'PoLP'  ; Reverse of 'PLoP'
     96      *   mov ebp,'DKHC'  ; Reverse of 'CHKD'
     97      *   int 13h
     98      *   cmp eax,' sey'  ; Reverse of 'yes '
     99      *   jz plop_INT13h_active
    100      */
    101 
    102     inregs.eax.l = 0x504c6f50;	/* "PLoP" */
    103     inregs.ebp.l = 0x43484b44;	/* "CHKD" */
    104 
    105     __intcall(0x13, &inregs, &outregs);
    106 
    107     /* eax will contain "yes " if PLoP INT13h hook is available */
    108     if (outregs.eax.l == 0x79657320)
    109 	return true;
    110 
    111     return false;
    112 }
    113 
    114 /* XXX: this really should be librarized */
    115 static void boot_args(char **args)
    116 {
    117     int len = 0, a = 0;
    118     char **pp;
    119     const char *p;
    120     char c, *q, *str;
    121 
    122     for (pp = args; *pp; pp++)
    123 	len += strlen(*pp) + 1;
    124 
    125     q = str = alloca(len);
    126     for (pp = args; *pp; pp++) {
    127 	p = *pp;
    128 	while ((c = *p++))
    129 	    *q++ = c;
    130 	*q++ = ' ';
    131 	a = 1;
    132     }
    133     q -= a;
    134     *q = '\0';
    135 
    136     if (!str[0])
    137 	syslinux_run_default();
    138     else
    139 	syslinux_run_command(str);
    140 }
    141 
    142 int main(int argc, char *argv[])
    143 {
    144     char **args[2];
    145     int arg = 0;
    146 
    147     if (argc)
    148 	arg++;
    149     args[0] = &argv[arg];
    150     args[1] = NULL;
    151     while (arg < argc) {
    152 	if (!strcmp(argv[arg], "--")) {
    153 	    argv[arg] = NULL;
    154 	    args[1] = &argv[arg + 1];
    155 	    break;
    156 	}
    157 	arg++;
    158     }
    159     if (args[1] != NULL) {
    160 	boot_args(plop_INT13h_check()? args[0] : args[1]);
    161     } else {
    162 	fprintf(stderr,
    163 		"Usage:   ifplop.c32 [<plop_detected>] -- [<plop_not_detected>]\n"
    164 		"Example: ifplop.c32 menu.c32 another.cfg -- plpbt hiddenusb usb1=2\n");
    165     }
    166 
    167     return 0;
    168 }
    169