Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

elf.c 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "etherboot.h"
  2. #include "elf.h"
  3. #include "memsizes.h"
  4. #define NAME "Etherboot"
  5. #if defined(PCBIOS)
  6. #define FIRMWARE "PCBIOS"
  7. #endif
  8. #if defined(LINUXBIOS)
  9. #define FIRMWARE "LinuxBIOS"
  10. #endif
  11. #if !defined(FIRMWARE)
  12. #error "No BIOS selected"
  13. #endif
  14. #define SZ(X) ((sizeof(X)+3) & ~3)
  15. #define CP(D,S) (memcpy(&(D), &(S), sizeof(S)))
  16. struct elf_notes {
  17. /* The note header */
  18. struct Elf_Bhdr hdr;
  19. /* First the Fixed sized entries that must be well aligned */
  20. /* Pointer to bootp data */
  21. Elf_Nhdr nf1;
  22. char nf1_name[SZ(EB_PARAM_NOTE)];
  23. uint32_t nf1_bootp_data;
  24. /* Pointer to ELF header */
  25. Elf_Nhdr nf2;
  26. char nf2_name[SZ(EB_PARAM_NOTE)];
  27. uint32_t nf2_header;
  28. /* A copy of the i386 memory map */
  29. Elf_Nhdr nf3;
  30. char nf3_name[SZ(EB_PARAM_NOTE)];
  31. struct meminfo nf3_meminfo;
  32. /* Then the variable sized data string data where alignment does not matter */
  33. /* The bootloader name */
  34. Elf_Nhdr nv1;
  35. char nv1_desc[SZ(NAME)];
  36. /* The bootloader version */
  37. Elf_Nhdr nv2;
  38. char nv2_desc[SZ(VERSION)];
  39. /* The firmware type */
  40. Elf_Nhdr nv3;
  41. char nv3_desc[SZ(FIRMWARE)];
  42. /* Name of the loaded image */
  43. Elf_Nhdr nv4;
  44. char nv4_loaded_image[128];
  45. /* An empty command line */
  46. Elf_Nhdr nv5;
  47. char nv5_cmdline[SZ("")];
  48. };
  49. #define ELF_NOTE_COUNT (3 + 5)
  50. static struct elf_notes notes;
  51. struct Elf_Bhdr *prepare_boot_params(void *header)
  52. {
  53. memset(&notes, 0, sizeof(notes));
  54. notes.hdr.b_signature = ELF_BHDR_MAGIC;
  55. notes.hdr.b_size = sizeof(notes);
  56. notes.hdr.b_checksum = 0;
  57. notes.hdr.b_records = ELF_NOTE_COUNT;
  58. /* Initialize the fixed length entries. */
  59. notes.nf1.n_namesz = sizeof(EB_PARAM_NOTE);
  60. notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
  61. notes.nf1.n_type = EB_BOOTP_DATA;
  62. CP(notes.nf1_name, EB_PARAM_NOTE);
  63. notes.nf1_bootp_data = virt_to_phys(BOOTP_DATA_ADDR);
  64. notes.nf2.n_namesz = sizeof(EB_PARAM_NOTE);
  65. notes.nf2.n_descsz = sizeof(notes.nf2_header);
  66. notes.nf2.n_type = EB_HEADER;
  67. CP(notes.nf2_name, EB_PARAM_NOTE);
  68. notes.nf2_header = virt_to_phys(header);
  69. notes.nf3.n_namesz = sizeof(EB_PARAM_NOTE);
  70. notes.nf3.n_descsz = sizeof(notes.nf3_meminfo);
  71. notes.nf3.n_type = EB_I386_MEMMAP;
  72. CP(notes.nf3_name, EB_PARAM_NOTE);
  73. memcpy(&notes.nf3_meminfo, &meminfo, sizeof(meminfo));
  74. /* Initialize the variable length entries */
  75. notes.nv1.n_namesz = 0;
  76. notes.nv1.n_descsz = sizeof(NAME);
  77. notes.nv1.n_type = EBN_BOOTLOADER_NAME;
  78. CP(notes.nv1_desc, NAME);
  79. notes.nv2.n_namesz = 0;
  80. notes.nv2.n_descsz = sizeof(VERSION);
  81. notes.nv2.n_type = EBN_BOOTLOADER_VERSION;
  82. CP(notes.nv2_desc, VERSION);
  83. notes.nv3.n_namesz = 0;
  84. notes.nv3.n_descsz = sizeof(FIRMWARE);
  85. notes.nv3.n_type = EBN_FIRMWARE_TYPE;
  86. CP(notes.nv3_desc, FIRMWARE);
  87. /* Attempt to pass the name of the loaded image */
  88. notes.nv4.n_namesz = 0;
  89. notes.nv4.n_descsz = sizeof(notes.nv4_loaded_image);
  90. notes.nv4.n_type = EBN_LOADED_IMAGE;
  91. memcpy(&notes.nv4_loaded_image, KERNEL_BUF, sizeof(notes.nv4_loaded_image));
  92. /* Pass an empty command line for now */
  93. notes.nv5.n_namesz = 0;
  94. notes.nv5.n_descsz = sizeof("");
  95. notes.nv5.n_type = EBN_COMMAND_LINE;
  96. CP(notes.nv5_cmdline, "");
  97. notes.hdr.b_checksum = ipchksum(&notes, sizeof(notes));
  98. /* Like UDP invert a 0 checksum to show that a checksum is present */
  99. if (notes.hdr.b_checksum == 0) {
  100. notes.hdr.b_checksum = 0xffff;
  101. }
  102. return &notes.hdr;
  103. }
  104. int elf_start(unsigned long machine __unused_i386, unsigned long entry, unsigned long params)
  105. {
  106. #if defined(CONFIG_X86_64)
  107. if (machine == EM_X86_64) {
  108. return xstart_lm(entry, params);
  109. }
  110. #endif
  111. return xstart32(entry, params);
  112. }