lib.rs 27 KB

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