lib.rs 26 KB

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