plat.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. plat.c
  5. Abstract:
  6. This module contains platform specific setup instructions.
  7. Author:
  8. Evan Green 7-May-2014
  9. Environment:
  10. User Mode
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <assert.h>
  16. #include <errno.h>
  17. #include <fcntl.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/stat.h>
  22. #include "setup.h"
  23. //
  24. // ---------------------------------------------------------------- Definitions
  25. //
  26. #define SETUP_RECIPE_FLAG_HIDDEN 0x00000001
  27. //
  28. // ------------------------------------------------------ Data Type Definitions
  29. //
  30. /*++
  31. Structure Description:
  32. This structure stores installation directions for a specific platform or
  33. configuration.
  34. Members:
  35. Id - Stores the recipe identifier.
  36. ShortName - Stores the short name of the platform, usually used at the
  37. command line.
  38. Description - Stores the longer name of the platform, used when printing.
  39. SmbiosProductName - Stores the platform name in the SMBIOS product name
  40. field.
  41. Flags - Stores a bitfield of flags. See SETUP_RECIPE_FLAG_* definitions.
  42. Script - Stores a pointer to the script corresponding to this recipe.
  43. ScriptEnd - Stores the pointer to the end of the script (the first invalid
  44. character). It's assumed there is no null terminator.
  45. --*/
  46. typedef struct _SETUP_RECIPE {
  47. SETUP_RECIPE_ID Id;
  48. PSTR ShortName;
  49. PSTR Description;
  50. PSTR SmbiosProductName;
  51. ULONG Flags;
  52. PVOID Script;
  53. PVOID ScriptEnd;
  54. } SETUP_RECIPE, *PSETUP_RECIPE;
  55. //
  56. // ----------------------------------------------- Internal Function Prototypes
  57. //
  58. //
  59. // -------------------------------------------------------------------- Globals
  60. //
  61. //
  62. // The objcopy utility provides symbols for the start, size, and end of the
  63. // text files converted to object files. These correspond directly to the
  64. // file names in the config directory, and are alphabetized.
  65. //
  66. extern PVOID _binary_bbone_txt_start;
  67. extern PVOID _binary_bbone_txt_end;
  68. extern PVOID _binary_common_txt_start;
  69. extern PVOID _binary_common_txt_end;
  70. extern PVOID _binary_galileo_txt_start;
  71. extern PVOID _binary_galileo_txt_end;
  72. extern PVOID _binary_instarv6_txt_start;
  73. extern PVOID _binary_instarv6_txt_end;
  74. extern PVOID _binary_instarv7_txt_start;
  75. extern PVOID _binary_instarv7_txt_end;
  76. extern PVOID _binary_instx86_txt_start;
  77. extern PVOID _binary_instx86_txt_end;
  78. extern PVOID _binary_integrd_txt_start;
  79. extern PVOID _binary_integrd_txt_end;
  80. extern PVOID _binary_panda_txt_start;
  81. extern PVOID _binary_panda_txt_end;
  82. extern PVOID _binary_pandausb_txt_start;
  83. extern PVOID _binary_pandausb_txt_end;
  84. extern PVOID _binary_pc_txt_start;
  85. extern PVOID _binary_pc_txt_end;
  86. extern PVOID _binary_pcefi_txt_start;
  87. extern PVOID _binary_pcefi_txt_end;
  88. extern PVOID _binary_pctiny_txt_start;
  89. extern PVOID _binary_pctiny_txt_end;
  90. extern PVOID _binary_rpi2_txt_start;
  91. extern PVOID _binary_rpi2_txt_end;
  92. extern PVOID _binary_rpi_txt_start;
  93. extern PVOID _binary_rpi_txt_end;
  94. extern PVOID _binary_veyron_txt_start;
  95. extern PVOID _binary_veyron_txt_end;
  96. //
  97. // Define the recipes used to install to specific platforms. These are kept
  98. // in the same order as above.
  99. //
  100. SETUP_RECIPE SetupRecipes[] = {
  101. {
  102. SetupRecipeNone,
  103. "None",
  104. "Complete user customization",
  105. NULL,
  106. SETUP_RECIPE_FLAG_HIDDEN,
  107. NULL,
  108. NULL
  109. },
  110. {
  111. SetupRecipeBeagleBoneBlack,
  112. "beagleboneblack",
  113. "TI BeagleBone Black",
  114. "A335BNLT",
  115. 0,
  116. &_binary_bbone_txt_start,
  117. &_binary_bbone_txt_end
  118. },
  119. {
  120. SetupRecipeCommon,
  121. "common",
  122. "Common initialization",
  123. NULL,
  124. SETUP_RECIPE_FLAG_HIDDEN,
  125. &_binary_common_txt_start,
  126. &_binary_common_txt_end
  127. },
  128. {
  129. SetupRecipeGalileo,
  130. "galileo",
  131. "Intel Galileo",
  132. "QUARK",
  133. 0,
  134. &_binary_galileo_txt_start,
  135. &_binary_galileo_txt_end
  136. },
  137. {
  138. SetupRecipeInstallArmv6,
  139. "install-armv6",
  140. "ARMv6 Install Image Recipe",
  141. NULL,
  142. SETUP_RECIPE_FLAG_HIDDEN,
  143. &_binary_instarv6_txt_start,
  144. &_binary_instarv6_txt_end
  145. },
  146. {
  147. SetupRecipeInstallArmv7,
  148. "install-armv7",
  149. "ARMv7 Install Image Recipe",
  150. NULL,
  151. SETUP_RECIPE_FLAG_HIDDEN,
  152. &_binary_instarv7_txt_start,
  153. &_binary_instarv7_txt_end
  154. },
  155. {
  156. SetupRecipeInstallX86,
  157. "install-x86",
  158. "x86 Install Image Recipe",
  159. NULL,
  160. SETUP_RECIPE_FLAG_HIDDEN,
  161. &_binary_instx86_txt_start,
  162. &_binary_instx86_txt_end
  163. },
  164. {
  165. SetupRecipeIntegratorCpRamDisk,
  166. "integrd",
  167. "Integrator/CP RAM Disk Recipe",
  168. NULL,
  169. SETUP_RECIPE_FLAG_HIDDEN,
  170. &_binary_integrd_txt_start,
  171. &_binary_integrd_txt_end
  172. },
  173. {
  174. SetupRecipePandaBoard,
  175. "panda",
  176. "TI PandaBoard",
  177. "PandaBoard",
  178. 0,
  179. &_binary_panda_txt_start,
  180. &_binary_panda_txt_end
  181. },
  182. {
  183. SetupRecipePandaBoard,
  184. "panda-es",
  185. "TI PandaBoard ES",
  186. "PandaBoard ES",
  187. SETUP_RECIPE_FLAG_HIDDEN,
  188. &_binary_panda_txt_start,
  189. &_binary_panda_txt_end
  190. },
  191. {
  192. SetupRecipePandaBoardUsb,
  193. "panda-usb",
  194. "TI PandaBoard USB Image Recipe",
  195. NULL,
  196. SETUP_RECIPE_FLAG_HIDDEN,
  197. &_binary_pandausb_txt_start,
  198. &_binary_pandausb_txt_end
  199. },
  200. {
  201. SetupRecipePc,
  202. "pc",
  203. "Standard x86 BIOS PC",
  204. NULL,
  205. 0,
  206. &_binary_pc_txt_start,
  207. &_binary_pc_txt_end
  208. },
  209. {
  210. SetupRecipePcEfi,
  211. "pcefi",
  212. "Standard x86 UEFI-based PC",
  213. NULL,
  214. 0,
  215. &_binary_pcefi_txt_start,
  216. &_binary_pcefi_txt_end
  217. },
  218. {
  219. SetupRecipePcTiny,
  220. "pc-tiny",
  221. "Minimal PC installation for Qemu",
  222. NULL,
  223. SETUP_RECIPE_FLAG_HIDDEN,
  224. &_binary_pctiny_txt_start,
  225. &_binary_pctiny_txt_end
  226. },
  227. {
  228. SetupRecipeRaspberryPi2,
  229. "raspberrypi2",
  230. "Raspberry Pi 2",
  231. "Raspberry Pi 2",
  232. 0,
  233. &_binary_rpi2_txt_start,
  234. &_binary_rpi2_txt_end
  235. },
  236. {
  237. SetupRecipeRaspberryPi,
  238. "raspberrypi",
  239. "Raspberry Pi",
  240. "Raspberry Pi",
  241. 0,
  242. &_binary_rpi_txt_start,
  243. &_binary_rpi_txt_end
  244. },
  245. {
  246. SetupRecipeVeyron,
  247. "veyron",
  248. "ASUS C201",
  249. "C201",
  250. 0,
  251. &_binary_veyron_txt_start,
  252. &_binary_veyron_txt_end
  253. },
  254. };
  255. //
  256. // ------------------------------------------------------------------ Functions
  257. //
  258. BOOL
  259. SetupParsePlatformString (
  260. PSETUP_CONTEXT Context,
  261. PSTR PlatformString
  262. )
  263. /*++
  264. Routine Description:
  265. This routine converts a platform string into a platform identifier, and
  266. sets it in the setup context.
  267. Arguments:
  268. Context - Supplies a pointer to the setup context.
  269. PlatformString - Supplies a pointer to the string to convert to a
  270. platform identifier.
  271. Return Value:
  272. TRUE if the platform name was successfully converted.
  273. FALSE if the name was invalid.
  274. --*/
  275. {
  276. PSETUP_RECIPE Recipe;
  277. ULONG RecipeCount;
  278. ULONG RecipeIndex;
  279. RecipeCount = sizeof(SetupRecipes) / sizeof(SetupRecipes[0]);
  280. for (RecipeIndex = 0; RecipeIndex < RecipeCount; RecipeIndex += 1) {
  281. Recipe = &(SetupRecipes[RecipeIndex]);
  282. if (((Recipe->ShortName != NULL) &&
  283. (strcasecmp(PlatformString, Recipe->ShortName) == 0)) ||
  284. ((Recipe->Description != NULL) &&
  285. (strcasecmp(PlatformString, Recipe->Description) == 0))) {
  286. Context->RecipeIndex = RecipeIndex;
  287. return TRUE;
  288. }
  289. }
  290. return FALSE;
  291. }
  292. VOID
  293. SetupPrintPlatformList (
  294. VOID
  295. )
  296. /*++
  297. Routine Description:
  298. This routine prints the supported platform list.
  299. Arguments:
  300. None.
  301. Return Value:
  302. None.
  303. --*/
  304. {
  305. PSETUP_RECIPE Recipe;
  306. ULONG RecipeCount;
  307. ULONG RecipeIndex;
  308. printf("Supported platforms:\n");
  309. RecipeCount = sizeof(SetupRecipes) / sizeof(SetupRecipes[0]);
  310. for (RecipeIndex = 0; RecipeIndex < RecipeCount; RecipeIndex += 1) {
  311. Recipe = &(SetupRecipes[RecipeIndex]);
  312. if ((Recipe->Flags & SETUP_RECIPE_FLAG_HIDDEN) != 0) {
  313. continue;
  314. }
  315. printf(" %s -- %s\n", Recipe->ShortName, Recipe->Description);
  316. }
  317. return;
  318. }
  319. INT
  320. SetupDeterminePlatform (
  321. PSETUP_CONTEXT Context
  322. )
  323. /*++
  324. Routine Description:
  325. This routine finalizes the setup platform recipe to use.
  326. Arguments:
  327. Context - Supplies a pointer to the setup context.
  328. Return Value:
  329. 0 on success.
  330. Non-zero on failure.
  331. --*/
  332. {
  333. SETUP_RECIPE_ID Fallback;
  334. LONG FallbackRecipeIndex;
  335. PSTR PlatformName;
  336. PSETUP_RECIPE Recipe;
  337. ULONG RecipeCount;
  338. ULONG RecipeIndex;
  339. INT Result;
  340. INT SmbiosLength;
  341. PSTR SmbiosName;
  342. PlatformName = NULL;
  343. Fallback = SetupRecipeNone;
  344. //
  345. // If the user specified a platform, just use it.
  346. //
  347. if (Context->RecipeIndex != -1) {
  348. return 0;
  349. }
  350. //
  351. // Ask the OS to detect the current platform.
  352. //
  353. Result = SetupOsGetPlatformName(&PlatformName, &Fallback);
  354. if (Result != 0) {
  355. if (Result != ENOSYS) {
  356. fprintf(stderr,
  357. "Failed to detect platform: %s\n",
  358. strerror(Result));
  359. }
  360. goto DeterminePlatformEnd;
  361. }
  362. if ((Context->Flags & SETUP_FLAG_VERBOSE) != 0) {
  363. printf("SMBIOS Platform Name: %s\n", PlatformName);
  364. }
  365. FallbackRecipeIndex = -1;
  366. RecipeCount = sizeof(SetupRecipes) / sizeof(SetupRecipes[0]);
  367. for (RecipeIndex = 0; RecipeIndex < RecipeCount; RecipeIndex += 1) {
  368. Recipe = &(SetupRecipes[RecipeIndex]);
  369. if (Recipe->Id == Fallback) {
  370. FallbackRecipeIndex = RecipeIndex;
  371. }
  372. //
  373. // Compare the name, ignoring case and ignoring any extra stuff that
  374. // might be on the end like a version.
  375. //
  376. SmbiosName = Recipe->SmbiosProductName;
  377. if ((PlatformName != NULL) && (SmbiosName != NULL)) {
  378. SmbiosLength = strlen(SmbiosName);
  379. if (strncasecmp(SmbiosName, PlatformName, SmbiosLength) == 0) {
  380. Context->RecipeIndex = RecipeIndex;
  381. break;
  382. }
  383. }
  384. }
  385. if (Context->RecipeIndex == -1) {
  386. if (FallbackRecipeIndex == -1) {
  387. fprintf(stderr,
  388. "Failed to convert platform name %s to recipe.\n",
  389. PlatformName);
  390. Result = EINVAL;
  391. goto DeterminePlatformEnd;
  392. }
  393. Context->RecipeIndex = FallbackRecipeIndex;
  394. }
  395. if ((Context->Flags & SETUP_FLAG_VERBOSE) != 0) {
  396. Recipe = &(SetupRecipes[Context->RecipeIndex]);
  397. printf("Platform: %s\n", Recipe->Description);
  398. }
  399. Result = 0;
  400. DeterminePlatformEnd:
  401. if (PlatformName != NULL) {
  402. free(PlatformName);
  403. }
  404. return Result;
  405. }
  406. INT
  407. SetupAddRecipeScript (
  408. PSETUP_CONTEXT Context
  409. )
  410. /*++
  411. Routine Description:
  412. This routine adds the platform recipe script.
  413. Arguments:
  414. Context - Supplies a pointer to the setup context.
  415. Return Value:
  416. 0 on success.
  417. Non-zero on failure.
  418. --*/
  419. {
  420. PSETUP_RECIPE Recipe;
  421. UINTN ScriptSize;
  422. INT Status;
  423. if (Context->RecipeIndex == -1) {
  424. return 0;
  425. }
  426. Recipe = &(SetupRecipes[Context->RecipeIndex]);
  427. if (Recipe->Script == NULL) {
  428. return 0;
  429. }
  430. ScriptSize = (UINTN)(Recipe->ScriptEnd) - (UINTN)(Recipe->Script);
  431. Status = ChalkLoadScriptBuffer(&(Context->Interpreter),
  432. Recipe->ShortName,
  433. Recipe->Script,
  434. ScriptSize,
  435. 0,
  436. NULL);
  437. return Status;
  438. }
  439. INT
  440. SetupAddCommonScripts (
  441. PSETUP_CONTEXT Context
  442. )
  443. /*++
  444. Routine Description:
  445. This routine adds the common scripts that are added no matter what.
  446. Arguments:
  447. Context - Supplies a pointer to the setup context.
  448. Return Value:
  449. 0 on success.
  450. Non-zero on failure.
  451. --*/
  452. {
  453. PSETUP_RECIPE Recipe;
  454. ULONG RecipeCount;
  455. ULONG RecipeIndex;
  456. UINTN ScriptSize;
  457. INT Status;
  458. Status = 0;
  459. RecipeCount = sizeof(SetupRecipes) / sizeof(SetupRecipes[0]);
  460. for (RecipeIndex = 0; RecipeIndex < RecipeCount; RecipeIndex += 1) {
  461. Recipe = &(SetupRecipes[RecipeIndex]);
  462. if (Recipe->Id != SetupRecipeCommon) {
  463. continue;
  464. }
  465. ScriptSize = (UINTN)(Recipe->ScriptEnd) - (UINTN)(Recipe->Script);
  466. Status = ChalkLoadScriptBuffer(&(Context->Interpreter),
  467. Recipe->ShortName,
  468. Recipe->Script,
  469. ScriptSize,
  470. 0,
  471. NULL);
  472. if (Status != 0) {
  473. fprintf(stderr, "Failed to add common scripts.\n");
  474. break;
  475. }
  476. }
  477. return Status;
  478. }
  479. //
  480. // --------------------------------------------------------- Internal Functions
  481. //