lib.rs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. #![no_std]
  2. use core::fmt;
  3. use header::{Tag, TagIter};
  4. pub use boot_loader_name::BootLoaderNameTag;
  5. pub use elf_sections::{ElfSectionsTag, ElfSection, ElfSectionIter, ElfSectionType, ElfSectionFlags, StringTable};
  6. pub use elf_sections::{ELF_SECTION_WRITABLE, ELF_SECTION_ALLOCATED, ELF_SECTION_EXECUTABLE};
  7. pub use memory_map::{MemoryMapTag, MemoryArea, MemoryAreaIter};
  8. pub use module::{ModuleTag, ModuleIter};
  9. pub use command_line::CommandLineTag;
  10. #[macro_use]
  11. extern crate bitflags;
  12. mod header;
  13. mod boot_loader_name;
  14. mod elf_sections;
  15. mod memory_map;
  16. mod module;
  17. mod command_line;
  18. pub unsafe fn load(address: usize) -> &'static BootInformation {
  19. if !cfg!(test) {
  20. assert_eq!(0, address & 0b111);
  21. }
  22. let multiboot = &*(address as *const BootInformation);
  23. assert_eq!(0, multiboot.total_size & 0b111);
  24. assert!(multiboot.has_valid_end_tag());
  25. multiboot
  26. }
  27. #[repr(C)]
  28. pub struct BootInformation {
  29. pub total_size: u32,
  30. _reserved: u32,
  31. first_tag: Tag,
  32. }
  33. impl BootInformation {
  34. pub fn start_address(&self) -> usize {
  35. self as *const _ as usize
  36. }
  37. pub fn end_address(&self) -> usize {
  38. self.start_address() + self.total_size as usize
  39. }
  40. pub fn elf_sections_tag(&self) -> Option<&'static ElfSectionsTag> {
  41. self.get_tag(9).map(|tag| unsafe{&*(tag as *const Tag as *const ElfSectionsTag)})
  42. }
  43. pub fn memory_map_tag(&self) -> Option<&'static MemoryMapTag> {
  44. self.get_tag(6).map(|tag| unsafe{&*(tag as *const Tag as *const MemoryMapTag)})
  45. }
  46. pub fn module_tags(&self) -> ModuleIter {
  47. ModuleIter{ iter: self.tags() }
  48. }
  49. pub fn boot_loader_name_tag(&self) -> Option<&'static BootLoaderNameTag> {
  50. self.get_tag(2).map(|tag| unsafe{&*(tag as *const Tag as *const BootLoaderNameTag)})
  51. }
  52. pub fn command_line_tag(&self) -> Option<&'static CommandLineTag> {
  53. self.get_tag(1).map(|tag| unsafe{&*(tag as *const Tag as *const CommandLineTag)})
  54. }
  55. fn has_valid_end_tag(&self) -> bool {
  56. const END_TAG: Tag = Tag{typ:0, size:8};
  57. let self_ptr = self as *const _;
  58. let end_tag_addr = self_ptr as usize + (self.total_size - END_TAG.size) as usize;
  59. let end_tag = unsafe{&*(end_tag_addr as *const Tag)};
  60. end_tag.typ == END_TAG.typ && end_tag.size == END_TAG.size
  61. }
  62. fn get_tag(&self, typ: u32) -> Option<&'static Tag> {
  63. self.tags().find(|tag| tag.typ == typ)
  64. }
  65. fn tags(&self) -> TagIter {
  66. TagIter{current: &self.first_tag as *const _}
  67. }
  68. }
  69. impl fmt::Debug for BootInformation {
  70. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  71. writeln!(f, "multiboot information")?;
  72. writeln!(f, "S: {:#010X}, E: {:#010X}, L: {:#010X}",
  73. self.start_address(), self.end_address(), self.total_size)?;
  74. if let Some(boot_loader_name_tag) = self.boot_loader_name_tag() {
  75. writeln!(f, "boot loader name: {}", boot_loader_name_tag.name())?;
  76. }
  77. if let Some(command_line_tag) = self.command_line_tag() {
  78. writeln!(f, "command line: {}", command_line_tag.command_line())?;
  79. }
  80. if let Some(memory_map_tag) = self.memory_map_tag() {
  81. writeln!(f, "memory areas:")?;
  82. for area in memory_map_tag.memory_areas() {
  83. writeln!(f, " S: {:#010X}, E: {:#010X}, L: {:#010X}",
  84. area.base_addr, area.base_addr + area.length, area.length)?;
  85. }
  86. }
  87. if let Some(elf_sections_tag) = self.elf_sections_tag() {
  88. let string_table = elf_sections_tag.string_table();
  89. writeln!(f, "kernel sections:")?;
  90. for s in elf_sections_tag.sections() {
  91. writeln!(f, " name: {:15}, S: {:#08X}, E: {:#08X}, L: {:#08X}, F: {:#04X}",
  92. string_table.section_name(s), s.addr, s.addr + s.size, s.size, s.flags)?;
  93. }
  94. }
  95. writeln!(f, "module tags:")?;
  96. for mt in self.module_tags() {
  97. writeln!(f, " name: {:15}, S: {:#010X}, E: {:#010X}",
  98. mt.name(), mt.start_address(), mt.end_address())?;
  99. }
  100. Ok(())
  101. }
  102. }
  103. #[cfg(test)]
  104. mod tests {
  105. use super::load;
  106. #[test]
  107. fn no_tags() {
  108. let bytes: [u8; 16] = [
  109. 16, 0, 0, 0, // total_size
  110. 0, 0, 0, 0, // reserved
  111. 0, 0, 0, 0, // end tag type
  112. 8, 0, 0, 0, // end tag size
  113. ];
  114. let addr = bytes.as_ptr() as usize;
  115. let bi = unsafe { load(addr) };
  116. assert_eq!(addr, bi.start_address());
  117. assert_eq!(addr + bytes.len(), bi.end_address());
  118. assert_eq!(bytes.len(), bi.total_size as usize);
  119. assert!(bi.elf_sections_tag().is_none());
  120. assert!(bi.memory_map_tag().is_none());
  121. assert!(bi.module_tags().next().is_none());
  122. assert!(bi.boot_loader_name_tag().is_none());
  123. assert!(bi.command_line_tag().is_none());
  124. }
  125. #[test]
  126. #[should_panic]
  127. fn invalid_total_size() {
  128. let bytes: [u8; 15] = [
  129. 15, 0, 0, 0, // total_size
  130. 0, 0, 0, 0, // reserved
  131. 0, 0, 0, 0, // end tag type
  132. 8, 0, 0, // end tag size
  133. ];
  134. let addr = bytes.as_ptr() as usize;
  135. let bi = unsafe { load(addr) };
  136. assert_eq!(addr, bi.start_address());
  137. assert_eq!(addr + bytes.len(), bi.end_address());
  138. assert_eq!(bytes.len(), bi.total_size as usize);
  139. assert!(bi.elf_sections_tag().is_none());
  140. assert!(bi.memory_map_tag().is_none());
  141. assert!(bi.module_tags().next().is_none());
  142. assert!(bi.boot_loader_name_tag().is_none());
  143. assert!(bi.command_line_tag().is_none());
  144. }
  145. #[test]
  146. #[should_panic]
  147. fn invalid_end_tag() {
  148. let bytes: [u8; 16] = [
  149. 16, 0, 0, 0, // total_size
  150. 0, 0, 0, 0, // reserved
  151. 0, 0, 0, 0, // end tag type
  152. 9, 0, 0, 0, // end tag size
  153. ];
  154. let addr = bytes.as_ptr() as usize;
  155. let bi = unsafe { load(addr) };
  156. assert_eq!(addr, bi.start_address());
  157. assert_eq!(addr + bytes.len(), bi.end_address());
  158. assert_eq!(bytes.len(), bi.total_size as usize);
  159. assert!(bi.elf_sections_tag().is_none());
  160. assert!(bi.memory_map_tag().is_none());
  161. assert!(bi.module_tags().next().is_none());
  162. assert!(bi.boot_loader_name_tag().is_none());
  163. assert!(bi.command_line_tag().is_none());
  164. }
  165. #[test]
  166. fn name_tag() {
  167. let bytes: [u8; 32] = [
  168. 32, 0, 0, 0, // total_size
  169. 0, 0, 0, 0, // reserved
  170. 2, 0, 0, 0, // boot loader name tag type
  171. 13, 0, 0, 0, // boot loader name tag size
  172. 110, 97, 109, 101, // boot loader name 'name'
  173. 0, 0, 0, 0, // boot loader name null + padding
  174. 0, 0, 0, 0, // end tag type
  175. 8, 0, 0, 0, // end tag size
  176. ];
  177. let addr = bytes.as_ptr() as usize;
  178. let bi = unsafe { load(addr) };
  179. assert_eq!(addr, bi.start_address());
  180. assert_eq!(addr + bytes.len(), bi.end_address());
  181. assert_eq!(bytes.len(), bi.total_size as usize);
  182. assert!(bi.elf_sections_tag().is_none());
  183. assert!(bi.memory_map_tag().is_none());
  184. assert!(bi.module_tags().next().is_none());
  185. assert_eq!("name", bi.boot_loader_name_tag().unwrap().name());
  186. assert!(bi.command_line_tag().is_none());
  187. }
  188. #[test]
  189. fn grub2() {
  190. let mut bytes: [u8; 960] = [
  191. 192, 3, 0, 0, // total_size
  192. 0, 0, 0, 0, // reserved
  193. 1, 0, 0, 0, // boot command tag type
  194. 9, 0, 0, 0, // boot command tag size
  195. 0, 0, 0, 0, // boot command null + padding
  196. 0, 0, 0, 0, // boot command padding
  197. 2, 0, 0, 0, // boot loader name tag type
  198. 26, 0, 0, 0, // boot loader name tag size
  199. 71, 82, 85, 66, // boot loader name
  200. 32, 50, 46, 48, // boot loader name
  201. 50, 126, 98, 101, // boot loader name
  202. 116, 97, 51, 45, // boot loader name
  203. 53, 0, 0, 0, // boot loader name null + padding
  204. 0, 0, 0, 0, // boot loader name padding
  205. 10, 0, 0, 0, // APM tag type
  206. 28, 0, 0, 0, // APM tag size
  207. 2, 1, 0, 240, // APM version, cseg
  208. 207, 212, 0, 0, // APM offset
  209. 0, 240, 0, 240, // APM cseg_16, dseg
  210. 3, 0, 240, 255, // APM flags, cseg_len
  211. 240, 255, 240, 255, // APM cseg_16_len, dseg_len
  212. 0, 0, 0, 0, // APM padding
  213. 6, 0, 0, 0, // memory map tag type
  214. 160, 0, 0, 0, // memory map tag size
  215. 24, 0, 0, 0, // memory map entry_size
  216. 0, 0, 0, 0, // memory map entry_version
  217. 0, 0, 0, 0, // memory map entry 0 base_addr
  218. 0, 0, 0, 0, // memory map entry 0 base_addr
  219. 0, 252, 9, 0, // memory map entry 0 length
  220. 0, 0, 0, 0, // memory map entry 0 length
  221. 1, 0, 0, 0, // memory map entry 0 type
  222. 0, 0, 0, 0, // memory map entry 0 reserved
  223. 0, 252, 9, 0, // memory map entry 1 base_addr
  224. 0, 0, 0, 0, // memory map entry 1 base_addr
  225. 0, 4, 0, 0, // memory map entry 1 length
  226. 0, 0, 0, 0, // memory map entry 1 length
  227. 2, 0, 0, 0, // memory map entry 1 type
  228. 0, 0, 0, 0, // memory map entry 1 reserved
  229. 0, 0, 15, 0, // memory map entry 2 base_addr
  230. 0, 0, 0, 0, // memory map entry 2 base_addr
  231. 0, 0, 1, 0, // memory map entry 2 length
  232. 0, 0, 0, 0, // memory map entry 2 length
  233. 2, 0, 0, 0, // memory map entry 2 type
  234. 0, 0, 0, 0, // memory map entry 2 reserved
  235. 0, 0, 16, 0, // memory map entry 3 base_addr
  236. 0, 0, 0, 0, // memory map entry 3 base_addr
  237. 0, 0, 238, 7, // memory map entry 3 length
  238. 0, 0, 0, 0, // memory map entry 3 length
  239. 1, 0, 0, 0, // memory map entry 3 type
  240. 0, 0, 0, 0, // memory map entry 3 reserved
  241. 0, 0, 254, 7, // memory map entry 4 base_addr
  242. 0, 0, 0, 0, // memory map entry 4 base_addr
  243. 0, 0, 2, 0, // memory map entry 4 length
  244. 0, 0, 0, 0, // memory map entry 4 length
  245. 2, 0, 0, 0, // memory map entry 4 type
  246. 0, 0, 0, 0, // memory map entry 4 reserved
  247. 0, 0, 252, 255, // memory map entry 5 base_addr
  248. 0, 0, 0, 0, // memory map entry 5 base_addr
  249. 0, 0, 4, 0, // memory map entry 5 length
  250. 0, 0, 0, 0, // memory map entry 5 length
  251. 2, 0, 0, 0, // memory map entry 5 type
  252. 0, 0, 0, 0, // memory map entry 5 reserved
  253. 9, 0, 0, 0, // elf symbols tag type
  254. 84, 2, 0, 0, // elf symbols tag size
  255. 9, 0, 0, 0, // elf symbols num
  256. 64, 0, 0, 0, // elf symbols entsize
  257. 8, 0, 0, 0, // elf symbols shndx
  258. 0, 0, 0, 0, // elf symbols entry 0 name
  259. 0, 0, 0, 0, // elf symbols entry 0 type
  260. 0, 0, 0, 0, // elf symbols entry 0 flags
  261. 0, 0, 0, 0, // elf symbols entry 0 flags
  262. 0, 0, 0, 0, // elf symbols entry 0 addr
  263. 0, 0, 0, 0, // elf symbols entry 0 addr
  264. 0, 0, 0, 0, // elf symbols entry 0 offset
  265. 0, 0, 0, 0, // elf symbols entry 0 offset
  266. 0, 0, 0, 0, // elf symbols entry 0 size
  267. 0, 0, 0, 0, // elf symbols entry 0 size
  268. 0, 0, 0, 0, // elf symbols entry 0 link
  269. 0, 0, 0, 0, // elf symbols entry 0 info
  270. 0, 0, 0, 0, // elf symbols entry 0 addralign
  271. 0, 0, 0, 0, // elf symbols entry 0 addralign
  272. 0, 0, 0, 0, // elf symbols entry 0 entsize
  273. 0, 0, 0, 0, // elf symbols entry 0 entsize
  274. 27, 0, 0, 0, // elf symbols entry 1 name
  275. 1, 0, 0, 0, // elf symbols entry 1 type
  276. 2, 0, 0, 0, // elf symbols entry 1 flags
  277. 0, 0, 0, 0, // elf symbols entry 1 flags
  278. 0, 0, 16, 0, // elf symbols entry 1 addr
  279. 0, 128, 255, 255, // elf symbols entry 1 addr
  280. 0, 16, 0, 0, // elf symbols entry 1 offset
  281. 0, 0, 0, 0, // elf symbols entry 1 offset
  282. 0, 48, 0, 0, // elf symbols entry 1 size
  283. 0, 0, 0, 0, // elf symbols entry 1 size
  284. 0, 0, 0, 0, // elf symbols entry 1 link
  285. 0, 0, 0, 0, // elf symbols entry 1 info
  286. 16, 0, 0, 0, // elf symbols entry 1 addralign
  287. 0, 0, 0, 0, // elf symbols entry 1 addralign
  288. 0, 0, 0, 0, // elf symbols entry 1 entsize
  289. 0, 0, 0, 0, // elf symbols entry 1 entsize
  290. 35, 0, 0, 0, // elf symbols entry 2 name
  291. 1, 0, 0, 0, // elf symbols entry 2 type
  292. 6, 0, 0, 0, // elf symbols entry 2 flags
  293. 0, 0, 0, 0, // elf symbols entry 2 flags
  294. 0, 48, 16, 0, // elf symbols entry 2 addr
  295. 0, 128, 255, 255, // elf symbols entry 2 addr
  296. 0, 64, 0, 0, // elf symbols entry 2 offset
  297. 0, 0, 0, 0, // elf symbols entry 2 offset
  298. 0, 144, 0, 0, // elf symbols entry 2 size
  299. 0, 0, 0, 0, // elf symbols entry 2 size
  300. 0, 0, 0, 0, // elf symbols entry 2 link
  301. 0, 0, 0, 0, // elf symbols entry 2 info
  302. 16, 0, 0, 0, // elf symbols entry 2 addralign
  303. 0, 0, 0, 0, // elf symbols entry 2 addralign
  304. 0, 0, 0, 0, // elf symbols entry 2 entsize
  305. 0, 0, 0, 0, // elf symbols entry 2 entsize
  306. 41, 0, 0, 0, // elf symbols entry 3 name
  307. 1, 0, 0, 0, // elf symbols entry 3 type
  308. 3, 0, 0, 0, // elf symbols entry 3 flags
  309. 0, 0, 0, 0, // elf symbols entry 3 flags
  310. 0, 192, 16, 0, // elf symbols entry 3 addr
  311. 0, 128, 255, 255, // elf symbols entry 3 addr
  312. 0, 208, 0, 0, // elf symbols entry 3 offset
  313. 0, 0, 0, 0, // elf symbols entry 3 offset
  314. 0, 32, 0, 0, // elf symbols entry 3 size
  315. 0, 0, 0, 0, // elf symbols entry 3 size
  316. 0, 0, 0, 0, // elf symbols entry 3 link
  317. 0, 0, 0, 0, // elf symbols entry 3 info
  318. 8, 0, 0, 0, // elf symbols entry 3 addralign
  319. 0, 0, 0, 0, // elf symbols entry 3 addralign
  320. 0, 0, 0, 0, // elf symbols entry 3 entsize
  321. 0, 0, 0, 0, // elf symbols entry 3 entsize
  322. 47, 0, 0, 0, // elf symbols entry 4 name
  323. 8, 0, 0, 0, // elf symbols entry 4 type
  324. 3, 0, 0, 0, // elf symbols entry 4 flags
  325. 0, 0, 0, 0, // elf symbols entry 4 flags
  326. 0, 224, 16, 0, // elf symbols entry 4 addr
  327. 0, 128, 255, 255, // elf symbols entry 4 addr
  328. 0, 240, 0, 0, // elf symbols entry 4 offset
  329. 0, 0, 0, 0, // elf symbols entry 4 offset
  330. 0, 80, 0, 0, // elf symbols entry 4 size
  331. 0, 0, 0, 0, // elf symbols entry 4 size
  332. 0, 0, 0, 0, // elf symbols entry 4 link
  333. 0, 0, 0, 0, // elf symbols entry 4 info
  334. 0, 16, 0, 0, // elf symbols entry 4 addralign
  335. 0, 0, 0, 0, // elf symbols entry 4 addralign
  336. 0, 0, 0, 0, // elf symbols entry 4 entsize
  337. 0, 0, 0, 0, // elf symbols entry 4 entsize
  338. 52, 0, 0, 0, // elf symbols entry 5 name
  339. 1, 0, 0, 0, // elf symbols entry 5 type
  340. 3, 0, 0, 0, // elf symbols entry 5 flags
  341. 0, 0, 0, 0, // elf symbols entry 5 flags
  342. 0, 48, 17, 0, // elf symbols entry 5 addr
  343. 0, 128, 255, 255, // elf symbols entry 5 addr
  344. 0, 240, 0, 0, // elf symbols entry 5 offset
  345. 0, 0, 0, 0, // elf symbols entry 5 offset
  346. 0, 0, 0, 0, // elf symbols entry 5 size
  347. 0, 0, 0, 0, // elf symbols entry 5 size
  348. 0, 0, 0, 0, // elf symbols entry 5 link
  349. 0, 0, 0, 0, // elf symbols entry 5 info
  350. 1, 0, 0, 0, // elf symbols entry 5 addralign
  351. 0, 0, 0, 0, // elf symbols entry 5 addralign
  352. 0, 0, 0, 0, // elf symbols entry 5 entsize
  353. 0, 0, 0, 0, // elf symbols entry 5 entsize
  354. 1, 0, 0, 0, // elf symbols entry 6 name
  355. 2, 0, 0, 0, // elf symbols entry 6 type
  356. 0, 0, 0, 0, // elf symbols entry 6 flags
  357. 0, 0, 0, 0, // elf symbols entry 6 flags
  358. 0, 48, 17, 0, // elf symbols entry 6 addr
  359. 0, 0, 0, 0, // elf symbols entry 6 addr
  360. 0, 240, 0, 0, // elf symbols entry 6 offset
  361. 0, 0, 0, 0, // elf symbols entry 6 offset
  362. 224, 43, 0, 0, // elf symbols entry 6 size
  363. 0, 0, 0, 0, // elf symbols entry 6 size
  364. 7, 0, 0, 0, // elf symbols entry 6 link
  365. 102, 1, 0, 0, // elf symbols entry 6 info
  366. 8, 0, 0, 0, // elf symbols entry 6 addralign
  367. 0, 0, 0, 0, // elf symbols entry 6 addralign
  368. 24, 0, 0, 0, // elf symbols entry 6 entsize
  369. 0, 0, 0, 0, // elf symbols entry 6 entsize
  370. 9, 0, 0, 0, // elf symbols entry 7 name
  371. 3, 0, 0, 0, // elf symbols entry 7 type
  372. 0, 0, 0, 0, // elf symbols entry 7 flags
  373. 0, 0, 0, 0, // elf symbols entry 7 flags
  374. 224, 91, 17, 0, // elf symbols entry 7 addr
  375. 0, 0, 0, 0, // elf symbols entry 7 addr
  376. 224, 27, 1, 0, // elf symbols entry 7 offset
  377. 0, 0, 0, 0, // elf symbols entry 7 offset
  378. 145, 55, 0, 0, // elf symbols entry 7 size
  379. 0, 0, 0, 0, // elf symbols entry 7 size
  380. 0, 0, 0, 0, // elf symbols entry 7 link
  381. 0, 0, 0, 0, // elf symbols entry 7 info
  382. 1, 0, 0, 0, // elf symbols entry 7 addralign
  383. 0, 0, 0, 0, // elf symbols entry 7 addralign
  384. 0, 0, 0, 0, // elf symbols entry 7 entsize
  385. 0, 0, 0, 0, // elf symbols entry 7 entsize
  386. 17, 0, 0, 0, // elf symbols entry 8 name
  387. 3, 0, 0, 0, // elf symbols entry 8 type
  388. 0, 0, 0, 0, // elf symbols entry 8 flags
  389. 0, 0, 0, 0, // elf symbols entry 8 flags
  390. 113, 147, 17, 0, // elf symbols entry 8 addr
  391. 0, 0, 0, 0, // elf symbols entry 8 addr
  392. 113, 83, 1, 0, // elf symbols entry 8 offset
  393. 0, 0, 0, 0, // elf symbols entry 8 offset
  394. 65, 0, 0, 0, // elf symbols entry 8 size
  395. 0, 0, 0, 0, // elf symbols entry 8 size
  396. 0, 0, 0, 0, // elf symbols entry 8 link
  397. 0, 0, 0, 0, // elf symbols entry 8 info
  398. 1, 0, 0, 0, // elf symbols entry 8 addralign
  399. 0, 0, 0, 0, // elf symbols entry 8 addralign
  400. 0, 0, 0, 0, // elf symbols entry 8 entsize
  401. 0, 0, 0, 0, // elf symbols entry 8 entsize
  402. 0, 0, 0, 0, // elf symbols padding
  403. 4, 0, 0, 0, // basic memory tag type
  404. 16, 0, 0, 0, // basic memory tag size
  405. 127, 2, 0, 0, // basic memory mem_lower
  406. 128, 251, 1, 0, // basic memory mem_upper
  407. 5, 0, 0, 0, // BIOS boot device tag type
  408. 20, 0, 0, 0, // BIOS boot device tag size
  409. 224, 0, 0, 0, // BIOS boot device biosdev
  410. 255, 255, 255, 255, // BIOS boot device partition
  411. 255, 255, 255, 255, // BIOS boot device subpartition
  412. 0, 0, 0, 0, // BIOS boot device padding
  413. 8, 0, 0, 0, // framebuffer info tag type
  414. 32, 0, 0, 0, // framebuffer info tag size
  415. 0, 128, 11, 0, // framebuffer info framebuffer_addr
  416. 0, 0, 0, 0, // framebuffer info framebuffer_addr
  417. 160, 0, 0, 0, // framebuffer info framebuffer_pitch
  418. 80, 0, 0, 0, // framebuffer info framebuffer_width
  419. 25, 0, 0, 0, // framebuffer info framebuffer_height
  420. 16, 2, 0, 0, // framebuffer info framebuffer_[bpp,type], reserved, color_info
  421. 14, 0, 0, 0, // ACPI old tag type
  422. 28, 0, 0, 0, // ACPI old tag size
  423. 82, 83, 68, 32, // ACPI old
  424. 80, 84, 82, 32, // ACPI old
  425. 89, 66, 79, 67, // ACPI old
  426. 72, 83, 32, 0, // ACPI old
  427. 220, 24, 254, 7, // ACPI old
  428. 0, 0, 0, 0, // ACPI old padding
  429. 0, 0, 0, 0, // end tag type
  430. 8, 0, 0, 0, // end tag size
  431. ];
  432. let string_bytes: [u8; 65] = [
  433. 0, 46, 115, 121,
  434. 109, 116, 97, 98,
  435. 0, 46, 115, 116,
  436. 114, 116, 97, 98,
  437. 0, 46, 115, 104,
  438. 115, 116, 114, 116,
  439. 97, 98, 0, 46,
  440. 114, 111, 100, 97,
  441. 116, 97, 0, 46,
  442. 116, 101, 120, 116,
  443. 0, 46, 100, 97,
  444. 116, 97, 0, 46,
  445. 98, 115, 115, 0,
  446. 46, 100, 97, 116,
  447. 97, 46, 114, 101,
  448. 108, 46, 114, 111,
  449. 0,
  450. ];
  451. let string_addr = string_bytes.as_ptr() as u64;
  452. for i in 0..8 {
  453. bytes[796 + i] = (string_addr >> (i * 8)) as u8;
  454. }
  455. let addr = bytes.as_ptr() as usize;
  456. let bi = unsafe { load(addr) };
  457. assert_eq!(addr, bi.start_address());
  458. assert_eq!(addr + bytes.len(), bi.end_address());
  459. assert_eq!(bytes.len(), bi.total_size as usize);
  460. let es = bi.elf_sections_tag().unwrap();
  461. let st = es.string_table();
  462. assert_eq!(string_addr, st as *const _ as u64);
  463. let mut s = es.sections();
  464. let s1 = s.next().unwrap();
  465. assert_eq!(".rodata", st.section_name(s1));
  466. assert_eq!(0xFFFF_8000_0010_0000, s1.start_address());
  467. assert_eq!(0xFFFF_8000_0010_3000, s1.end_address());
  468. assert_eq!(0x0000_0000_0000_3000, s1.size);
  469. assert_eq!(2, s1.flags);
  470. let s2 = s.next().unwrap();
  471. assert_eq!(".text", st.section_name(s2));
  472. assert_eq!(0xFFFF_8000_0010_3000, s2.start_address());
  473. assert_eq!(0xFFFF_8000_0010_C000, s2.end_address());
  474. assert_eq!(0x0000_0000_0000_9000, s2.size);
  475. assert_eq!(6, s2.flags);
  476. let s3 = s.next().unwrap();
  477. assert_eq!(".data", st.section_name(s3));
  478. assert_eq!(0xFFFF_8000_0010_C000, s3.start_address());
  479. assert_eq!(0xFFFF_8000_0010_E000, s3.end_address());
  480. assert_eq!(0x0000_0000_0000_2000, s3.size);
  481. assert_eq!(3, s3.flags);
  482. let s4 = s.next().unwrap();
  483. assert_eq!(".bss", st.section_name(s4));
  484. assert_eq!(0xFFFF_8000_0010_E000, s4.start_address());
  485. assert_eq!(0xFFFF_8000_0011_3000, s4.end_address());
  486. assert_eq!(0x0000_0000_0000_5000, s4.size);
  487. assert_eq!(3, s4.flags);
  488. let s5 = s.next().unwrap();
  489. assert_eq!(".data.rel.ro", st.section_name(s5));
  490. assert_eq!(0xFFFF_8000_0011_3000, s5.start_address());
  491. assert_eq!(0xFFFF_8000_0011_3000, s5.end_address());
  492. assert_eq!(0x0000_0000_0000_0000, s5.size);
  493. assert_eq!(3, s5.flags);
  494. let s6 = s.next().unwrap();
  495. assert_eq!(".symtab", st.section_name(s6));
  496. assert_eq!(0x0000_0000_0011_3000, s6.start_address());
  497. assert_eq!(0x0000_0000_0011_5BE0, s6.end_address());
  498. assert_eq!(0x0000_0000_0000_2BE0, s6.size);
  499. assert_eq!(0, s6.flags);
  500. let s7 = s.next().unwrap();
  501. assert_eq!(".strtab", st.section_name(s7));
  502. assert_eq!(0x0000_0000_0011_5BE0, s7.start_address());
  503. assert_eq!(0x0000_0000_0011_9371, s7.end_address());
  504. assert_eq!(0x0000_0000_0000_3791, s7.size);
  505. assert_eq!(0, s7.flags);
  506. assert!(s.next().is_none());
  507. let mut mm = bi.memory_map_tag().unwrap().memory_areas();
  508. let mm1 = mm.next().unwrap();
  509. assert_eq!(0x00000000, mm1.base_addr);
  510. assert_eq!(0x009_FC00, mm1.length);
  511. let mm2 = mm.next().unwrap();
  512. assert_eq!(0x010_0000, mm2.base_addr);
  513. assert_eq!(0x7EE_0000, mm2.length);
  514. assert!(mm.next().is_none());
  515. assert!(bi.module_tags().next().is_none());
  516. assert_eq!("GRUB 2.02~beta3-5", bi.boot_loader_name_tag().unwrap().name());
  517. assert_eq!("", bi.command_line_tag().unwrap().command_line());
  518. }
  519. }