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 | } |
---|