acorn.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* acorn.c - Read Linux/ADFS partition tables. */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2005,2007 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/disk.h>
  20. #include <grub/misc.h>
  21. #include <grub/mm.h>
  22. #include <grub/partition.h>
  23. #include <grub/acorn_filecore.h>
  24. #define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de)
  25. #define LINUX_SWAP_MAGIC grub_cpu_to_le32 (0xdeafab1e)
  26. #define LINUX_MAP_ENTRIES (512 / 12)
  27. #define NONADFS_PARTITION_TYPE_LINUX 9
  28. #define NONADFS_PARTITION_TYPE_MASK 15
  29. struct grub_acorn_boot_block
  30. {
  31. grub_uint8_t misc[0x1C0];
  32. struct grub_filecore_disc_record disc_record;
  33. grub_uint8_t flags;
  34. grub_uint16_t start_cylinder;
  35. grub_uint8_t checksum;
  36. } __attribute__ ((packed, aligned));
  37. struct linux_part
  38. {
  39. grub_uint32_t magic;
  40. grub_uint32_t start;
  41. grub_uint32_t size;
  42. };
  43. static struct grub_partition_map grub_acorn_partition_map;
  44. static grub_err_t
  45. acorn_partition_map_find (grub_disk_t disk, struct linux_part *m,
  46. grub_disk_addr_t *sector)
  47. {
  48. struct grub_acorn_boot_block boot;
  49. grub_err_t err;
  50. unsigned int checksum = 0;
  51. unsigned int heads;
  52. unsigned int sectors_per_cylinder;
  53. int i;
  54. err = grub_disk_read (disk, 0xC00 / GRUB_DISK_SECTOR_SIZE, 0,
  55. sizeof (struct grub_acorn_boot_block),
  56. &boot);
  57. if (err)
  58. return err;
  59. if ((boot.flags & NONADFS_PARTITION_TYPE_MASK) != NONADFS_PARTITION_TYPE_LINUX)
  60. goto fail;
  61. for (i = 0; i != 0x1ff; ++i)
  62. checksum = (checksum & 0xff) + (checksum >> 8) + boot.misc[i];
  63. if ((grub_uint8_t) checksum != boot.checksum)
  64. goto fail;
  65. heads = (boot.disc_record.heads
  66. + ((boot.disc_record.lowsector >> 6) & 1));
  67. sectors_per_cylinder = boot.disc_record.secspertrack * heads;
  68. *sector = grub_le_to_cpu16 (boot.start_cylinder) * sectors_per_cylinder;
  69. return grub_disk_read (disk, *sector, 0,
  70. sizeof (struct linux_part) * LINUX_MAP_ENTRIES,
  71. m);
  72. fail:
  73. return grub_error (GRUB_ERR_BAD_PART_TABLE,
  74. "Linux/ADFS partition map not found");
  75. }
  76. static grub_err_t
  77. acorn_partition_map_iterate (grub_disk_t disk,
  78. int (*hook) (grub_disk_t disk,
  79. const grub_partition_t partition,
  80. void *closure),
  81. void *closure)
  82. {
  83. struct grub_partition part;
  84. struct linux_part map[LINUX_MAP_ENTRIES];
  85. int i;
  86. grub_disk_addr_t sector = 0;
  87. grub_err_t err;
  88. err = acorn_partition_map_find (disk, map, &sector);
  89. if (err)
  90. return err;
  91. part.partmap = &grub_acorn_partition_map;
  92. for (i = 0; i != LINUX_MAP_ENTRIES; ++i)
  93. {
  94. if (map[i].magic != LINUX_NATIVE_MAGIC
  95. && map[i].magic != LINUX_SWAP_MAGIC)
  96. return GRUB_ERR_NONE;
  97. part.start = sector + map[i].start;
  98. part.len = map[i].size;
  99. part.offset = 6;
  100. part.number = part.index = i;
  101. if (hook (disk, &part, closure))
  102. return grub_errno;
  103. }
  104. return GRUB_ERR_NONE;
  105. }
  106. /* Partition map type. */
  107. static struct grub_partition_map grub_acorn_partition_map =
  108. {
  109. .name = "acorn",
  110. .iterate = acorn_partition_map_iterate,
  111. };
  112. GRUB_MOD_INIT(part_acorn)
  113. {
  114. grub_partition_map_register (&grub_acorn_partition_map);
  115. }
  116. GRUB_MOD_FINI(part_acorn)
  117. {
  118. grub_partition_map_unregister (&grub_acorn_partition_map);
  119. }