Fix and improve mkoverlay

This commit is contained in:
Jaby 2023-01-24 22:12:37 +01:00 committed by Jaby
parent 6710fc825a
commit 5bc0b375c5
4 changed files with 35 additions and 117 deletions

View File

@ -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 std::io::Write;
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> {
fn create_heap_base(overlay_desc: &OverlayDesc) -> String {
let (first_entry,additional_slots_iter) = {
if overlay_desc.boot_section.is_empty() {
(&overlay_desc.additional_slots[0].name, overlay_desc.additional_slots.iter().skip(1))
}
let (first_entry, additional_slots_iter) = (&overlay_desc[0].name, overlay_desc.iter().skip(1));
else {
(&overlay_desc.boot_section.name, overlay_desc.additional_slots.iter().skip(0))
}
};
let mut heap_start = format!("MAX({}, __{}_end)", OVERLAY_DEFAULT_START, first_entry);
let mut heap_start = format!(concat!("MAX({}, ", section_end_name_template!(), ")"), OVERLAY_DEFAULT_START, first_entry);
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
}
fn get_slot_start_adr(slot: &OverlaySlot) -> &str {
slot.start_adr.as_ref()
}
if overlay_desc.additional_slots.is_empty() && overlay_desc.boot_section.is_empty() {
if overlay_desc.is_empty() {
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))?;
}
let mut slot_start_adr = format!(section_end_name_template!(), "bss");
writeln!(output, "")?;
writeln!(output, "SECTIONS {{")?;
writeln!(output, "\t/DISCARD/ : {{ *(.comment*) *(.gnu.*) *(.mdebug*) *(.debug_*) *(.pdr)}}")?;
write_first_section(output, &overlay_desc.boot_section)?;
for slot in &overlay_desc.additional_slots {
for slot in overlay_desc {
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)?;
writeln!(output, "\t}}")?;
writeln!(output, "\t. = ALIGN(4);")?;
writeln!(output, "\t__{}_end = .;", slot.name)?;
writeln!(output, concat!("\t", section_end_name_template!(), " = .;"), slot.name)?;
writeln!(output, "")?;
slot_start_adr = format!(section_end_name_template!(), slot.name);
}
writeln!(output, "}}")?;
return Ok(());
@ -57,18 +54,6 @@ fn write_heap_base(output: &mut Output, heap_base: &str) -> Result<(), Error> {
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> {
for section in sections {
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 {
writeln!(output, "\t\t\t__{}_end = .;", section.name)?;
writeln!(output, concat!("\t\t\t", section_end_name_template!(), " = .;"), section.name)?;
}
writeln!(output, "\t\t}}")?;
}

View File

@ -2,14 +2,10 @@ use super::super::types::OverlayDesc;
use tool_helper::{Error, Output};
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 = ")?;
for section in &overlay_desc.boot_section.sections {
write!(output, ".{} ", section.name)?;
}
for slot in &overlay_desc.additional_slots {
for slot in overlay_desc {
for section in &slot.sections {
write!(output, ".{} ", section.name)?;
}

View File

@ -1,29 +1,13 @@
use super::{BootOverlaySection, OverlayDesc, OverlaySection, OverlaySlot};
use super::{OverlayDesc, OverlaySection, OverlaySlot};
use tool_helper::{Error, format_if_error, Input};
const FOLLOW_KEYWORD:&'static str = "following";
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 mut overlay_desc = OverlayDesc::new();
if let Some(objects) = json_reader.as_object() {
for object in objects {
let mut slot = 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);
}
overlay_desc.push(read_as_slot(object)?);
}
Ok(overlay_desc)
@ -36,23 +20,11 @@ pub fn read_config(input: Input) -> Result<OverlayDesc, Error> {
fn read_as_slot(json_value: (&String, &serde_json::Value)) -> Result<OverlaySlot, Error> {
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() {
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)?);
}
}

View File

@ -1,34 +1,19 @@
pub mod json_reader;
pub struct OverlayDesc {
pub(super) boot_section: BootOverlaySection,
pub(super) additional_slots: Vec<OverlaySlot>
pub type OverlayDesc = Vec<OverlaySlot>;
pub struct OverlaySlot {
pub(super) name: String,
pub(super) sections: Vec<OverlaySection>
}
impl OverlayDesc {
pub fn new() -> OverlayDesc {
OverlayDesc{boot_section: BootOverlaySection::default(), additional_slots: Vec::new()}
}
}
pub struct BootOverlaySection {
pub(super) name: String,
pub(super) sections: Vec<OverlaySection>,
}
impl BootOverlaySection {
pub fn new(name: String, sections: Vec<OverlaySection>) -> BootOverlaySection {
BootOverlaySection{name, sections}
impl OverlaySlot {
pub fn new(name: String) -> OverlaySlot {
OverlaySlot{name, sections: Vec::new()}
}
pub fn is_empty(&self) -> bool {
self.sections.is_empty()
}
}
impl std::default::Default for BootOverlaySection {
fn default() -> Self {
BootOverlaySection{name: String::new(), sections: Vec::new()}
pub fn add_section(&mut self, section: OverlaySection) {
self.sections.push(section);
}
}
@ -46,23 +31,3 @@ impl OverlaySection {
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);
}
}