mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-30 21:02:32 +01:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									f8a1dc7424
								
							
						
					
					
						commit
						be33d3a515
					
				| @ -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" | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -39,7 +39,6 @@ | ||||
| 	/* Includes: */ | ||||
| 		#include <avr/io.h> | ||||
| 		#include <avr/wdt.h> | ||||
| 		#include <avr/power.h> | ||||
| 		#include <avr/interrupt.h> | ||||
| 		#include <string.h> | ||||
| 
 | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -12,6 +12,8 @@ | ||||
|  * | ||||
|  *  \li Series 7 USB AVRs (AT90USBxxx7) | ||||
|  *  \li Series 6 USB AVRs (AT90USBxxx6) | ||||
|  *  \li Series 4 USB AVRs (ATMEGAxxU4) - <i>See \ref SSec_Aux_Space</i> | ||||
|  *  \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2) - <i>See \ref SSec_Aux_Space</i> | ||||
|  * | ||||
|  *  \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 <i>Auxiliary Bootloader Section</i>) 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. | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
| @ -146,29 +135,20 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, | ||||
|                                     const void** const DescriptorAddress) | ||||
| { | ||||
| 	const uint8_t DescriptorType = (wValue >> 8); | ||||
| 	const uint8_t  DescriptorNumber = (wValue & 0xFF); | ||||
| 
 | ||||
| 	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) | ||||
| 	{ | ||||
| 		case DTYPE_Device: | ||||
| 		Address = &DeviceDescriptor; | ||||
| 		Size    = sizeof(USB_Descriptor_Device_t); | ||||
| 			break; | ||||
| 		case DTYPE_Configuration: | ||||
| 	} | ||||
| 	else if (DescriptorType == 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; | ||||
| 	} | ||||
| 
 | ||||
| 	*DescriptorAddress = Address; | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
| @ -42,7 +42,6 @@ | ||||
| 
 | ||||
| 		#include <LUFA/Drivers/USB/USB.h> | ||||
| 
 | ||||
| 		#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 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -37,9 +37,11 @@ | ||||
| 
 | ||||
| 		#include <LUFA/Drivers/USB/USB.h> | ||||
| 
 | ||||
| 		#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 | ||||
|  | ||||
| @ -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: | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dean Camera
						Dean Camera