I have a "classic" bank-switched project using LX51 that needs to reserve some address ranges to prevent code from being assigned to those areas. I have a linker directive thus: RESERVE (0xf000-0xffff,0x1fff8-0x1ffff) yet the linker will happily locate code in the reserved addresses: 00EFF5H 00EFFDH 000009H BYTE UNIT CODE/B1 ?L?COM00F0 00EFFEH 00F00CH 00000FH BYTE UNIT CODE/B1 ?L?COM038F 00F00DH 00F015H 000009H BYTE UNIT CODE/B1 ?L?COM0290 00F016H 00F022H 00000DH BYTE UNIT CODE/B1 ?L?COM0298 00F023H 00F02FH 00000DH BYTE UNIT CODE/B1 ?L?COM030C 00F030H 00F03FH 000010H BYTE UNIT CODE/B1 ?L?COM0374 00F040H 00F049H 00000AH BYTE UNIT CODE/B1 ?L?COM04B5 00F04AH 00F051H 000008H BYTE UNIT CODE/B1 ?L?COM0574 I noticed on review of the manual that the description of the RESERVE directive just says "address ranges of the physical memory", but doesn't make a distinction between code and data space. Perhaps the correct thing to do is use CLASSES to limit the address map, e.g. CLASSES (CODE (0 - 0xf000, 0x10000 - 0x1fff8)) I have "Use Memory Layout from Target Dialog" checked, so the default CLASSES is XDATA (X:0x0-X:0x7FFF), HDATA (X:0x0-X:0x7FFF), CODE (C:0x0-C:0x7FFF), ECODE (C:0x0-C:0x7FFF), HCONST (C:0x0-C:0x7FFF)) I've found in the past that if CODE is allowed to grow beyond 0x7fff, then code that should be limited to the common bank (0 - 0x7fff) can be located in the high end of the bank area (0x8000 - 0xffff) if such space happens to be unused by the code for that bank. That layout is bugged, since there's no guarantee that the upper bank with necessary code will happen to be switched in. How do I keep the linker from placing code into certain address ranges?
You need to include the bank prefix with the addresses. For example,
LX51 ... RESERVE(B0:0X808000-B0:0X808FFF, B1:0X818000-B1:0X818FFF, C:0X200-C:0X2FF)
* * * * * * * * * * * C O D E M E M O R Y * * * * * * * * * * * * * *** CODE BANK 0 *** 808000H 808FFFH 001000H --- --- *** RESERVED MEMORY *** 009000H 00901BH 00001CH BYTE UNIT CODE/B0 ?PR?FUNC0?C_BANK0 *** CODE BANK 1 *** 818000H 818FFFH 001000H --- --- *** RESERVED MEMORY *** 009000H 00901BH 00001CH BYTE UNIT CODE/B1 ?PR?FUNC1?C_BANK1 *** CODE BANK 2 *** 008000H 008018H 000019H BYTE UNIT CODE/B2 ?PR?FUNC2?C_BANK2 *** COMMON AREA *** 000000H 000002H 000003H --- OFFS.. CODE ?CO??C_STARTUP?0 000003H 000063H 000061H BYTE INBLOCK CODE ?BANK?SELECT 000064H 0000F1H 00008EH BYTE UNIT CODE ?C?LIB_CODE 0000F2H 00017DH 00008CH BYTE UNIT CODE ?C_C51STARTUP 00017EH 0001E5H 000068H BYTE UNIT CODE ?CO?C_ROOT 0001E6H 0001EDH 000008H BYTE UNIT CODE ?C_INITSEG 0001EEH 0001FFH 000012H --- --- **GAP** 000200H 0002FFH 000100H --- --- *** RESERVED MEMORY *** 000300H 00065BH 00035CH BYTE UNIT CODE ?PR?PRINTF?PRINTF 00065CH 0006A1H 000046H BYTE UNIT CODE ?CO?C_BANK1 0006A2H 0006E7H 000046H BYTE UNIT CODE ?CO?C_BANK0
Thanks for the help on the syntax for RESERVE. Is the high order bit necessary? That is, RESERVE (B0:0x80f000-0x80ffff) rather than RESERVE (B0:0xf000-B0:0xffff)? If the ROM area that is dedicated as common area is not large enough to contain the entire common code, the linker duplicates the remaining part of the common code area into the beginning of each code bank. The behavior that I saw was the the high end of the bank area would contain common bank code. That is, common would range from 0 - 7fff, then there would be bank code from 8000 - e900 (say), and then there would be more common code from e900 up. This behavior was with the "Off-Chip Code Memory" in uVision set to 0 - 0xffff, which apparently translates to a CLASSES (CODE()) directive to the linker. Restricting the range to 0 - 0x7fff solves the problem. I assumed this was just misconfiguration on my part. (But maybe discrepancies between CODE and BANKAREA rate a warning?)
RESERVE (B0:0xf000-B0:0xffff) is just fine. Reinhard