From be33d3a5156ea3fde221c9e174ad0405eb8d1f8d Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 18 Mar 2013 17:18:11 +0000 Subject: [PATCH] Update Mass Storage bootloader so that it can support devices with only 4KB bootloader sections by creating a special AUX section before the real bootloader section to store part of the bootloader code. --- Bootloaders/MassStorage/BootloaderAPITable.S | 13 ++++++ .../MassStorage/BootloaderMassStorage.c | 22 ++++++++-- .../MassStorage/BootloaderMassStorage.h | 17 ++++---- .../MassStorage/BootloaderMassStorage.txt | 36 ++++++++++++---- Bootloaders/MassStorage/Config/LUFAConfig.h | 2 +- Bootloaders/MassStorage/Descriptors.c | 42 +++++-------------- Bootloaders/MassStorage/Descriptors.h | 2 +- Bootloaders/MassStorage/Lib/SCSI.c | 31 +------------- Bootloaders/MassStorage/Lib/SCSI.h | 14 +++---- Bootloaders/MassStorage/Lib/VirtualFAT.c | 27 ++++++++---- Bootloaders/MassStorage/Lib/VirtualFAT.h | 14 ++++--- Bootloaders/MassStorage/makefile | 25 ++++++++--- 12 files changed, 136 insertions(+), 109 deletions(-) diff --git a/Bootloaders/MassStorage/BootloaderAPITable.S b/Bootloaders/MassStorage/BootloaderAPITable.S index 2aded74213..2d7610b582 100644 --- a/Bootloaders/MassStorage/BootloaderAPITable.S +++ b/Bootloaders/MassStorage/BootloaderAPITable.S @@ -28,6 +28,19 @@ this software. */ +#if AUX_BOOT_SECTION_SIZE > 0 + +#warning Using a AUX bootloader section in addition to the defined bootloader space (see documentation). + +; Trampoline to jump over the AUX bootloader section to the start of the bootloader, +; on devices where an AUX bootloader section is used. +.section .boot_aux_trampoline, "ax" +.global Boot_AUX_Trampoline +Boot_AUX_Trampoline: + jmp BOOT_START_ADDR + +#endif + ; Trampolines to actual API implementations if the target address is outside the ; range of a rjmp instruction (can happen with large bootloader sections) .section .apitable_trampolines, "ax" diff --git a/Bootloaders/MassStorage/BootloaderMassStorage.c b/Bootloaders/MassStorage/BootloaderMassStorage.c index 7adeaced7a..a5e953a5b0 100644 --- a/Bootloaders/MassStorage/BootloaderMassStorage.c +++ b/Bootloaders/MassStorage/BootloaderMassStorage.c @@ -61,6 +61,25 @@ USB_ClassInfo_MS_Device_t Disk_MS_Interface = }; +void Application_Jump_Check(void) +{ + bool JumpToApplication = false; + + #if (BOARD == BOARD_LEONARDO) + /* Enable pull-up on the IO13 pin so we can use it to select the mode */ + PORTC |= (1 << 7); + Delay_MS(10); + JumpToApplication |= ((PINC & (1 << 7)) != 0); + PORTC &= ~(1 << 7); + #endif + + if (JumpToApplication) + { + // cppcheck-suppress constStatement + ((void (*)(void))0x0000)(); + } +} + /** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ @@ -85,9 +104,6 @@ static void SetupHardware(void) MCUSR &= ~(1 << WDRF); wdt_disable(); - /* Disable clock division */ - clock_prescale_set(clock_div_1); - /* Relocate the interrupt vector table to the bootloader section */ MCUCR = (1 << IVCE); MCUCR = (1 << IVSEL); diff --git a/Bootloaders/MassStorage/BootloaderMassStorage.h b/Bootloaders/MassStorage/BootloaderMassStorage.h index b12cbafe57..dd67381f70 100644 --- a/Bootloaders/MassStorage/BootloaderMassStorage.h +++ b/Bootloaders/MassStorage/BootloaderMassStorage.h @@ -39,7 +39,6 @@ /* Includes: */ #include #include - #include #include #include @@ -67,14 +66,18 @@ #define LEDMASK_USB_BUSY LEDS_LED2 /* Function Prototypes: */ - static void SetupHardware(void); + int main(void) AUX_BOOT_SECTION; - void EVENT_USB_Device_Connect(void); - void EVENT_USB_Device_Disconnect(void); - void EVENT_USB_Device_ConfigurationChanged(void); - void EVENT_USB_Device_ControlRequest(void); + static void SetupHardware(void) AUX_BOOT_SECTION; - bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); + void Application_Jump_Check(void) ATTR_INIT_SECTION(3); + + void EVENT_USB_Device_Connect(void) AUX_BOOT_SECTION; + void EVENT_USB_Device_Disconnect(void) AUX_BOOT_SECTION; + void EVENT_USB_Device_ConfigurationChanged(void) AUX_BOOT_SECTION; + void EVENT_USB_Device_ControlRequest(void) AUX_BOOT_SECTION; + + bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; #endif diff --git a/Bootloaders/MassStorage/BootloaderMassStorage.txt b/Bootloaders/MassStorage/BootloaderMassStorage.txt index 7ca7c1f85e..19751d3be6 100644 --- a/Bootloaders/MassStorage/BootloaderMassStorage.txt +++ b/Bootloaders/MassStorage/BootloaderMassStorage.txt @@ -12,6 +12,8 @@ * * \li Series 7 USB AVRs (AT90USBxxx7) * \li Series 6 USB AVRs (AT90USBxxx6) + * \li Series 4 USB AVRs (ATMEGAxxU4) - See \ref SSec_Aux_Space + * \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2) - See \ref SSec_Aux_Space * * \section Sec_Info USB Information: * @@ -49,7 +51,7 @@ * firmware image file, to load firmware onto the AVR. * * Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit - * into 8KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to + * into 6KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to * edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile. * * When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the @@ -100,6 +102,22 @@ * #define BOOTLOADER_ADDRESS_LENGTH 4 * \endcode * + * From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address + * \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader + * can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them + * to the value \c BOOTLOADER_MASS_STORAGE_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes + * of FLASH memory starting from address \c BOOTLOADER_ADDRESS_START. + * + * \subsection SSec_Aux_Space Auxiliary Bootloader Section + * To make the bootloader function on smaller devices (those with a physical bootloader section of smaller than 6KB) a second + * section of memory (called the Auxiliary Bootloader Section) is added before the start of the real bootloader section, + * and is filled with a portion of the bootloader code. This allows smaller devices to run the bootloader, at the cost of an + * additional portion of the device's FLASH (the bootloader section size in KB subtracted from the 6KB total size). A small + * trampoline is inserted at the start of the auxiliary section so that the bootloader will run normally in the case of a blank + * application section. + * + * On devices supporting a 8KB bootloader section size, the AUX section is not created in the final binary. + * * \subsection SSec_API_MemLayout Device Memory Map * The following illustration indicates the final memory map of the device when loaded with the bootloader. * @@ -121,6 +139,16 @@ * | | * | | * | | + * | | + * +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE + * | Booloader Start Trampoline | + * | (Not User App. Accessible) | + * +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE + 4 + * | | + * | Auxiliary Bootloader | + * | Space for Smaller Devices | + * | (Not User App. Accessible) | + * | | * +----------------------------+ FLASHEND - BOOT_SECTION_SIZE * | | * | Bootloader Application | @@ -138,12 +166,6 @@ * +----------------------------+ FLASHEND * \endverbatim * - * Bootloaders reporting a device release revision number of 1.00 or greater are bootloader API enabled. From the application - * the API support of the bootloader can be detected by reading the FLASH memory bytes located at address \c BOOTLOADER_MAGIC_SIGNATURE_START - * and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader can be determined by reading the - * FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MASS_STORAGE_SIGNATURE. - * The start address of the bootloader can be retrieved by reading the bytes of FLASH memory starting from address \c BOOTLOADER_ADDRESS_START. - * * \section Sec_Options Project Options * * The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value. diff --git a/Bootloaders/MassStorage/Config/LUFAConfig.h b/Bootloaders/MassStorage/Config/LUFAConfig.h index b22e67fbd5..fcc3ea8199 100644 --- a/Bootloaders/MassStorage/Config/LUFAConfig.h +++ b/Bootloaders/MassStorage/Config/LUFAConfig.h @@ -69,7 +69,7 @@ #define USE_RAM_DESCRIPTORS // #define USE_FLASH_DESCRIPTORS // #define USE_EEPROM_DESCRIPTORS -// #define NO_INTERNAL_SERIAL + #define NO_INTERNAL_SERIAL #define FIXED_CONTROL_ENDPOINT_SIZE 8 #define DEVICE_STATE_AS_GPIOR 0 #define FIXED_NUM_CONFIGURATIONS 1 diff --git a/Bootloaders/MassStorage/Descriptors.c b/Bootloaders/MassStorage/Descriptors.c index 4de12075a4..cbc320f9c7 100644 --- a/Bootloaders/MassStorage/Descriptors.c +++ b/Bootloaders/MassStorage/Descriptors.c @@ -60,7 +60,7 @@ const USB_Descriptor_Device_t DeviceDescriptor = .ManufacturerStrIndex = NO_DESCRIPTOR, .ProductStrIndex = NO_DESCRIPTOR, - .SerialNumStrIndex = USE_INTERNAL_SERIAL, + .SerialNumStrIndex = NO_DESCRIPTOR, .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS }; @@ -124,17 +124,6 @@ const USB_Descriptor_Configuration_t ConfigurationDescriptor = } }; -/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests - * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate - * via the language ID table available at USB.org what languages the device supports for its string descriptors. - */ -const USB_Descriptor_String_t LanguageString = -{ - .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, - - .UnicodeString = {LANGUAGE_ID_ENG} -}; - /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" * documentation) by the application code so that the address and size of a requested descriptor can be given * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function @@ -145,30 +134,21 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void** const DescriptorAddress) { - const uint8_t DescriptorType = (wValue >> 8); - const uint8_t DescriptorNumber = (wValue & 0xFF); + const uint8_t DescriptorType = (wValue >> 8); const void* Address = NULL; uint16_t Size = NO_DESCRIPTOR; - switch (DescriptorType) + /* If/Else If chain compiles slightly smaller than a switch case */ + if (DescriptorType == DTYPE_Device) + { + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + } + else if (DescriptorType == DTYPE_Configuration) { - case DTYPE_Device: - Address = &DeviceDescriptor; - Size = sizeof(USB_Descriptor_Device_t); - break; - case DTYPE_Configuration: - Address = &ConfigurationDescriptor; - Size = sizeof(USB_Descriptor_Configuration_t); - break; - case DTYPE_String: - if (!(DescriptorNumber)) - { - Address = &LanguageString; - Size = pgm_read_byte(&LanguageString.Header.Size); - } - - break; + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); } *DescriptorAddress = Address; diff --git a/Bootloaders/MassStorage/Descriptors.h b/Bootloaders/MassStorage/Descriptors.h index 7261fabfa9..4460fdab31 100644 --- a/Bootloaders/MassStorage/Descriptors.h +++ b/Bootloaders/MassStorage/Descriptors.h @@ -70,7 +70,7 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, const void** const DescriptorAddress) - ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3) AUX_BOOT_SECTION; #endif diff --git a/Bootloaders/MassStorage/Lib/SCSI.c b/Bootloaders/MassStorage/Lib/SCSI.c index 154fe48857..0bb1c7aeeb 100644 --- a/Bootloaders/MassStorage/Lib/SCSI.c +++ b/Bootloaders/MassStorage/Lib/SCSI.c @@ -104,9 +104,6 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) case SCSI_CMD_READ_CAPACITY_10: CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo); break; - case SCSI_CMD_SEND_DIAGNOSTIC: - CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo); - break; case SCSI_CMD_WRITE_10: CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE); break; @@ -116,6 +113,7 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) case SCSI_CMD_MODE_SENSE_6: CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo); break; + case SCSI_CMD_SEND_DIAGNOSTIC: case SCSI_CMD_START_STOP_UNIT: case SCSI_CMD_TEST_UNIT_READY: case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: @@ -227,33 +225,6 @@ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInt return true; } -/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the - * board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is - * supported. - * - * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with - * - * \return Boolean true if the command completed successfully, false otherwise. - */ -static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) -{ - /* Check to see if the SELF TEST bit is not set */ - if (!(MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & (1 << 2))) - { - /* Only self-test supported - update SENSE key and fail the command */ - SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, - SCSI_ASENSE_INVALID_FIELD_IN_CDB, - SCSI_ASENSEQ_NO_QUALIFIER); - - return false; - } - - /* Succeed the command and update the bytes transferred counter */ - MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0; - - return true; -} - /** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address * and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual * reading and writing of the data. diff --git a/Bootloaders/MassStorage/Lib/SCSI.h b/Bootloaders/MassStorage/Lib/SCSI.h index 54914f5eb6..8eb817fa77 100644 --- a/Bootloaders/MassStorage/Lib/SCSI.h +++ b/Bootloaders/MassStorage/Lib/SCSI.h @@ -42,7 +42,6 @@ #include - #include "../BootloaderMassStorage.h" #include "../Descriptors.h" #include "VirtualFAT.h" @@ -69,16 +68,15 @@ #define DEVICE_TYPE_BLOCK 0x00 /* Function Prototypes: */ - bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); + bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; #if defined(INCLUDE_FROM_SCSI_C) - static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); - static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); - static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); - static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); + static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; + static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; + static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, - const bool IsDataRead); - static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo); + const bool IsDataRead) AUX_BOOT_SECTION; + static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION; #endif #endif diff --git a/Bootloaders/MassStorage/Lib/VirtualFAT.c b/Bootloaders/MassStorage/Lib/VirtualFAT.c index ee0107c1b1..41c661ed39 100644 --- a/Bootloaders/MassStorage/Lib/VirtualFAT.c +++ b/Bootloaders/MassStorage/Lib/VirtualFAT.c @@ -151,26 +151,28 @@ static void WriteVirtualBlock(const uint16_t BlockNumber) if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES)))) { + #if (FLASHEND > 0xFFFF) uint32_t WriteFlashAddress = (uint32_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; + #else + uint16_t WriteFlashAddress = (uint16_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; + #endif for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i += 2) { if ((WriteFlashAddress % SPM_PAGESIZE) == 0) { /* Erase the given FLASH page, ready to be programmed */ - boot_page_erase(WriteFlashAddress); - boot_spm_busy_wait(); + BootloaderAPI_ErasePage(WriteFlashAddress); } /* Write the next data word to the FLASH page */ - boot_page_fill(WriteFlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]); + BootloaderAPI_FillWord(WriteFlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]); WriteFlashAddress += 2; if ((WriteFlashAddress % SPM_PAGESIZE) == 0) { /* Write the filled FLASH page to memory */ - boot_page_write(WriteFlashAddress - SPM_PAGESIZE); - boot_spm_busy_wait(); + BootloaderAPI_WritePage(WriteFlashAddress - SPM_PAGESIZE); } } } @@ -219,10 +221,17 @@ static void ReadVirtualBlock(const uint16_t BlockNumber) default: /* Blocks 4 onwards: Data allocation section */ if ((BlockNumber >= 4) && (BlockNumber < (4 + FILE_SECTORS(FIRMWARE_FILE_SIZE_BYTES)))) { + #if (FLASHEND > 0xFFFF) uint32_t ReadFlashAddress = (uint32_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) BlockBuffer[i] = pgm_read_byte_far(ReadFlashAddress++); + #else + uint16_t ReadFlashAddress = (uint16_t)(BlockNumber - 4) * SECTOR_SIZE_BYTES; + + for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++) + BlockBuffer[i] = pgm_read_byte(ReadFlashAddress++); + #endif } break; @@ -237,8 +246,8 @@ static void ReadVirtualBlock(const uint16_t BlockNumber) * PC via the USB Mass Storage interface. * * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state - * \param[in] BlockAddress Data block starting address for the write sequence - * \param[in] TotalBlocks Number of blocks of data to write + * \param[in] BlockAddress Data block starting address for the write sequence + * \param[in] TotalBlocks Number of blocks of data to write */ void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, const uint32_t BlockAddress, @@ -256,8 +265,8 @@ void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, * to the host PC via the USB Mass Storage interface. * * \param[in] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state - * \param[in] BlockAddress Data block starting address for the read sequence - * \param[in] TotalBlocks Number of blocks of data to read + * \param[in] BlockAddress Data block starting address for the read sequence + * \param[in] TotalBlocks Number of blocks of data to read */ void VirtualFAT_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, const uint32_t BlockAddress, diff --git a/Bootloaders/MassStorage/Lib/VirtualFAT.h b/Bootloaders/MassStorage/Lib/VirtualFAT.h index 16b4b738d0..8019691dcd 100644 --- a/Bootloaders/MassStorage/Lib/VirtualFAT.h +++ b/Bootloaders/MassStorage/Lib/VirtualFAT.h @@ -37,9 +37,11 @@ #include + #include "../BootloaderAPI.h" + /* Macros: */ /** Size of the virtual FIRMWARE.BIN file in bytes. */ - #define FIRMWARE_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR)) + #define FIRMWARE_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR) - AUX_BOOT_SECTION_SIZE) /** Number of sectors that comprise a single logical disk cluster. */ #define SECTOR_PER_CLUSTER 4 @@ -144,16 +146,16 @@ #if defined(INCLUDE_FROM_VIRTUAL_FAT_C) static void UpdateFAT12ClusterEntry(uint8_t* const FATTable, const uint16_t Index, - const uint16_t ChainEntry); - static void WriteVirtualBlock(const uint16_t BlockNumber); - static void ReadVirtualBlock(const uint16_t BlockNumber); + const uint16_t ChainEntry) AUX_BOOT_SECTION; + static void WriteVirtualBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; + static void ReadVirtualBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION; #endif void VirtualFAT_WriteBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, const uint32_t BlockAddress, - uint16_t TotalBlocks); + uint16_t TotalBlocks) AUX_BOOT_SECTION; void VirtualFAT_ReadBlocks(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, const uint32_t BlockAddress, - uint16_t TotalBlocks); + uint16_t TotalBlocks) AUX_BOOT_SECTION; #endif diff --git a/Bootloaders/MassStorage/makefile b/Bootloaders/MassStorage/makefile index 68b26b1bd5..c23e62f197 100644 --- a/Bootloaders/MassStorage/makefile +++ b/Bootloaders/MassStorage/makefile @@ -27,20 +27,33 @@ LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAG # match the target's total FLASH size and the bootloader size set in the # device's fuses. FLASH_SIZE_KB = 128 -BOOT_SECTION_SIZE_KB = 8 +BOOT_SECTION_SIZE_KB = 4 # Bootloader address calculation formulas # Do not modify these macros, but rather modify the dependent values above. CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) ) BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 ) -BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - $(strip $(1)) ) +BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) ) # Bootloader linker section flags for relocating the API table sections to # known FLASH addresses - these should not normally be user-edited. -BOOT_SECTION_LD_FLAG = -Wl,--section-start=.apitable_$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=BootloaderAPI_$(strip $(2)) -BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, trampolines, Trampolines, 96) -BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, jumptable, JumpTable, 32) -BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, signatures, Signatures, 8) +BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2)) +BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96) +BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32) +BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8) + +# Check if the bootloader needs an AUX section, located before the real bootloader section to store some of the +# bootloader code. This is required for 32KB and smaller devices, where the actual bootloader is 6KB but the maximum +# bootloader section size is 4KB. The actual usable application space will be reduced by 6KB for these devices. +ifeq ($(BOOT_SECTION_SIZE_KB),8) + CC_FLAGS += -DAUX_BOOT_SECTION='' -DAUX_BOOT_SECTION_SIZE=0 +else + AUX_BOOT_SECTION_KB = (6 - $(BOOT_SECTION_SIZE_KB)) + + CC_FLAGS += -DAUX_BOOT_SECTION='__attribute__((section(".boot_aux")))' -DAUX_BOOT_SECTION_SIZE='($(AUX_BOOT_SECTION_KB) * 1024)' + LD_FLAGS += -Wl,--section-start=.boot_aux=$(call BOOT_SEC_OFFSET, (($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_KB)) * 1024 - 16)) + LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .boot_aux_trampoline, Boot_AUX_Trampoline, ($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_KB)) * 1024) +endif # Default target all: