Fix and improve mkoverlay
This commit is contained in:
parent
204760b4bd
commit
0ede401ee4
|
@ -1,33 +1,27 @@
|
||||||
use super::super::types::{BootOverlaySection, OverlayDesc, OverlaySection, OverlaySlot};
|
use super::super::types::{OverlayDesc, OverlaySection};
|
||||||
use tool_helper::{Error, format_if_error, Output};
|
use tool_helper::{Error, format_if_error, Output};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
const OVERLAY_DEFAULT_START:&'static str = "__planschi_start"; // < will probably be "__boot_loader_start" later
|
const OVERLAY_DEFAULT_START:&'static str = "__planschi_start"; // < will probably be "__boot_loader_start" later
|
||||||
|
|
||||||
|
macro_rules! section_end_name_template {
|
||||||
|
() => {
|
||||||
|
"__{}_end"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> {
|
pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> {
|
||||||
fn create_heap_base(overlay_desc: &OverlayDesc) -> String {
|
fn create_heap_base(overlay_desc: &OverlayDesc) -> String {
|
||||||
let (first_entry,additional_slots_iter) = {
|
let (first_entry, additional_slots_iter) = (&overlay_desc[0].name, overlay_desc.iter().skip(1));
|
||||||
if overlay_desc.boot_section.is_empty() {
|
|
||||||
(&overlay_desc.additional_slots[0].name, overlay_desc.additional_slots.iter().skip(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
let mut heap_start = format!(concat!("MAX({}, ", section_end_name_template!(), ")"), OVERLAY_DEFAULT_START, first_entry);
|
||||||
(&overlay_desc.boot_section.name, overlay_desc.additional_slots.iter().skip(0))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut heap_start = format!("MAX({}, __{}_end)", OVERLAY_DEFAULT_START, first_entry);
|
|
||||||
for slot in additional_slots_iter {
|
for slot in additional_slots_iter {
|
||||||
heap_start = format!("MAX(__{}_end, {})", slot.name, heap_start);
|
heap_start = format!(concat!("MAX(", section_end_name_template!(), ", {})"), slot.name, heap_start);
|
||||||
}
|
}
|
||||||
heap_start
|
heap_start
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_slot_start_adr(slot: &OverlaySlot) -> &str {
|
if overlay_desc.is_empty() {
|
||||||
slot.start_adr.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
if overlay_desc.additional_slots.is_empty() && overlay_desc.boot_section.is_empty() {
|
|
||||||
write_heap_base(output, OVERLAY_DEFAULT_START)?;
|
write_heap_base(output, OVERLAY_DEFAULT_START)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,18 +29,21 @@ pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Erro
|
||||||
write_heap_base(output, &create_heap_base(&overlay_desc))?;
|
write_heap_base(output, &create_heap_base(&overlay_desc))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut slot_start_adr = format!(section_end_name_template!(), "bss");
|
||||||
|
|
||||||
writeln!(output, "")?;
|
writeln!(output, "")?;
|
||||||
writeln!(output, "SECTIONS {{")?;
|
writeln!(output, "SECTIONS {{")?;
|
||||||
writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?;
|
writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?;
|
||||||
write_first_section(output, &overlay_desc.boot_section)?;
|
for slot in overlay_desc {
|
||||||
for slot in &overlay_desc.additional_slots {
|
|
||||||
writeln!(output, "\t/*{}*/", slot.name)?;
|
writeln!(output, "\t/*{}*/", slot.name)?;
|
||||||
writeln!(output, "\tOVERLAY {} : NOCROSSREFS SUBALIGN(4) {{", get_slot_start_adr(slot))?;
|
writeln!(output, "\tOVERLAY {} : NOCROSSREFS SUBALIGN(4) {{", slot_start_adr)?;
|
||||||
write_section(output, &slot.sections, false)?;
|
write_section(output, &slot.sections, false)?;
|
||||||
writeln!(output, "\t}}")?;
|
writeln!(output, "\t}}")?;
|
||||||
writeln!(output, "\t. = ALIGN(4);")?;
|
writeln!(output, "\t. = ALIGN(4);")?;
|
||||||
writeln!(output, "\t__{}_end = .;", slot.name)?;
|
writeln!(output, concat!("\t", section_end_name_template!(), " = .;"), slot.name)?;
|
||||||
writeln!(output, "")?;
|
writeln!(output, "")?;
|
||||||
|
|
||||||
|
slot_start_adr = format!(section_end_name_template!(), slot.name);
|
||||||
}
|
}
|
||||||
writeln!(output, "}}")?;
|
writeln!(output, "}}")?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -57,18 +54,6 @@ fn write_heap_base(output: &mut Output, heap_base: &str) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_first_section(output: &mut Output, boot_overlay: &BootOverlaySection) -> Result<(), Error> {
|
|
||||||
writeln!(output, "\tOVERLAY __bss_end : NOCROSSREFS SUBALIGN(4) {{")?;
|
|
||||||
writeln!(output, "\t\t/*{}*/", boot_overlay.name)?;
|
|
||||||
write_section(output, &boot_overlay.sections, true)?;
|
|
||||||
writeln!(output, "\t}}")?;
|
|
||||||
writeln!(output, "\t. = ALIGN(4);")?;
|
|
||||||
writeln!(output, "\t__{}_end = .;", boot_overlay.name)?;
|
|
||||||
writeln!(output, "")?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_section(output: &mut Output, sections: &Vec<OverlaySection>, add_end_name: bool) -> Result<(), Error> {
|
fn write_section(output: &mut Output, sections: &Vec<OverlaySection>, add_end_name: bool) -> Result<(), Error> {
|
||||||
for section in sections {
|
for section in sections {
|
||||||
writeln!(output, "\t\t.{} {{", section.name)?;
|
writeln!(output, "\t\t.{} {{", section.name)?;
|
||||||
|
@ -83,7 +68,7 @@ fn write_section(output: &mut Output, sections: &Vec<OverlaySection>, add_end_na
|
||||||
}
|
}
|
||||||
|
|
||||||
if add_end_name {
|
if add_end_name {
|
||||||
writeln!(output, "\t\t\t__{}_end = .;", section.name)?;
|
writeln!(output, concat!("\t\t\t", section_end_name_template!(), " = .;"), section.name)?;
|
||||||
}
|
}
|
||||||
writeln!(output, "\t\t}}")?;
|
writeln!(output, "\t\t}}")?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,10 @@ use super::super::types::OverlayDesc;
|
||||||
use tool_helper::{Error, Output};
|
use tool_helper::{Error, Output};
|
||||||
|
|
||||||
pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> {
|
pub fn write(output: &mut Output, overlay_desc: &OverlayDesc) -> Result<(), Error> {
|
||||||
if !overlay_desc.boot_section.is_empty() || !overlay_desc.additional_slots.is_empty() {
|
if !overlay_desc.is_empty() {
|
||||||
write!(output, "OVERLAYSECTION = ")?;
|
write!(output, "OVERLAYSECTION = ")?;
|
||||||
|
|
||||||
for section in &overlay_desc.boot_section.sections {
|
for slot in overlay_desc {
|
||||||
write!(output, ".{} ", section.name)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for slot in &overlay_desc.additional_slots {
|
|
||||||
for section in &slot.sections {
|
for section in &slot.sections {
|
||||||
write!(output, ".{} ", section.name)?;
|
write!(output, ".{} ", section.name)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,13 @@
|
||||||
use super::{BootOverlaySection, OverlayDesc, OverlaySection, OverlaySlot};
|
use super::{OverlayDesc, OverlaySection, OverlaySlot};
|
||||||
use tool_helper::{Error, format_if_error, Input};
|
use tool_helper::{Error, format_if_error, Input};
|
||||||
|
|
||||||
const FOLLOW_KEYWORD:&'static str = "following";
|
|
||||||
|
|
||||||
pub fn read_config(input: Input) -> Result<OverlayDesc, Error> {
|
pub fn read_config(input: Input) -> Result<OverlayDesc, Error> {
|
||||||
let json_reader:serde_json::Value = format_if_error!(serde_json::from_reader(input), "Parsing JSON failed with: {error_text}")?;
|
let json_reader:serde_json::Value = format_if_error!(serde_json::from_reader(input), "Parsing JSON failed with: {error_text}")?;
|
||||||
let mut overlay_desc = OverlayDesc::new();
|
let mut overlay_desc = OverlayDesc::new();
|
||||||
|
|
||||||
if let Some(objects) = json_reader.as_object() {
|
if let Some(objects) = json_reader.as_object() {
|
||||||
for object in objects {
|
for object in objects {
|
||||||
let mut slot = read_as_slot(object)?;
|
overlay_desc.push(read_as_slot(object)?);
|
||||||
if overlay_desc.boot_section.is_empty() {
|
|
||||||
overlay_desc.boot_section = BootOverlaySection::new(slot.name, slot.sections);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
if let Some(prev_slot) = overlay_desc.additional_slots.last() {
|
|
||||||
slot.set_start_adr_as_end_of(prev_slot.name.as_ref());
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
slot.set_start_adr_as_end_of("bss");
|
|
||||||
}
|
|
||||||
overlay_desc.additional_slots.push(slot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(overlay_desc)
|
Ok(overlay_desc)
|
||||||
|
@ -36,25 +20,13 @@ pub fn read_config(input: Input) -> Result<OverlayDesc, Error> {
|
||||||
|
|
||||||
fn read_as_slot(json_value: (&String, &serde_json::Value)) -> Result<OverlaySlot, Error> {
|
fn read_as_slot(json_value: (&String, &serde_json::Value)) -> Result<OverlaySlot, Error> {
|
||||||
let (slot_name, json_value) = json_value;
|
let (slot_name, json_value) = json_value;
|
||||||
let mut slot = OverlaySlot::new(slot_name.clone(), "bss");
|
let mut slot = OverlaySlot::new(slot_name.clone());
|
||||||
|
|
||||||
if let Some(json_value) = json_value.as_object() {
|
if let Some(json_value) = json_value.as_object() {
|
||||||
for (name, json_value) in json_value {
|
for (name, json_value) in json_value {
|
||||||
if name == FOLLOW_KEYWORD {
|
|
||||||
if let Some(start_adr) = json_value.as_str() {
|
|
||||||
slot.set_start_adr_as_end_of(start_adr);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
return Err(Error::from_text(format!("\"{}\" option of {} must be a string", FOLLOW_KEYWORD, slot_name)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
slot.add_section(read_as_section(name.clone(), json_value)?);
|
slot.add_section(read_as_section(name.clone(), json_value)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(slot)
|
Ok(slot)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,19 @@
|
||||||
pub mod json_reader;
|
pub mod json_reader;
|
||||||
|
|
||||||
pub struct OverlayDesc {
|
pub type OverlayDesc = Vec<OverlaySlot>;
|
||||||
pub(super) boot_section: BootOverlaySection,
|
|
||||||
pub(super) additional_slots: Vec<OverlaySlot>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OverlayDesc {
|
pub struct OverlaySlot {
|
||||||
pub fn new() -> OverlayDesc {
|
|
||||||
OverlayDesc{boot_section: BootOverlaySection::default(), additional_slots: Vec::new()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BootOverlaySection {
|
|
||||||
pub(super) name: String,
|
pub(super) name: String,
|
||||||
pub(super) sections: Vec<OverlaySection>,
|
pub(super) sections: Vec<OverlaySection>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BootOverlaySection {
|
impl OverlaySlot {
|
||||||
pub fn new(name: String, sections: Vec<OverlaySection>) -> BootOverlaySection {
|
pub fn new(name: String) -> OverlaySlot {
|
||||||
BootOverlaySection{name, sections}
|
OverlaySlot{name, sections: Vec::new()}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn add_section(&mut self, section: OverlaySection) {
|
||||||
self.sections.is_empty()
|
self.sections.push(section);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::default::Default for BootOverlaySection {
|
|
||||||
fn default() -> Self {
|
|
||||||
BootOverlaySection{name: String::new(), sections: Vec::new()}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,23 +31,3 @@ impl OverlaySection {
|
||||||
self.file_pattern.push(file_pattern);
|
self.file_pattern.push(file_pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OverlaySlot {
|
|
||||||
pub(super) name: String,
|
|
||||||
pub(super) start_adr: String,
|
|
||||||
pub(super) sections: Vec<OverlaySection>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OverlaySlot {
|
|
||||||
pub fn new(name: String, start_adr: &str) -> OverlaySlot {
|
|
||||||
OverlaySlot{name, start_adr: String::from(start_adr), sections: Vec::new()}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_start_adr_as_end_of(&mut self, end: &str) {
|
|
||||||
self.start_adr = format!("__{}_end", end);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_section(&mut self, section: OverlaySection) {
|
|
||||||
self.sections.push(section);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue