You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

multiboot.c 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* Support for Multiboot */
  2. #include <etherboot.h>
  3. #include <lib.h>
  4. #include <sys_info.h>
  5. #include <arch/io.h>
  6. #define DEBUG_THIS DEBUG_MULTIBOOT
  7. #include <debug.h>
  8. /* Multiboot header, gives information to loader */
  9. #define MULTIBOOT_HEADER_MAGIC 0x1BADB002
  10. #define MULTIBOOT_HEADER_FLAGS 0x00000003
  11. struct mbheader {
  12. unsigned int magic, flags, checksum;
  13. };
  14. const struct mbheader multiboot_header
  15. __attribute__((section (".hdr"))) =
  16. {
  17. MULTIBOOT_HEADER_MAGIC,
  18. MULTIBOOT_HEADER_FLAGS,
  19. -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
  20. };
  21. /* Multiboot information structure, provided by loader to us */
  22. struct multiboot_mmap {
  23. unsigned entry_size;
  24. unsigned base_lo, base_hi;
  25. unsigned size_lo, size_hi;
  26. unsigned type;
  27. };
  28. struct multiboot_info {
  29. unsigned flags;
  30. #define MULTIBOOT_MEM_VALID 0x01
  31. #define MULTIBOOT_BOOT_DEV_VALID 0x02
  32. #define MULTIBOOT_CMDLINE_VALID 0x04
  33. #define MULTIBOOT_MODS_VALID 0x08
  34. #define MULTIBOOT_AOUT_SYMS_VALID 0x10
  35. #define MULTIBOOT_ELF_SYMS_VALID 0x20
  36. #define MULTIBOOT_MMAP_VALID 0x40
  37. unsigned mem_lower;
  38. unsigned mem_upper;
  39. unsigned char boot_device[4];
  40. unsigned command_line;
  41. unsigned mods_count;
  42. unsigned mods_addr;
  43. unsigned syms_num;
  44. unsigned syms_size;
  45. unsigned syms_addr;
  46. unsigned syms_shndx;
  47. unsigned mmap_length;
  48. unsigned mmap_addr;
  49. };
  50. void collect_multiboot_info(struct sys_info *info)
  51. {
  52. struct multiboot_info *mbinfo;
  53. struct multiboot_mmap *mbmem;
  54. unsigned mbcount, mbaddr;
  55. int i;
  56. struct memrange *mmap;
  57. int mmap_count;
  58. if (info->boot_type != 0x2BADB002)
  59. return;
  60. debug("Using Multiboot information at %#lx\n", info->boot_data);
  61. mbinfo = phys_to_virt(info->boot_data);
  62. if (mbinfo->flags & MULTIBOOT_MMAP_VALID) {
  63. /* convert mmap records */
  64. mbmem = phys_to_virt(mbinfo->mmap_addr);
  65. mbcount = mbinfo->mmap_length / (mbmem->entry_size + 4);
  66. mmap = malloc(mbcount * sizeof *mmap);
  67. mmap_count = 0;
  68. mbaddr = mbinfo->mmap_addr;
  69. for (i = 0; i < mbcount; i++) {
  70. mbmem = phys_to_virt(mbaddr);
  71. debug("%08x%08x %08x%08x (%d)\n",
  72. mbmem->base_hi,
  73. mbmem->base_lo,
  74. mbmem->size_hi,
  75. mbmem->size_lo,
  76. mbmem->type);
  77. if (mbmem->type == 1) { /* Only normal RAM */
  78. mmap[mmap_count].base = mbmem->base_lo
  79. + (((unsigned long long) mbmem->base_hi) << 32);
  80. mmap[mmap_count].size = mbmem->size_lo
  81. + (((unsigned long long) mbmem->size_hi) << 32);
  82. mmap_count++;
  83. }
  84. mbaddr += mbmem->entry_size + 4;
  85. if (mbaddr >= mbinfo->mmap_addr + mbinfo->mmap_length)
  86. break;
  87. }
  88. /* simple sanity check - there should be at least 2 RAM segments
  89. * (base 640k and extended) */
  90. if (mmap_count >= 2)
  91. goto got_it;
  92. printf("Multiboot mmap is broken\n");
  93. free(mmap);
  94. /* fall back to mem_lower/mem_upper */
  95. }
  96. if (mbinfo->flags & MULTIBOOT_MEM_VALID) {
  97. /* use mem_lower and mem_upper */
  98. mmap_count = 2;
  99. mmap = malloc(2 * sizeof(*mmap));
  100. mmap[0].base = 0;
  101. mmap[0].size = mbinfo->mem_lower << 10;
  102. mmap[1].base = 1 << 20; /* 1MB */
  103. mmap[1].size = mbinfo->mem_upper << 10;
  104. goto got_it;
  105. }
  106. printf("Can't get memory information from Multiboot\n");
  107. return;
  108. got_it:
  109. info->memrange = mmap;
  110. info->n_memranges = mmap_count;
  111. return;
  112. }