# Copyright 2008 Castle Technology Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Document Status --------------- Distribution: Company Confidential Title: Makefile migration (aasm -> objasm) Drawing Number: 2503,105/T Issue: 1 Author(s): Stewart Brodie Date: 2001-04-11 Change Number: N/A Last Issue: 1 Contents -------- Document Status Issue History Introduction Changes Makefile Assembler Issue History ------------- 1 11/04/01 Original version Introduction ------------ This document describes, in outline, the changes that must be made to RISC OS components currently built with aasm to permit them to build using the shared makefiles and objasm. It assumes that the reader has some knowledge of the RISC OS system and ARM assembler. THIS IS NOT A REVIEWED DOCUMENT - MERELY NOTES TO PROGRAMMERS WHO NEED THE BENEFIT OF OUR PRIOR EXPERIENCES. Because of this, not all the technical terms are explained fully, and there is no glossary. Changes ------- The key features are: * Avoid duplication by using shared rules in AAsmModule makefile fragment * Avoid conflicts with build system macros by only defining them to be the same as srcbuild defines them. * Permit building with objasm, to permit cross-compilation (no sources to aasm and no Solaris version) AAsm also does not support the full ARM instruction set as required by lots of our assembler source code nowadays either, instead requiring complex macros to encode various instructions like MRS and MSR. ======== Makefile ======== In the best cases, the makefile can be just three lines: COMPONENT = ...component name... include StdTools include AAsmModule In practice, this is only possible for modules which have resources (e.g. messages files), have TARGET the same as COMPONENT, export no headers and do not require exotic switches to objasm/link. COMPONENT and TARGET should be set based on the first and fifth fields of the module's entry in the ModuleDB file. If TARGET is the same as COMPONENT (as is the case for many components), then TARGET need not be defined - AAsmModule will default it to whatever COMPONENT is. A lot of the information in this section is informational. You should be aware of it, but most will be irrelevant for many modules. AAsmModule ---------- The AAsmModule makefile fragment (look at it) defines an awful lot of rules and macros. Many of them are there to be useful defaults. In most cases, rules are defined using double-colon notation to permit you to add extra commands to be executed for those cases. This could be useful for rules such as "clean", where you want AAsmModule to clean all the standard stuff that it has created, but you need to do some extra cleaning. The top-level makefile can just say: clean:: ${RM} myotherfile and this will be executed IN ADDITION to the ones in AAsmModule. [Note that if you use macros defined by StdTools, such as RM in this example, you need to put these rules at the end of the file after the two includes.] It is assumed that the reader has a copy of the AAsmModule makefile fragment available (from RiscOS.BuildSys.Makefiles) for reference. Not all the macro definitions are going to be explained - work the details out for yourself. Clean ----- See previous section. clean does *not* remove the rm directory. Use a supplementary rule to remove it if you need to get rid of it (most don't want this). Resources --------- If the component has resources that are in the standard form (Resources..Messages), then no action need be taken - AAsmModule will handle this for you. It will also handle appending of CmdHelp files containing the syntax and help messages for *-commands in the module - it looks for LocalRes:CmdHelp. Some modules have called this file Syntax and have it in the root of the component. If this is the case, copy it into Resources.UK as CmdHelp and cvs add it, cvs remove the original file in the root. AAsmModule provides the "resources" rule invoked by srcbuild to export resources. If you want to prevent AAsmModule's rule from being invoked, you must define the macro RESOURCES to a non-empty value. AAsmModule defines a rule for "resources${RESOURCES}", so by setting RESOURCES, you change the rule that it is defining, thus allowing you to substitute your own resources rule. It is suggested that the value be set to something like "-private". If there are no resources, simply define RESOURCES as "no". AAsmModule will then provide a rule that echos a message saying that there are no resources for this component during builds. Supplementing the resources rule may actually be more worthwhile in many cases. You can supplement resources_common, resources-, resources-None or resources. This scheme works by allowing srcbuild to set CMDHELP=None on the make command line to avoid getting the syntax and help messages in the Messages file. The 'resources' rules provided assume that the ResourceFS target directory for any messages is Resources.${TARGET}. If it is not this, then you must set the macro RESFSDIR to be the target directory. You can use the macro RESDIR in your definition (it will point to the Resources directory - hence the default of ${RESDIR}.${TARGET}). Export ------ AAsmModule can export headers automatically. There are three classes of header file: assembler, C and assembler that needs translating into C. To export headers, place these macro definitions before the inclusion of the sub-makefiles. assembler: "HEADER1=leafname" This copies hdr.leafname to ${EXP_HDR}.leafname (which should mean Export..Hdr.Interface) C: "CHEADER1=lefaname" This copies h.leafname to ${C_EXP_HDR}.leafname (which should mean Export..C.Interface.h.leafname) assembler->C: "ASMCHEADER1=leafname" This runs the Hdr2H script on hdr.leafname to generate ${C_EXP_HDR}.leafname. Each of the three methods supports up to three header files (HEADER1, HEADER2, HEADER3; CHEADER1, .. etc.) ROM / Standalone / Debug ------------------------ The 'rom' rule assembles the module destined for ROM. The 'standalone' rule assembles the module destined for softload (or extension ROM or expansion card). The (logical) assembler macro 'standalone' is initialised to true, and the string macro MergedMsgs is set to the filename of the messages file to be embedded in the module The 'debug' rule assembles a standalone module with debugging enabled (the (logical) assembler macro 'debugging' is initialised to true) NOTE: Not all modules support standalone - they never have their resources embedded in them. Even fewer support debugging. The single source file is assumed to be "s.${TARGET}", but if this is not the case, then you must supply a macro definition ROM_SOURCE which is the name of the source file. Use the UNIX notation for the filename "leafname.s" rather than "s.leafname". The output object file is ROM_OBJECT, SA_OBJECT, DBG_OBJECT for rom, standalone & debug targets respectively. These are all defaulted. The final built image is ROM_MODULE, SA_MODULE & DBG_MODULE for rom, standalone & debug targets respectively. These are all defaulted. install_rom ----------- This rule copies ROM_TARGET to ${INSTDIR}.${TARGET}. This is correct and should not be changed. Tokenisation ------------ Some components run the tokenise tool to tokenise their help messages. This is automated by AAsmModule, but you must supply two macro definitions to enable it: TOKHELPSRC = ${TOKENSOURCE} HELPSRC = untokenised file The former is required (exactly as shown) to ensure that the object files are declared to be dependent on the tokenised message source file; the latter indicates the file containing the untokenised messages that are to be tokenised. TOKENSOURCE itself is defaulted (to s.TokHelpSrc). ${TOKENSOURCE} is DELETED during the default clean phase. ========= Assembler ========= Once the Makefile has been redesigned, attention should turn to the source files. It may be easier to simply attempt builds of the module and let objasm report all the things it doesn't like. However, you should read through this list first to help you recognise the things that get thrown up. Some errors (like the LEADR one) will require fixing before the others become apparent, so the process will be iterative. LEADR ----- This line will be faulted by objasm - delete it. Replace it with an AREA declaration. It is suggested that something like: AREA |modulename$$Code|, CODE, READONLY, PIC is suitable. You won't get very far until you fix this one. If you start getting errors about declarations not inside areas, you need to move the AREA declaration closer to the start of the file (maybe into ${ROM_SOURCE} itself) GET/LNK ------- The single source file (ROM_SOURCE - see above) may have a whole string of GET instructions to pull in all the component's source files (assuming there is more than 1!) or it may GET or LNK to one other and each source file will simply GET/LNK the next one at the end. You should change all of these local GET/LNKs to use UNIX-style notation (Foo.s, instead of s.Foo). Although this isn't faulted, it will aid the cross-compilation effort later on. MRS/MSR ------- aasm did not support the MRS and MSR instructions, so macros mrs and msr were developed to permit this instruction to be encoded by aasm-based modules. These must be converted to the upper-case forms to avoid clashes with the macros, plus the condition code (if any) needs to be appended to the opcode e.g. mrs ,r9,CPSR --> MRS r9, CPSR mrs NE,r8,SPSR --> MRSNE r8, SPSR Note the potentially empty field in the macro usage for holding the condition code, hence the odd looking comma before the register number. ORG --- This is not permitted for relocatable code - it should not be there. If you find this in a component, either stop fiddling with the kernel or ASK A GURU. ResourceFile ------------ This is a macro which is usually used in standalone builds to define a ResourceFS-compatible data block for an embedded messages file. However, instead of naming Resources..Messages or LocalRes:Messages as the file to embed, it needs to simply use $MergedMsgs instead. The Makefile sets this when building 'standalone' or 'debug' modules to the name of the merged messages+cmdhelp file. standalone / Standalone / other options --------------------------------------- Many modules have the capability to build standalone modules (ie. with their resources bundled in, code to handle ResourceFS (de|re)registration etc., but not always based on the symbol name 'standalone'. It is suggested that you insert the following change (shown by example of a module that uses the macro 'resources' to determine its build type) GBLL resources resources SETL {FALSE} ; {TRUE} to include resources ... changes to ... GBLL resources [ :DEF: standalone resources SETL standalone | resources SETL {FALSE} ; {TRUE} to include resources ] Although this may seem complex, it does simplify non-build system builds (ie. by using !Mk as it does not rely on standalone being set by the !Mk script) It is recommended that you not bother adding standalone capability to modules that do not already have it. ENTRY ===== These must be converted to Entry, as ENTRY is a reserved word in objasm. Be wary of doing a global search & replace, because you don't want to change any occurrence of ALTENTRY. \ = Backslashes were not special characters in aasm, but they are the escape character in objasm. You will need to double any \ characters: TEQ r0, "\" --> TEQ r0, "\\". Also watch out for \ at the end of comments. Since these are usually part of ASCII art, usually a suitable replacement character can be substituted (+ can be a good choice). Non-aligned instructions ======================== AAsm would automatically align the program counter to the next word boundary before generating code after inlined data. objasm requires an explicit ALIGN after such data: helpstring DCB "MyModule", TAB, "$Module_HelpVersion", 0 mycode MOV r0, #0 If the data at helpstring is not an exact multipe of 4, then you will get an error about mycode being non-aligned. Simply insert an ALIGN directive before the mycode definition. helpstring DCB "MyModule", TAB, "$Module_HelpVersion", 0 ALIGN mycode MOV r0, #0 ==END==