[444] | 1 | \input texinfo @c -*- Texinfo -*- |
---|
| 2 | @setfilename porting.info |
---|
| 3 | @settitle Embed with GNU |
---|
| 4 | |
---|
| 5 | @c |
---|
| 6 | @c This file documents the process of porting the GNU tools to an |
---|
| 7 | @c embedded environment. |
---|
| 8 | @c |
---|
| 9 | |
---|
| 10 | @finalout |
---|
| 11 | @setchapternewpage off |
---|
| 12 | @iftex |
---|
| 13 | @raggedbottom |
---|
| 14 | @global@parindent=0pt |
---|
| 15 | @end iftex |
---|
| 16 | |
---|
| 17 | @titlepage |
---|
| 18 | @title Embed With GNU |
---|
| 19 | @subtitle Porting The GNU Tools To Embedded Systems |
---|
| 20 | @sp 4 |
---|
| 21 | @subtitle Spring 1995 |
---|
| 22 | @subtitle Very *Rough* Draft |
---|
| 23 | @author Rob Savoye - Cygnus Support |
---|
| 24 | @page |
---|
| 25 | |
---|
| 26 | @vskip 0pt plus 1filll |
---|
| 27 | Copyright @copyright{} 1993, 1994, 1995 Cygnus Support |
---|
| 28 | |
---|
| 29 | Permission is granted to make and distribute verbatim copies of |
---|
| 30 | this manual provided the copyright notice and this permission notice |
---|
| 31 | are preserved on all copies. |
---|
| 32 | |
---|
| 33 | Permission is granted to copy and distribute modified versions of this |
---|
| 34 | manual under the conditions for verbatim copying, provided also that |
---|
| 35 | the entire resulting derived work is distributed under the terms of a |
---|
| 36 | permission notice identical to this one. |
---|
| 37 | |
---|
| 38 | Permission is granted to copy and distribute translations of this manual |
---|
| 39 | into another language, under the above conditions for modified versions. |
---|
| 40 | @end titlepage |
---|
| 41 | |
---|
| 42 | @ifnottex |
---|
| 43 | @format |
---|
| 44 | START-INFO-DIR-ENTRY |
---|
| 45 | * Embed with GNU: (porting-). Embed with GNU |
---|
| 46 | END-INFO-DIR-ENTRY |
---|
| 47 | @end format |
---|
| 48 | Copyright (c) 1993, 1994, 1995 Cygnus Support |
---|
| 49 | |
---|
| 50 | Permission is granted to make and distribute verbatim copies of |
---|
| 51 | this manual provided the copyright notice and this permission notice |
---|
| 52 | are preserved on all copies. |
---|
| 53 | |
---|
| 54 | Permission is granted to copy and distribute modified versions of this |
---|
| 55 | manual under the conditions for verbatim copying, provided also that |
---|
| 56 | the entire resulting derived work is distributed under the terms of a |
---|
| 57 | permission notice identical to this one. |
---|
| 58 | |
---|
| 59 | Permission is granted to copy and distribute translations of this manual |
---|
| 60 | into another language, under the above conditions for modified versions. |
---|
| 61 | |
---|
| 62 | @node Top |
---|
| 63 | @top Embed with GNU |
---|
| 64 | |
---|
| 65 | @end ifnottex |
---|
| 66 | @strong{Rough Draft} |
---|
| 67 | |
---|
| 68 | The goal of this document is to gather all the information needed to |
---|
| 69 | port the GNU tools to a new embedded target in one place. This will |
---|
| 70 | duplicate some info found in the other manual for the GNU tools, but |
---|
| 71 | this should be all you'll need. |
---|
| 72 | |
---|
| 73 | @menu |
---|
| 74 | * Libgloss:: Libgloss, a library of board support packages. |
---|
| 75 | * GCC:: Porting GCC/G++ to a new embedded target. |
---|
| 76 | * Libraries:: Making Newlib run on an new embedded target. |
---|
| 77 | * GDB:: Making GDB understand a new back end. |
---|
| 78 | * Binutils:: Using the GNU binary utilities. |
---|
| 79 | * Code Listings:: Listings of the commented source code from the |
---|
| 80 | text. |
---|
| 81 | @end menu |
---|
| 82 | |
---|
| 83 | @node Libgloss, GCC, Top, Top |
---|
| 84 | @chapter Libgloss |
---|
| 85 | Libgloss is a library for all the details that usually get glossed over. |
---|
| 86 | This library refers to things like startup code, and usually I/O support |
---|
| 87 | for @code{gcc} and @code{C library}. The C library used through out |
---|
| 88 | this manual is @code{newlib}. Newlib is a ANSI conforming C library |
---|
| 89 | developed by Cygnus Support. Libgloss could easily be made to |
---|
| 90 | support other C libraries, and it can be used standalone as well. The |
---|
| 91 | standalone configuration is typically used when bringing up new |
---|
| 92 | hardware, or on small systems. |
---|
| 93 | |
---|
| 94 | For a long time, these details were part of newlib. This approach worked |
---|
| 95 | well when a complete tool chain only had to support one system. A tool |
---|
| 96 | chain refers to the series of compiler passes required to produce a |
---|
| 97 | binary file that will run on an embedded system. For C, the passes are |
---|
| 98 | cpp, gcc, gas, ld. Cpp is the preprocessor, which process all the header |
---|
| 99 | files and macros. Gcc is the compiler, which produces assembler from the |
---|
| 100 | processed C files. Gas assembles the code into object files, and then ld |
---|
| 101 | combines the object files and binds the code to addresses and produces |
---|
| 102 | the final executable image. |
---|
| 103 | |
---|
| 104 | Most of the time a tool chain does only have to support one target |
---|
| 105 | execution environment. An example of this would be a tool chain for the |
---|
| 106 | AMD 29k processor family. All of the execution environments for this |
---|
| 107 | processor have the same interface, the same memory map, and the same |
---|
| 108 | I/O code. In this case all of the support code is under newlib/libc/sys. |
---|
| 109 | Libgloss's creation was forced initially because of the @code{cpu32} |
---|
| 110 | processor family. There are many different execution environments for |
---|
| 111 | this line, and they vary wildly. newlib itself has only a few |
---|
| 112 | dependencies that it needs for each target. These are explained later in |
---|
| 113 | this doc. The hardware dependent part of newlib was reorganized into a |
---|
| 114 | separate directory structure within newlib called the stub dirs. It was |
---|
| 115 | initially called this because most of the routines newlib needs for a |
---|
| 116 | target were simple stubs that do nothing, but return a value to the |
---|
| 117 | application. They only exist so the linker can produce a final |
---|
| 118 | executable image. This work was done during the early part of 1993. |
---|
| 119 | |
---|
| 120 | After a while it became apparent that this approach of isolating the |
---|
| 121 | hardware and systems files together made sense. Around this same time |
---|
| 122 | the stub dirs were made to run standalone, mostly so it could also be |
---|
| 123 | used to support GDB's remote debugging needs. At this time it was |
---|
| 124 | decided to move the stub dirs out of newlib and into it's own separate |
---|
| 125 | library so it could be used standalone, and be included in various other |
---|
| 126 | GNU tools without having to bring in all of newlib, which is large. The |
---|
| 127 | new library is called Libgloss, for Gnu Low-level OS support. |
---|
| 128 | |
---|
| 129 | @menu |
---|
| 130 | * Supported targets:: What targets libgloss currently |
---|
| 131 | supports. |
---|
| 132 | * Building libgloss:: How to configure and built libgloss |
---|
| 133 | for a target. |
---|
| 134 | * Board support:: How to add support for a new board. |
---|
| 135 | @end menu |
---|
| 136 | |
---|
| 137 | @node Supported targets, Building libgloss, Libgloss, Libgloss |
---|
| 138 | @section Supported Targets |
---|
| 139 | Currently libgloss is being used for the following targets: |
---|
| 140 | |
---|
| 141 | @menu |
---|
| 142 | * Sparclite:: Fujitsu's sparclite. |
---|
| 143 | * CPU32:: Various m68k based targets. |
---|
| 144 | * Mips:: Mips code based targets. |
---|
| 145 | * PA-RISC:: Precision Risc Organization.. |
---|
| 146 | @end menu |
---|
| 147 | |
---|
| 148 | @node Sparclite, CPU32, , Supported targets |
---|
| 149 | @subsection Sparclite Targets Supported |
---|
| 150 | @c FIXME: put links to the docs in etc/targetdoc |
---|
| 151 | This is for the Fujitsu Sparclite family of processors. Currently this |
---|
| 152 | covers the ex930, ex931, ex932, ex933, and the ex934. In addition to the |
---|
| 153 | I/O code a startup file, this has a GDB debug-stub that gets linked into |
---|
| 154 | your application. This is an exception handler style debug stub. For |
---|
| 155 | more info, see the section on Porting GDB. @ref{GDB,,Porting GDB}. |
---|
| 156 | |
---|
| 157 | The Fujitsu eval boards use a host based terminal program to load and |
---|
| 158 | execute programs on the target. This program, @code{pciuh} is relatively |
---|
| 159 | new (in 1994) and it replaced the previous ROM monitor which had the |
---|
| 160 | shell in the ROM. GDB uses the the GDB remote protocol, the relevant |
---|
| 161 | source files from the gdb sources are remote-sparcl.c. The debug stub is |
---|
| 162 | part of libgloss and is called sparcl-stub.c. |
---|
| 163 | |
---|
| 164 | @node CPU32, Mips, Sparclite, Supported targets |
---|
| 165 | @subsection Motorola CPU32 Targets supported |
---|
| 166 | This refers to Motorola's m68k based CPU32 processor family. The crt0.S |
---|
| 167 | startup file should be usable with any target environment, and it's |
---|
| 168 | mostly just the I/O code and linker scripts that vary. Currently there |
---|
| 169 | is support for the Motorola MVME line of 6U VME boards and IDP |
---|
| 170 | line of eval boards. All of the |
---|
| 171 | Motorola VME boards run @code{Bug}, a ROM based debug monitor. |
---|
| 172 | This monitor has the feature of using user level traps to do I/O, so |
---|
| 173 | this code should be portable to other MVME boards with little if any |
---|
| 174 | change. The startup file also can remain unchanged. About the only thing |
---|
| 175 | that varies is the address for where the text section begins. This can |
---|
| 176 | be accomplished either in the linker script, or on the command line |
---|
| 177 | using the @samp{-Ttext [address]}. |
---|
| 178 | |
---|
| 179 | @c FIXME: Intermetrics or ISI wrote rom68k ? |
---|
| 180 | There is also support for the @code{rom68k} monitor as shipped on |
---|
| 181 | Motorola's IDP eval board line. This code should be portable across the |
---|
| 182 | range of CPU's the board supports. There is also GDB support for this |
---|
| 183 | target environment in the GDB source tree. The relevant files are |
---|
| 184 | gdb/monitor.c, monitor.h, and rom58k-rom.c. The usage of these files is |
---|
| 185 | discussed in the GDB section. |
---|
| 186 | |
---|
| 187 | @node Mips, PA-RISC, CPU32, Supported targets |
---|
| 188 | @subsection Mips core Targets Supported |
---|
| 189 | The Crt0 startup file should run on any mips target that doesn't require |
---|
| 190 | additional hardware initialization. The I/O code so far only supports a |
---|
| 191 | custom LSI33k based RAID disk controller board. It should easy to |
---|
| 192 | change to support the IDT line of eval boards. Currently the two |
---|
| 193 | debugging protocols supported by GDB for mips targets is IDT's mips |
---|
| 194 | debug protocol, and a customized hybrid of the standard GDB remote |
---|
| 195 | protocol and GDB's standard ROM monitor support. Included here is the |
---|
| 196 | debug stub for the hybrid monitor. This supports the LSI33k processor, |
---|
| 197 | and only has support for the GDB protocol commands @code{g}, @code{G}, |
---|
| 198 | @code{m}, @code{M}, which basically only supports the register and |
---|
| 199 | memory reading and writing commands. This is part of libgloss and is |
---|
| 200 | called lsi33k-stub.c. |
---|
| 201 | |
---|
| 202 | The crt0.S should also work on the IDT line of eval boards, but has only |
---|
| 203 | been run on the LSI33k for now. There is no I/O support for the IDT eval |
---|
| 204 | board at this time. The current I/O code is for a customized version of |
---|
| 205 | LSI's @code{pmon} ROM monitor. This uses entry points into the monitor, |
---|
| 206 | and should easily port to other versions of the pmon monitor. Pmon is |
---|
| 207 | distributed in source by LSI. |
---|
| 208 | |
---|
| 209 | @node PA-RISC, , Mips, Supported targets |
---|
| 210 | @subsection PA-RISC Targets Supported |
---|
| 211 | This supports the various boards manufactured by the HP-PRO consortium. |
---|
| 212 | This is a group of companies all making variations on the PA-RISC |
---|
| 213 | processor. Currently supported are ports to the WinBond @samp{Cougar} |
---|
| 214 | board based around their w89k version of the PA. Also supported is the |
---|
| 215 | Oki op50n processor. |
---|
| 216 | |
---|
| 217 | There is also included, but never built an unfinished port to the HP 743 |
---|
| 218 | board. This board is the main CPU board for the HP700 line of industrial |
---|
| 219 | computers. This target isn't exactly an embedded system, in fact it's |
---|
| 220 | really only designed to load and run HP-UX. Still, the crt0.S and I/O |
---|
| 221 | code are fully working. It is included mostly because their is a barely |
---|
| 222 | functioning exception handler GDB debug stub, and I hope somebody could |
---|
| 223 | use it. The other PRO targets all use GDB's ability to talk to ROM |
---|
| 224 | monitors directly, so it doesn't need a debug stub. There is also a |
---|
| 225 | utility that will produce a bootable file by HP's ROM monitor. This is |
---|
| 226 | all included in the hopes somebody else will finish it. :-) |
---|
| 227 | |
---|
| 228 | Both the WinBond board and the Oki board download srecords. The WinBond |
---|
| 229 | board also has support for loading the SOM files as produced by the |
---|
| 230 | native compiler on HP-UX. WinBond supplies a set of DOS programs that |
---|
| 231 | will allow the loading of files via a bidirectional parallel port. This |
---|
| 232 | has never been tested with the output of GNU SOM, as this manual is |
---|
| 233 | mostly for Unix based systems. |
---|
| 234 | |
---|
| 235 | @node Building libgloss, Board support, Supported targets, Libgloss |
---|
| 236 | @section Configuring and building libgloss. |
---|
| 237 | |
---|
| 238 | Libgloss uses an autoconf based script to configure. Autoconf scripts |
---|
| 239 | are portable shell scripts that are generated from a configure.in file. |
---|
| 240 | Configure input scripts are based themselves on m4. Most configure |
---|
| 241 | scripts run a series of tests to determine features the various |
---|
| 242 | supported features of the target. For features that can't be determined |
---|
| 243 | by a feature test, a makefile fragment is merged in. The configure |
---|
| 244 | process leaves creates a Makefile in the build directory. For libgloss, |
---|
| 245 | there are only a few configure options of importance. These are --target |
---|
| 246 | and --srcdir. |
---|
| 247 | |
---|
| 248 | Typically libgloss is built in a separate tree just for objects. In this |
---|
| 249 | manner, it's possible to have a single source tree, and multiple object |
---|
| 250 | trees. If you only need to configure for a single target environment, |
---|
| 251 | then you can configure in the source tree. The argument for --target is |
---|
| 252 | a config string. It's usually safest to use the full canonical opposed |
---|
| 253 | to the target alias. So, to configure for a CPU32 (m68k) with a separate |
---|
| 254 | source tree, use: |
---|
| 255 | |
---|
| 256 | @smallexample |
---|
| 257 | ../src/libgloss/configure --verbose --target m68k-coff |
---|
| 258 | @end smallexample |
---|
| 259 | |
---|
| 260 | The configure script is in the source tree. When configure is invoked |
---|
| 261 | it will determine it's own source tree, so the --srcdir is would be |
---|
| 262 | redundant here. |
---|
| 263 | |
---|
| 264 | Once libgloss is configured, @code{make} is sufficient to build it. The |
---|
| 265 | default values for @code{Makefiles} are typically correct for all |
---|
| 266 | supported systems. The test cases in the testsuite will also built |
---|
| 267 | automatically as opposed to a @code{make check}, where test binaries |
---|
| 268 | aren't built till test time. This is mostly cause the libgloss |
---|
| 269 | testsuites are the last thing built when building the entire GNU source |
---|
| 270 | tree, so it's a good test of all the other compilation passes. |
---|
| 271 | |
---|
| 272 | The default values for the Makefiles are set in the Makefile fragment |
---|
| 273 | merged in during configuration. This fragment typically has rules like |
---|
| 274 | |
---|
| 275 | @smallexample |
---|
| 276 | CC_FOR_TARGET = `if [ -f $$@{OBJROOT@}/gcc/xgcc ] ; \ |
---|
| 277 | then echo $@{OBJROOT@}/gcc/xgcc -B$@{OBJROOT@}/gcc/ ; \ |
---|
| 278 | else t='$@{program_transform_name@}'; echo gcc | sed -e '' $$t ; fi` |
---|
| 279 | @end smallexample |
---|
| 280 | |
---|
| 281 | Basically this is a runtime test to determine whether there are freshly |
---|
| 282 | built executables for the other main passes of the GNU tools. If there |
---|
| 283 | isn't an executable built in the same object tree, then |
---|
| 284 | @emph{transformed}the generic tool name (like gcc) is transformed to the |
---|
| 285 | name typically used in GNU cross compilers. The names are |
---|
| 286 | typically based on the target's canonical name, so if you've configured |
---|
| 287 | for @code{m68k-coff} the transformed name is @code{m68k-coff-gcc} in |
---|
| 288 | this case. If you install with aliases or rename the tools, this won't |
---|
| 289 | work, and it will always look for tools in the path. You can force the a |
---|
| 290 | different name to work by reconfiguring with the |
---|
| 291 | @code{--program-transform-name} option to configure. This option takes a |
---|
| 292 | sed script like this @code{-e s,^,m68k-coff-,} which produces tools |
---|
| 293 | using the standard names (at least here at Cygnus). |
---|
| 294 | |
---|
| 295 | The search for the other GNU development tools is exactly the same idea. |
---|
| 296 | This technique gets messier when build options like @code{-msoft-float} |
---|
| 297 | support are used. The Makefile fragments set the @code{MUTILIB} |
---|
| 298 | variable, and if it is set, the search path is modified. If the linking |
---|
| 299 | is done with an installed cross compiler, then none of this needs to be |
---|
| 300 | used. This is done so libgloss will build automatically with a fresh, |
---|
| 301 | and uninstalled object tree. It also makes it easier to debug the other |
---|
| 302 | tools using libgloss's test suites. |
---|
| 303 | |
---|
| 304 | @node Board support, , Building libgloss, Libgloss |
---|
| 305 | @section Adding Support for a New Board |
---|
| 306 | |
---|
| 307 | This section explains how to add support for a new board to libgloss. |
---|
| 308 | In order to add support for a board, you must already have developed a |
---|
| 309 | toolchain for the target architecture. |
---|
| 310 | |
---|
| 311 | All of the changes you will make will be in the subdirectory named |
---|
| 312 | after the architecture used by your board. For example, if you are |
---|
| 313 | developing support for a new ColdFire board, you will modify files in |
---|
| 314 | the @file{m68k} subdirectory, as that subdirectory contains support |
---|
| 315 | for all 68K devices, including architecture variants like ColdFire. |
---|
| 316 | |
---|
| 317 | In general, you will be adding three components: a @file{crt0.S} file |
---|
| 318 | (@pxref{Crt0}), a linker script (@pxref{Linker Scripts}), and a |
---|
| 319 | hardware support library. Each should be prefixed with the name of |
---|
| 320 | your board. For example, if you ard adding support for a new Surf |
---|
| 321 | board, then you will be adding the assembly @file{surf-crt0.S} (which |
---|
| 322 | will be assembled into @file{surf-crt0.o}), the linker script |
---|
| 323 | @file{surf.ld}, and other C and assembly files which will be combined |
---|
| 324 | into the hardware support library @file{libsurf.a}. |
---|
| 325 | |
---|
| 326 | You should modify @file{Makefile.in} to define new variables |
---|
| 327 | corresponding to your board. Although there is some variation between |
---|
| 328 | architectures, the general convention is to use the following format: |
---|
| 329 | |
---|
| 330 | @example |
---|
| 331 | # The name of the crt0.o file. |
---|
| 332 | SURF_CRT0 = surf-crt0.o |
---|
| 333 | # The name of the linker script. |
---|
| 334 | SURF_SCRIPTS = surf.ld |
---|
| 335 | # The name of the hardware support library. |
---|
| 336 | SURF_BSP = libsurf.a |
---|
| 337 | # The object files that make up the hardware support library. |
---|
| 338 | SURF_OBJS = surf-file1.o surf-file2.o |
---|
| 339 | # The name of the Makefile target to use for installation. |
---|
| 340 | SURF_INSTALL = install-surf |
---|
| 341 | @end example |
---|
| 342 | |
---|
| 343 | Then, you should create the @code{$@{SURF_BSP@}} and |
---|
| 344 | @code{$@{SURF_INSTALL@}} make targets. Add @code{$@{SURF_CRT0@}} to |
---|
| 345 | the dependencies for the @code{all} target and add |
---|
| 346 | @code{$@{SURF_INSTALL@}} to the dependencies for the @code{install} |
---|
| 347 | target. Now, when libgloss is built and installed, support for your |
---|
| 348 | BSP will be installed as well. |
---|
| 349 | |
---|
| 350 | @node GCC, Libraries, Libgloss, Top |
---|
| 351 | @chapter Porting GCC |
---|
| 352 | |
---|
| 353 | Porting GCC requires two things, neither of which has anything to do |
---|
| 354 | with GCC. If GCC already supports a processor type, then all the work in |
---|
| 355 | porting GCC is really a linker issue. All GCC has to do is produce |
---|
| 356 | assembler output in the proper syntax. Most of the work is done by the |
---|
| 357 | linker, which is described elsewhere. |
---|
| 358 | |
---|
| 359 | Mostly all GCC does is format the command line for the linker pass. The |
---|
| 360 | command line for GCC is set in the various config subdirectories of gcc. |
---|
| 361 | The options of interest to us are @code{CPP_SPEC} and |
---|
| 362 | @code{STARTFILE_SPEC}. CPP_SPEC sets the builtin defines for your |
---|
| 363 | environment. If you support multiple environments with the same |
---|
| 364 | processor, then OS specific defines will need to be elsewhere. |
---|
| 365 | @c FIXME: Check these names |
---|
| 366 | |
---|
| 367 | @code{STARTFILE_SPEC} |
---|
| 368 | |
---|
| 369 | Once you have linker support, GCC will be able to produce a fully linked |
---|
| 370 | executable image. The only @emph{part} of GCC that the linker wants is a |
---|
| 371 | crt0.o, and a memory map. If you plan on running any programs that do |
---|
| 372 | I/O of any kind, you'll need to write support for the C library, which |
---|
| 373 | is described elsewhere. |
---|
| 374 | |
---|
| 375 | @menu |
---|
| 376 | * Overview:: An overview as to the compilation passes. |
---|
| 377 | * Options:: Useful GCC options for embedded systems. |
---|
| 378 | @end menu |
---|
| 379 | |
---|
| 380 | @node Overview, Options, , GCC |
---|
| 381 | @section Compilation passes |
---|
| 382 | |
---|
| 383 | GCC by itself only compiles the C or C++ code into assembler. Typically |
---|
| 384 | GCC invokes all the passes required for you. These passes are cpp, cc1, |
---|
| 385 | gas, ld. @code{cpp} is the C preprocessor. This will merge in the |
---|
| 386 | include files, expand all macros definitions, and process all the |
---|
| 387 | @code{#ifdef} sections. To see the output of ccp, invoke gcc with the |
---|
| 388 | @code{-E} option, and the preprocessed file will be printed on the |
---|
| 389 | stdout. cc1 is the actual compiler pass that produces the assembler for |
---|
| 390 | the processed file. GCC is actually only a driver program for all the |
---|
| 391 | compiler passes. It will format command line options for the other passes. |
---|
| 392 | The usual command line GCC uses for the final link phase will have LD |
---|
| 393 | link in the startup code and additional libraries by default. |
---|
| 394 | |
---|
| 395 | GNU AS started it's life to only function as a compiler pass, but |
---|
| 396 | these days it can also be used as a source level assembler. When used as |
---|
| 397 | a source level assembler, it has a companion assembler preprocessor |
---|
| 398 | called @code{gasp}. This has a syntax similar to most other assembler |
---|
| 399 | macros packages. GAS emits a relocatable object file from the assembler |
---|
| 400 | source. The object file contains the executable part of the application, |
---|
| 401 | and debug symbols. |
---|
| 402 | |
---|
| 403 | LD is responsible for resolving the addresses and symbols to something |
---|
| 404 | that will be fully self-contained. Some RTOS's use relocatable object |
---|
| 405 | file formats like @code{a.out}, but more commonly the final image will |
---|
| 406 | only use absolute addresses for symbols. This enables code to be burned |
---|
| 407 | into PROMS as well. Although LD can produce an executable image, there |
---|
| 408 | is usually a hidden object file called @code{crt0.o} that is required as |
---|
| 409 | startup code. With this startup code and a memory map, the executable |
---|
| 410 | image will actually run on the target environment. @ref{Crt0,,Startup |
---|
| 411 | Files}. |
---|
| 412 | |
---|
| 413 | The startup code usually defines a special symbol like @code{_start} |
---|
| 414 | that is the default base address for the application, and the first |
---|
| 415 | symbol in the executable image. If you plan to use any routines from the |
---|
| 416 | standard C library, you'll also need to implement the functions that |
---|
| 417 | this library is dependent on. @ref{Libraries,,Porting Newlib}. |
---|
| 418 | |
---|
| 419 | @node Options, , Overview, GCC |
---|
| 420 | @c FIXME: Need stuff here about -fpic, -Ttext, etc... |
---|
| 421 | |
---|
| 422 | Options for the various development tools are covered in more detail |
---|
| 423 | elsewhere. Still, the amount of options can be an overwhelming amount of |
---|
| 424 | stuff, so the options most suited to embedded systems are summarized |
---|
| 425 | here. If you use GCC as the main driver for all the passes, most of the |
---|
| 426 | linker options can be passed directly to the compiler. There are also |
---|
| 427 | GCC options that control how the GCC driver formats the command line |
---|
| 428 | arguments for the linker. |
---|
| 429 | |
---|
| 430 | @menu |
---|
| 431 | * GCC Options:: Options for the compiler. |
---|
| 432 | * GAS Options:: Options for the assembler. |
---|
| 433 | * LD Options:: Options for the linker. |
---|
| 434 | @end menu |
---|
| 435 | |
---|
| 436 | @node GCC Options, GAS Options, , Options |
---|
| 437 | Most of the GCC options that we're interested control how the GCC driver |
---|
| 438 | formats the options for the linker pass. |
---|
| 439 | |
---|
| 440 | @c FIXME: this section is still under work. |
---|
| 441 | @table @code |
---|
| 442 | @item -nostartfiles |
---|
| 443 | @item -nostdlib |
---|
| 444 | @item -Xlinker |
---|
| 445 | Pass the next option directly to the linker. |
---|
| 446 | |
---|
| 447 | @item -v |
---|
| 448 | @item -fpic |
---|
| 449 | @end table |
---|
| 450 | |
---|
| 451 | @node GAS Options, LD Options, GCC Options, Options |
---|
| 452 | @c FIXME: Needs stuff here |
---|
| 453 | |
---|
| 454 | @node LD Options, , GAS Options, Options |
---|
| 455 | @c FIXME: Needs stuff here |
---|
| 456 | |
---|
| 457 | |
---|
| 458 | @node Libraries, GDB, GCC, Top |
---|
| 459 | @chapter Porting newlib |
---|
| 460 | |
---|
| 461 | @menu |
---|
| 462 | * Crt0:: Crt0.S. |
---|
| 463 | * Linker Scripts:: Linker scripts for memory management. |
---|
| 464 | * What to do now:: Tricks for manipulating formats. |
---|
| 465 | * Libc:: Making libc work. |
---|
| 466 | @end menu |
---|
| 467 | |
---|
| 468 | @node Crt0, Linker Scripts, , Libraries |
---|
| 469 | @section Crt0, the main startup file |
---|
| 470 | |
---|
| 471 | To make a program that has been compiled with GCC to run, you |
---|
| 472 | need to write some startup code. The initial piece of startup code is |
---|
| 473 | called a crt0. (C RunTime 0) This is usually written in assembler, and |
---|
| 474 | it's object gets linked in first, and bootstraps the rest of the |
---|
| 475 | application when executed. This file needs to do the following things. |
---|
| 476 | |
---|
| 477 | @enumerate |
---|
| 478 | @item |
---|
| 479 | Initialize anything that needs it. This init section varies. If you are |
---|
| 480 | developing an application that gets download to a ROM monitor, then |
---|
| 481 | there is usually no need for any special initialization. The ROM monitor |
---|
| 482 | handles it for you. |
---|
| 483 | |
---|
| 484 | If you plan to burn your code in a ROM, then the crt0 typically has to |
---|
| 485 | do all the hardware initialization that is required to run an |
---|
| 486 | application. This can include things like initializing serial ports or |
---|
| 487 | run a memory check. It all depends on the hardware. |
---|
| 488 | |
---|
| 489 | @item |
---|
| 490 | Zero the BSS section. This is for uninitialized data. All the addresses in |
---|
| 491 | this section need to be initialized to zero so that programs that forget |
---|
| 492 | to check new variables default value will get unpredictable results. |
---|
| 493 | |
---|
| 494 | @item |
---|
| 495 | Call main() |
---|
| 496 | This is what basically starts things running. If your ROM monitor |
---|
| 497 | supports it, then first setup argc and argv for command line arguments |
---|
| 498 | and an environment pointer. Then branch to main(). For G++ the the main |
---|
| 499 | routine gets a branch to __main inserted by the code generator at the |
---|
| 500 | very top. __main() is used by G++ to initialize it's internal tables. |
---|
| 501 | __main() then returns back to your original main() and your code gets |
---|
| 502 | executed. |
---|
| 503 | |
---|
| 504 | @item |
---|
| 505 | Call exit() |
---|
| 506 | After main() has returned, you need to cleanup things and return control |
---|
| 507 | of the hardware from the application. On some hardware, there is nothing |
---|
| 508 | to return to, especially if your program is in ROM. Sometimes the best |
---|
| 509 | thing to do in this case is do a hardware reset, or branch back to the |
---|
| 510 | start address all over again. |
---|
| 511 | |
---|
| 512 | When there is a ROM monitor present, usually a user trap can be called |
---|
| 513 | and then the ROM takes over. Pick a safe vector with no side |
---|
| 514 | effects. Some ROMs have a builtin trap handler just for this case. |
---|
| 515 | @end enumerate |
---|
| 516 | portable between all the m68k based boards we have here. |
---|
| 517 | @ref{crt0.S,,Example Crt0.S}. |
---|
| 518 | |
---|
| 519 | |
---|
| 520 | @smallexample |
---|
| 521 | /* ANSI concatenation macros. */ |
---|
| 522 | |
---|
| 523 | #define CONCAT1(a, b) CONCAT2(a, b) |
---|
| 524 | #define CONCAT2(a, b) a ## b |
---|
| 525 | @end smallexample |
---|
| 526 | These we'll use later. |
---|
| 527 | |
---|
| 528 | @smallexample |
---|
| 529 | /* These are predefined by new versions of GNU cpp. */ |
---|
| 530 | |
---|
| 531 | #ifndef __USER_LABEL_PREFIX__ |
---|
| 532 | #define __USER_LABEL_PREFIX__ _ |
---|
| 533 | #endif |
---|
| 534 | |
---|
| 535 | /* Use the right prefix for global labels. */ |
---|
| 536 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) |
---|
| 537 | |
---|
| 538 | @end smallexample |
---|
| 539 | |
---|
| 540 | These macros are to make this code portable between both @emph{COFF} and |
---|
| 541 | @emph{a.out}. @emph{COFF} always has an @var{_ (underline)} prepended on |
---|
| 542 | the front of all global symbol names. @emph{a.out} has none. |
---|
| 543 | |
---|
| 544 | @smallexample |
---|
| 545 | #ifndef __REGISTER_PREFIX__ |
---|
| 546 | #define __REGISTER_PREFIX__ |
---|
| 547 | #endif |
---|
| 548 | |
---|
| 549 | /* Use the right prefix for registers. */ |
---|
| 550 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) |
---|
| 551 | |
---|
| 552 | #define d0 REG (d0) |
---|
| 553 | #define d1 REG (d1) |
---|
| 554 | #define d2 REG (d2) |
---|
| 555 | #define d3 REG (d3) |
---|
| 556 | #define d4 REG (d4) |
---|
| 557 | #define d5 REG (d5) |
---|
| 558 | #define d6 REG (d6) |
---|
| 559 | #define d7 REG (d7) |
---|
| 560 | #define a0 REG (a0) |
---|
| 561 | #define a1 REG (a1) |
---|
| 562 | #define a2 REG (a2) |
---|
| 563 | #define a3 REG (a3) |
---|
| 564 | #define a4 REG (a4) |
---|
| 565 | #define a5 REG (a5) |
---|
| 566 | #define a6 REG (a6) |
---|
| 567 | #define fp REG (fp) |
---|
| 568 | #define sp REG (sp) |
---|
| 569 | @end smallexample |
---|
| 570 | |
---|
| 571 | This is for portability between assemblers. Some register names have a |
---|
| 572 | @var{%} or @var{$} prepended to the register name. |
---|
| 573 | |
---|
| 574 | @smallexample |
---|
| 575 | /* |
---|
| 576 | * Set up some room for a stack. We just grab a chunk of memory. |
---|
| 577 | */ |
---|
| 578 | .set stack_size, 0x2000 |
---|
| 579 | .comm SYM (stack), stack_size |
---|
| 580 | @end smallexample |
---|
| 581 | |
---|
| 582 | Set up space for the stack. This can also be done in the linker script, |
---|
| 583 | but it typically gets done here. |
---|
| 584 | |
---|
| 585 | @smallexample |
---|
| 586 | /* |
---|
| 587 | * Define an empty environment. |
---|
| 588 | */ |
---|
| 589 | .data |
---|
| 590 | .align 2 |
---|
| 591 | SYM (environ): |
---|
| 592 | .long 0 |
---|
| 593 | @end smallexample |
---|
| 594 | |
---|
| 595 | Set up an empty space for the environment. This is bogus on any most ROM |
---|
| 596 | monitor, but we setup a valid address for it, and pass it to main. At |
---|
| 597 | least that way if an application checks for it, it won't crash. |
---|
| 598 | |
---|
| 599 | @smallexample |
---|
| 600 | .align 2 |
---|
| 601 | .text |
---|
| 602 | .global SYM (stack) |
---|
| 603 | |
---|
| 604 | .global SYM (main) |
---|
| 605 | .global SYM (exit) |
---|
| 606 | /* |
---|
| 607 | * This really should be __bss_start, not SYM (__bss_start). |
---|
| 608 | */ |
---|
| 609 | .global __bss_start |
---|
| 610 | @end smallexample |
---|
| 611 | |
---|
| 612 | Setup a few global symbols that get used elsewhere. @var{__bss_start} |
---|
| 613 | needs to be unchanged, as it's setup by the linker script. |
---|
| 614 | |
---|
| 615 | @smallexample |
---|
| 616 | /* |
---|
| 617 | * start -- set things up so the application will run. |
---|
| 618 | */ |
---|
| 619 | SYM (start): |
---|
| 620 | link a6, #-8 |
---|
| 621 | moveal #SYM (stack) + stack_size, sp |
---|
| 622 | |
---|
| 623 | /* |
---|
| 624 | * zerobss -- zero out the bss section |
---|
| 625 | */ |
---|
| 626 | moveal #__bss_start, a0 |
---|
| 627 | moveal #SYM (end), a1 |
---|
| 628 | 1: |
---|
| 629 | movel #0, (a0) |
---|
| 630 | leal 4(a0), a0 |
---|
| 631 | cmpal a0, a1 |
---|
| 632 | bne 1b |
---|
| 633 | @end smallexample |
---|
| 634 | |
---|
| 635 | The global symbol @code{start} is used by the linker as the default |
---|
| 636 | address to use for the @code{.text} section. then it zeros the |
---|
| 637 | @code{.bss} section so the uninitialized data will all be cleared. Some |
---|
| 638 | programs have wild side effects from having the .bss section let |
---|
| 639 | uncleared. Particularly it causes problems with some implementations of |
---|
| 640 | @code{malloc}. |
---|
| 641 | |
---|
| 642 | @smallexample |
---|
| 643 | /* |
---|
| 644 | * Call the main routine from the application to get it going. |
---|
| 645 | * main (argc, argv, environ) |
---|
| 646 | * We pass argv as a pointer to NULL. |
---|
| 647 | */ |
---|
| 648 | pea 0 |
---|
| 649 | pea SYM (environ) |
---|
| 650 | pea sp@@(4) |
---|
| 651 | pea 0 |
---|
| 652 | jsr SYM (main) |
---|
| 653 | movel d0, sp@@- |
---|
| 654 | @end smallexample |
---|
| 655 | |
---|
| 656 | Setup the environment pointer and jump to @code{main()}. When |
---|
| 657 | @code{main()} returns, it drops down to the @code{exit} routine below. |
---|
| 658 | |
---|
| 659 | @smallexample |
---|
| 660 | /* |
---|
| 661 | * _exit -- Exit from the application. Normally we cause a user trap |
---|
| 662 | * to return to the ROM monitor for another run. |
---|
| 663 | */ |
---|
| 664 | SYM (exit): |
---|
| 665 | trap #0 |
---|
| 666 | @end smallexample |
---|
| 667 | |
---|
| 668 | Implementing @code{exit} here is easy. Both the @code{rom68k} and @code{bug} |
---|
| 669 | can handle a user caused exception of @code{zero} with no side effects. |
---|
| 670 | Although the @code{bug} monitor has a user caused trap that will return |
---|
| 671 | control to the ROM monitor, this solution has been more portable. |
---|
| 672 | |
---|
| 673 | @node Linker Scripts, What to do now, Crt0, Libraries |
---|
| 674 | @section Linker scripts for memory management |
---|
| 675 | |
---|
| 676 | The linker script sets up the memory map of an application. It also |
---|
| 677 | sets up default values for variables used elsewhere by sbrk() and the |
---|
| 678 | crt0. These default variables are typically called @code{_bss_start} and |
---|
| 679 | @code{_end}. |
---|
| 680 | |
---|
| 681 | For G++, the constructor and destructor tables must also be setup here. |
---|
| 682 | The actual section names vary depending on the object file format. For |
---|
| 683 | @code{a.out} and @code{coff}, the three main sections are @code{.text}, |
---|
| 684 | @code{.data}, and @code{.bss}. |
---|
| 685 | |
---|
| 686 | Now that you have an image, you can test to make sure it got the |
---|
| 687 | memory map right. You can do this by having the linker create a memory |
---|
| 688 | map (by using the @code{-Map} option), or afterwards by using @code{nm} to |
---|
| 689 | check a few critical addresses like @code{start}, @code{bss_end}, and |
---|
| 690 | @code{_etext}. |
---|
| 691 | |
---|
| 692 | Here's a breakdown of a linker script for a m68k based target board. |
---|
| 693 | See the file @code{libgloss/m68k/idp.ld}, or go to the appendixes in |
---|
| 694 | the end of the manual. @ref{idp.ld,,Example Linker Script}. |
---|
| 695 | |
---|
| 696 | @smallexample |
---|
| 697 | STARTUP(crt0.o) |
---|
| 698 | OUTPUT_ARCH(m68k) |
---|
| 699 | INPUT(idp.o) |
---|
| 700 | SEARCH_DIR(.) |
---|
| 701 | __DYNAMIC = 0; |
---|
| 702 | @end smallexample |
---|
| 703 | |
---|
| 704 | The @code{STARTUP} command loads the file specified so that it's |
---|
| 705 | first. In this case it also doubles to load the file as well, because |
---|
| 706 | the m68k-coff configuration defaults to not linking in the crt0.o by |
---|
| 707 | default. It assumes that the developer probably has their own crt0.o. |
---|
| 708 | This behavior is controlled in the config file for each architecture. |
---|
| 709 | It's a macro called @code{STARTFILE_SPEC}, and if it's set to |
---|
| 710 | @code{null}, then when @code{gcc} formats it's command line, it doesn't |
---|
| 711 | add @code{crto.o}. Any file name can be specified here, but the default |
---|
| 712 | is always @code{crt0.o}. |
---|
| 713 | |
---|
| 714 | Course if you only use @code{ld} to link, then the control of whether or |
---|
| 715 | not to link in @code{crt0.o} is done on the command line. If you have |
---|
| 716 | multiple crto files, then you can leave this out all together, and link |
---|
| 717 | in the @code{crt0.o} in the makefile, or by having different linker |
---|
| 718 | scripts. Sometimes this is done for initializing floating point |
---|
| 719 | optionally, or to add device support. |
---|
| 720 | |
---|
| 721 | The @code{OUTPUT_ARCH} sets architecture the output file is for. |
---|
| 722 | |
---|
| 723 | @code{INPUT} loads in the file specified. In this case, it's a relocated |
---|
| 724 | library that contains the definitions for the low-level functions need |
---|
| 725 | by libc.a. This could have also been specified on the command line, but |
---|
| 726 | as it's always needed, it might as well be here as a default. |
---|
| 727 | @code{SEARCH_DIR} specifies the path to look for files, and |
---|
| 728 | @code{_DYNAMIC} means in this case there are no shared libraries. |
---|
| 729 | |
---|
| 730 | @c FIXME: Check the linker manual to make sure this is accurate. |
---|
| 731 | @smallexample |
---|
| 732 | /* |
---|
| 733 | * Setup the memory map of the MC68ec0x0 Board (IDP) |
---|
| 734 | * stack grows up towards high memory. This works for |
---|
| 735 | * both the rom68k and the mon68k monitors. |
---|
| 736 | */ |
---|
| 737 | MEMORY |
---|
| 738 | @{ |
---|
| 739 | ram : ORIGIN = 0x10000, LENGTH = 2M |
---|
| 740 | @} |
---|
| 741 | @end smallexample |
---|
| 742 | |
---|
| 743 | This specifies a name for a section that can be referred to later in the |
---|
| 744 | script. In this case, it's only a pointer to the beginning of free RAM |
---|
| 745 | space, with an upper limit at 2M. If the output file exceeds the upper |
---|
| 746 | limit, it will produce an error message. |
---|
| 747 | |
---|
| 748 | @smallexample |
---|
| 749 | /* |
---|
| 750 | * stick everything in ram (of course) |
---|
| 751 | */ |
---|
| 752 | SECTIONS |
---|
| 753 | @{ |
---|
| 754 | .text : |
---|
| 755 | @{ |
---|
| 756 | CREATE_OBJECT_SYMBOLS |
---|
| 757 | *(.text) |
---|
| 758 | etext = .; |
---|
| 759 | __CTOR_LIST__ = .; |
---|
| 760 | LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) |
---|
| 761 | *(.ctors) |
---|
| 762 | LONG(0) |
---|
| 763 | __CTOR_END__ = .; |
---|
| 764 | __DTOR_LIST__ = .; |
---|
| 765 | LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) |
---|
| 766 | *(.dtors) |
---|
| 767 | LONG(0) |
---|
| 768 | __DTOR_END__ = .; |
---|
| 769 | *(.lit) |
---|
| 770 | *(.shdata) |
---|
| 771 | @} > ram |
---|
| 772 | .shbss SIZEOF(.text) + ADDR(.text) : @{ |
---|
| 773 | *(.shbss) |
---|
| 774 | @} |
---|
| 775 | @end smallexample |
---|
| 776 | |
---|
| 777 | Set up the @code{.text} section. In a @code{COFF} file, .text is where |
---|
| 778 | all the actual instructions are. This also sets up the @emph{CONTRUCTOR} |
---|
| 779 | and the @emph{DESTRUCTOR} tables for @code{G++}. Notice that the section |
---|
| 780 | description redirects itself to the @emph{ram} variable setup earlier. |
---|
| 781 | |
---|
| 782 | @smallexample |
---|
| 783 | .talias : @{ @} > ram |
---|
| 784 | .data : @{ |
---|
| 785 | *(.data) |
---|
| 786 | CONSTRUCTORS |
---|
| 787 | _edata = .; |
---|
| 788 | @} > ram |
---|
| 789 | @end smallexample |
---|
| 790 | |
---|
| 791 | Setup the @code{.data} section. In a @code{coff} file, this is where all |
---|
| 792 | he initialized data goes. @code{CONSTRUCTORS} is a special command used |
---|
| 793 | by @code{ld}. |
---|
| 794 | |
---|
| 795 | @smallexample |
---|
| 796 | .bss SIZEOF(.data) + ADDR(.data) : |
---|
| 797 | @{ |
---|
| 798 | __bss_start = ALIGN(0x8); |
---|
| 799 | *(.bss) |
---|
| 800 | *(COMMON) |
---|
| 801 | end = ALIGN(0x8); |
---|
| 802 | _end = ALIGN(0x8); |
---|
| 803 | __end = ALIGN(0x8); |
---|
| 804 | @} |
---|
| 805 | .mstack : @{ @} > ram |
---|
| 806 | .rstack : @{ @} > ram |
---|
| 807 | .stab . (NOLOAD) : |
---|
| 808 | @{ |
---|
| 809 | [ .stab ] |
---|
| 810 | @} |
---|
| 811 | .stabstr . (NOLOAD) : |
---|
| 812 | @{ |
---|
| 813 | [ .stabstr ] |
---|
| 814 | @} |
---|
| 815 | @} |
---|
| 816 | @end smallexample |
---|
| 817 | |
---|
| 818 | Setup the @code{.bss} section. In a @code{COFF} file, this is where |
---|
| 819 | unitialized data goes. The symbols @code{_bss_start} and @code{_end} |
---|
| 820 | are setup here for use by the @code{crt0.o} when it zero's the |
---|
| 821 | @code{.bss} section. |
---|
| 822 | |
---|
| 823 | |
---|
| 824 | @node What to do now, Libc, Linker Scripts, Libraries |
---|
| 825 | @section What to do when you have a binary image |
---|
| 826 | |
---|
| 827 | A few ROM monitors load binary images, typically @code{a.out}, but most all |
---|
| 828 | will load an @code{srecord}. An srecord is an ASCII representation of a binary |
---|
| 829 | image. At it's simplest, an srecord is an address, followed by a byte |
---|
| 830 | count, followed by the bytes, and a 2's compliment checksum. A whole |
---|
| 831 | srecord file has an optional @emph{start} record, and a required @emph{end} |
---|
| 832 | record. To make an srecord from a binary image, the GNU @code{objcopy} program |
---|
| 833 | is used. This will read the image and make an srecord from it. To do |
---|
| 834 | this, invoke objcopy like this: @code{objcopy -O srec infile outfile}. Most |
---|
| 835 | PROM burners also read srecords or a similar format. Use @code{objdump -i} to |
---|
| 836 | get a list of support object files types for your architecture. |
---|
| 837 | |
---|
| 838 | @node Libc, , What to do now, Libraries |
---|
| 839 | @section Libraries |
---|
| 840 | |
---|
| 841 | This describes @code{newlib}, a freely available libc replacement. Most |
---|
| 842 | applications use calls in the standard C library. When initially linking |
---|
| 843 | in libc.a, several I/O functions are undefined. If you don't plan on |
---|
| 844 | doing any I/O, then you're OK, otherwise they need to be created. These |
---|
| 845 | routines are read, write, open, close. sbrk, and kill. Open & close |
---|
| 846 | don't need to be fully supported unless you have a filesystems, so |
---|
| 847 | typically they are stubbed out. Kill is also a stub, since you can't do |
---|
| 848 | process control on an embedded system. |
---|
| 849 | |
---|
| 850 | Sbrk() is only needed by applications that do dynamic memory |
---|
| 851 | allocation. It's uses the symbol @code{_end} that is setup in the linker |
---|
| 852 | script. It also requires a compile time option to set the upper size |
---|
| 853 | limit on the heap space. This leaves us with read and write, which are |
---|
| 854 | required for serial I/O. Usually these two routines are written in C, |
---|
| 855 | and call a lower level function for the actual I/O operation. These two |
---|
| 856 | lowest level I/O primitives are inbyte() and outbyte(), and are also |
---|
| 857 | used by GDB back ends if you've written an exception handler. Some |
---|
| 858 | systems also implement a havebyte() for input as well. |
---|
| 859 | |
---|
| 860 | Other commonly included functions are routines for manipulating |
---|
| 861 | LED's on the target (if they exist) or low level debug help. Typically a |
---|
| 862 | putnum() for printing words and bytes as a hex number is helpful, as |
---|
| 863 | well as a low-level print() to output simple strings. |
---|
| 864 | |
---|
| 865 | As libg++ uses the I/O routines in libc.a, if read and write work, |
---|
| 866 | then libg++ will also work with no additional changes. |
---|
| 867 | |
---|
| 868 | @menu |
---|
| 869 | * I/O Support:: Functions that make serial I/O work. |
---|
| 870 | * Memory Support:: Memory support. |
---|
| 871 | * Misc Support:: Other needed functions. |
---|
| 872 | * Debugging:: Useful Debugging Functions |
---|
| 873 | @end menu |
---|
| 874 | |
---|
| 875 | @node I/O Support, Memory Support, , Libc |
---|
| 876 | @subsection Making I/O work |
---|
| 877 | |
---|
| 878 | @node Memory Support, Misc Support, I/O Support, Libc |
---|
| 879 | @subsection Routines for dynamic memory allocation |
---|
| 880 | To support using any of the memory functions, you need to implement |
---|
| 881 | sbrk(). @code{malloc()}, @code{calloc()}, and @code{realloc()} all call |
---|
| 882 | @code{sbrk()} at there lowest level. @code{caddr_t} is defined elsewhere |
---|
| 883 | as @code{char *}. @code{RAMSIZE} is presently a compile time option. All |
---|
| 884 | this does is move a pointer to heap memory and check for the upper |
---|
| 885 | limit. @ref{glue.c,,Example libc support code}. @code{sbrk()} returns a |
---|
| 886 | pointer to the previous value before more memory was allocated. |
---|
| 887 | |
---|
| 888 | @smallexample |
---|
| 889 | /* _end is set in the linker command file * |
---|
| 890 | extern caddr_t _end;/ |
---|
| 891 | |
---|
| 892 | /* just in case, most boards have at least some memory */ |
---|
| 893 | #ifndef RAMSIZE |
---|
| 894 | # define RAMSIZE (caddr_t)0x100000 |
---|
| 895 | #endif |
---|
| 896 | |
---|
| 897 | /* |
---|
| 898 | * sbrk -- changes heap size size. Get nbytes more |
---|
| 899 | * RAM. We just increment a pointer in what's |
---|
| 900 | * left of memory on the board. |
---|
| 901 | */ |
---|
| 902 | caddr_t |
---|
| 903 | sbrk(nbytes) |
---|
| 904 | int nbytes; |
---|
| 905 | @{ |
---|
| 906 | static caddr_t heap_ptr = NULL; |
---|
| 907 | caddr_t base; |
---|
| 908 | |
---|
| 909 | if (heap_ptr == NULL) @{ |
---|
| 910 | heap_ptr = (caddr_t)&_end; |
---|
| 911 | @} |
---|
| 912 | |
---|
| 913 | if ((RAMSIZE - heap_ptr) >= 0) @{ |
---|
| 914 | base = heap_ptr; |
---|
| 915 | heap_ptr += nbytes; |
---|
| 916 | return (base); |
---|
| 917 | @} else @{ |
---|
| 918 | errno = ENOMEM; |
---|
| 919 | return ((caddr_t)-1); |
---|
| 920 | @} |
---|
| 921 | @} |
---|
| 922 | @end smallexample |
---|
| 923 | |
---|
| 924 | @node Misc Support, Debugging, Memory Support, Libc |
---|
| 925 | @subsection Misc support routines |
---|
| 926 | |
---|
| 927 | These are called by @code{newlib} but don't apply to the embedded |
---|
| 928 | environment. @code{isatty()} is self explanatory. @code{kill()} doesn't |
---|
| 929 | apply either in an environment withno process control, so it justs |
---|
| 930 | exits, which is a similar enough behavior. @code{getpid()} can safely |
---|
| 931 | return any value greater than 1. The value doesn't effect anything in |
---|
| 932 | @code{newlib} because once again there is no process control. |
---|
| 933 | |
---|
| 934 | @smallexample |
---|
| 935 | /* |
---|
| 936 | * isatty -- returns 1 if connected to a terminal device, |
---|
| 937 | * returns 0 if not. Since we're hooked up to a |
---|
| 938 | * serial port, we'll say yes and return a 1. |
---|
| 939 | */ |
---|
| 940 | int |
---|
| 941 | isatty(fd) |
---|
| 942 | int fd; |
---|
| 943 | @{ |
---|
| 944 | return (1); |
---|
| 945 | @} |
---|
| 946 | |
---|
| 947 | /* |
---|
| 948 | * getpid -- only one process, so just return 1. |
---|
| 949 | */ |
---|
| 950 | #define __MYPID 1 |
---|
| 951 | int |
---|
| 952 | getpid() |
---|
| 953 | @{ |
---|
| 954 | return __MYPID; |
---|
| 955 | @} |
---|
| 956 | |
---|
| 957 | /* |
---|
| 958 | * kill -- go out via exit... |
---|
| 959 | */ |
---|
| 960 | int |
---|
| 961 | kill(pid, sig) |
---|
| 962 | int pid; |
---|
| 963 | int sig; |
---|
| 964 | @{ |
---|
| 965 | if(pid == __MYPID) |
---|
| 966 | _exit(sig); |
---|
| 967 | return 0; |
---|
| 968 | @} |
---|
| 969 | @end smallexample |
---|
| 970 | |
---|
| 971 | @node Debugging, , Misc Support, Libc |
---|
| 972 | @subsection Useful debugging functions |
---|
| 973 | |
---|
| 974 | There are always a few useful functions for debugging your project in |
---|
| 975 | progress. I typically implement a simple @code{print()} routine that |
---|
| 976 | runs standalone in liblgoss, with no @code{newlib} support. The I/O |
---|
| 977 | function @code{outbyte()} can also be used for low level debugging. Many |
---|
| 978 | times print will work when there are problems that cause @code{printf()} to |
---|
| 979 | cause an exception. @code{putnum()} is just to print out values in hex |
---|
| 980 | so they are easier to read. |
---|
| 981 | |
---|
| 982 | @smallexample |
---|
| 983 | /* |
---|
| 984 | * print -- do a raw print of a string |
---|
| 985 | */ |
---|
| 986 | int |
---|
| 987 | print(ptr) |
---|
| 988 | char *ptr; |
---|
| 989 | @{ |
---|
| 990 | while (*ptr) @{ |
---|
| 991 | outbyte (*ptr++); |
---|
| 992 | @} |
---|
| 993 | @} |
---|
| 994 | |
---|
| 995 | /* |
---|
| 996 | * putnum -- print a 32 bit number in hex |
---|
| 997 | */ |
---|
| 998 | int |
---|
| 999 | putnum (num) |
---|
| 1000 | unsigned int num; |
---|
| 1001 | @{ |
---|
| 1002 | char buffer[9]; |
---|
| 1003 | int count; |
---|
| 1004 | char *bufptr = buffer; |
---|
| 1005 | int digit; |
---|
| 1006 | |
---|
| 1007 | for (count = 7 ; count >= 0 ; count--) @{ |
---|
| 1008 | digit = (num >> (count * 4)) & 0xf; |
---|
| 1009 | |
---|
| 1010 | if (digit <= 9) |
---|
| 1011 | *bufptr++ = (char) ('0' + digit); |
---|
| 1012 | else |
---|
| 1013 | *bufptr++ = (char) ('a' - 10 + digit); |
---|
| 1014 | @} |
---|
| 1015 | |
---|
| 1016 | *bufptr = (char) 0; |
---|
| 1017 | print (buffer); |
---|
| 1018 | return; |
---|
| 1019 | @} |
---|
| 1020 | @end smallexample |
---|
| 1021 | |
---|
| 1022 | If there are LEDs on the board, they can also be put to use for |
---|
| 1023 | debugging when the serial I/O code is being written. I usually implement |
---|
| 1024 | a @code{zylons()} function, which strobes the LEDS (if there is more |
---|
| 1025 | than one) in sequence, creating a rotating effect. This is convenient |
---|
| 1026 | between I/O to see if the target is still alive. Another useful LED |
---|
| 1027 | function is @code{led_putnum()}, which takes a digit and displays it as |
---|
| 1028 | a bit pattern or number. These usually have to be written in assembler |
---|
| 1029 | for each target board. Here are a number of C based routines that may be |
---|
| 1030 | useful. |
---|
| 1031 | |
---|
| 1032 | @code{led_putnum()} puts a number on a single digit segmented |
---|
| 1033 | LED display. This LED is set by setting a bit mask to an address, where |
---|
| 1034 | 1 turns the segment off, and 0 turns it on. There is also a little |
---|
| 1035 | decimal point on the LED display, so it gets the leftmost bit. The other |
---|
| 1036 | bits specify the segment location. The bits look like: |
---|
| 1037 | |
---|
| 1038 | @smallexample |
---|
| 1039 | [d.p | g | f | e | d | c | b | a ] is the byte. |
---|
| 1040 | @end smallexample |
---|
| 1041 | |
---|
| 1042 | The locations are set up as: |
---|
| 1043 | |
---|
| 1044 | @smallexample |
---|
| 1045 | a |
---|
| 1046 | ----- |
---|
| 1047 | f | | b |
---|
| 1048 | | g | |
---|
| 1049 | ----- |
---|
| 1050 | | | |
---|
| 1051 | e | | c |
---|
| 1052 | ----- |
---|
| 1053 | d |
---|
| 1054 | @end smallexample |
---|
| 1055 | |
---|
| 1056 | This takes a number that's already been converted to a string, and |
---|
| 1057 | prints it. |
---|
| 1058 | |
---|
| 1059 | @smallexample |
---|
| 1060 | #define LED_ADDR 0xd00003 |
---|
| 1061 | |
---|
| 1062 | void |
---|
| 1063 | led_putnum ( num ) |
---|
| 1064 | char num; |
---|
| 1065 | @{ |
---|
| 1066 | static unsigned char *leds = (unsigned char *)LED_ADDR; |
---|
| 1067 | static unsigned char num_bits [18] = @{ |
---|
| 1068 | 0xff, /* clear all */ |
---|
| 1069 | 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */ |
---|
| 1070 | 0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */ |
---|
| 1071 | @}; |
---|
| 1072 | |
---|
| 1073 | if (num >= '0' && num <= '9') |
---|
| 1074 | num = (num - '0') + 1; |
---|
| 1075 | |
---|
| 1076 | if (num >= 'a' && num <= 'f') |
---|
| 1077 | num = (num - 'a') + 12; |
---|
| 1078 | |
---|
| 1079 | if (num == ' ') |
---|
| 1080 | num = 0; |
---|
| 1081 | |
---|
| 1082 | *leds = num_bits[num]; |
---|
| 1083 | @} |
---|
| 1084 | |
---|
| 1085 | /* |
---|
| 1086 | * zylons -- draw a rotating pattern. NOTE: this function never returns. |
---|
| 1087 | */ |
---|
| 1088 | void |
---|
| 1089 | zylons() |
---|
| 1090 | @{ |
---|
| 1091 | unsigned char *leds = (unsigned char *)LED_ADDR; |
---|
| 1092 | unsigned char curled = 0xfe; |
---|
| 1093 | |
---|
| 1094 | while (1) |
---|
| 1095 | @{ |
---|
| 1096 | *leds = curled; |
---|
| 1097 | curled = (curled >> 1) | (curled << 7); |
---|
| 1098 | delay ( 200 ); |
---|
| 1099 | @} |
---|
| 1100 | @} |
---|
| 1101 | @end smallexample |
---|
| 1102 | |
---|
| 1103 | |
---|
| 1104 | @node GDB, Binutils, Libraries, Top |
---|
| 1105 | @chapter Writing a new GDB backend |
---|
| 1106 | |
---|
| 1107 | Typically, either the low-level I/O routines are used for debugging, or |
---|
| 1108 | LEDs, if present. It is much easier to use GDb for debugging an |
---|
| 1109 | application. There are several different techniques used to have GDB work |
---|
| 1110 | remotely. Commonly more than one kind of GDB interface is used to cober |
---|
| 1111 | a wide variety of development needs. |
---|
| 1112 | |
---|
| 1113 | The most common style of GDB backend is an exception handler for |
---|
| 1114 | breakpoints. This is also called a @emph{gdb stub}, and is requires the |
---|
| 1115 | two additional lines of init code in your @code{main()} routine. The GDB |
---|
| 1116 | stubs all use the GDB @emph{remote protocol}. When the application gets a |
---|
| 1117 | breakpoint exception, it communicates to GDB on the host. |
---|
| 1118 | |
---|
| 1119 | Another common style of interfacing GDB to a target is by using an |
---|
| 1120 | existing ROM monitor. These break down into two main kinds, a similar |
---|
| 1121 | protocol to the GDB remote protocol, and an interface that uses the ROM |
---|
| 1122 | monitor directly. This kind has GDB simulating a human operator, and all |
---|
| 1123 | GDB does is work as a command formatter and parser. |
---|
| 1124 | |
---|
| 1125 | @menu |
---|
| 1126 | * GNU remote protocol:: The standard remote protocol. |
---|
| 1127 | * Exception handler:: A linked in exception handler. |
---|
| 1128 | * ROM monitors:: Using a ROM monitor as a backend. |
---|
| 1129 | * Other remote protocols:: Adding support for new protocols. |
---|
| 1130 | @end menu |
---|
| 1131 | |
---|
| 1132 | @node GNU remote protocol, Exception handler, ,GDB |
---|
| 1133 | @section The standard remote protocol |
---|
| 1134 | |
---|
| 1135 | The standard remote protocol is a simple, packet based scheme. A debug |
---|
| 1136 | packet whose contents are @emph{<data>} is encapsulated for transmission |
---|
| 1137 | in the form: |
---|
| 1138 | |
---|
| 1139 | @smallexample |
---|
| 1140 | $ <data> # CSUM1 CSUM2 |
---|
| 1141 | @end smallexample |
---|
| 1142 | |
---|
| 1143 | @emph{<data>} must be ASCII alphanumeric and cannot include characters |
---|
| 1144 | @code{$} or @code{#}. If @emph{<data>} starts with two characters |
---|
| 1145 | followed by @code{:}, then the existing stubs interpret this as a |
---|
| 1146 | sequence number. For example, the command @code{g} is used to read the |
---|
| 1147 | values of the registers. So, a packet to do this would look like |
---|
| 1148 | |
---|
| 1149 | @smallexample |
---|
| 1150 | $g#67 |
---|
| 1151 | @end smallexample |
---|
| 1152 | |
---|
| 1153 | @emph{CSUM1} and @emph{CSUM2} are an ascii representation in hex of an |
---|
| 1154 | 8-bit checksum of @emph{<data>}, the most significant nibble is sent first. |
---|
| 1155 | the hex digits 0-9,a-f are used. |
---|
| 1156 | |
---|
| 1157 | A simple protocol is used when communicating with the target. This is |
---|
| 1158 | mainly to give a degree of error handling over the serial cable. For |
---|
| 1159 | each packet transmitted successfully, the target responds with a |
---|
| 1160 | @code{+} (@code{ACK}). If there was a transmission error, then the target |
---|
| 1161 | responds with a @code{-} (@code{NAK}). An error is determined when the |
---|
| 1162 | checksum doesn't match the calculated checksum for that data record. |
---|
| 1163 | Upon reciept of the @code{ACK}, @code{GDB} can then transmit the next |
---|
| 1164 | packet. |
---|
| 1165 | |
---|
| 1166 | Here is a list of the main functions that need to be supported. Each data |
---|
| 1167 | packet is a command with a set number of bytes in the command packet. |
---|
| 1168 | Most commands either return data, or respond with a @code{NAK}. Commands |
---|
| 1169 | that don't return data respond with an @code{ACK}. All data values are |
---|
| 1170 | ascii hex digits. Every byte needs two hex digits to represent t. This |
---|
| 1171 | means that a byte with the value @samp{7} becomes @samp{07}. On a 32 bit |
---|
| 1172 | machine this works out to 8 characters per word. All of the bytes in a |
---|
| 1173 | word are stored in the target byte order. When writing the host side of |
---|
| 1174 | the GDB protocol, be careful of byte order, and make sure that the code |
---|
| 1175 | will run on both big and little endian hosts and produce the same answers. |
---|
| 1176 | |
---|
| 1177 | These functions are the minimum required to make a GDB backend work. All |
---|
| 1178 | other commands are optional, and not supported by all GDB backends. |
---|
| 1179 | |
---|
| 1180 | @table @samp |
---|
| 1181 | @item read registers @code{g} |
---|
| 1182 | |
---|
| 1183 | returns @code{XXXXXXXX...} |
---|
| 1184 | |
---|
| 1185 | Registers are in the internal order for GDB, and the bytes in a register |
---|
| 1186 | are in the same order the machine uses. All values are in sequence |
---|
| 1187 | starting with register 0. All registers are listed in the same packet. A |
---|
| 1188 | sample packet would look like @code{$g#}. |
---|
| 1189 | |
---|
| 1190 | @item write registers @code{GXXXXXXXX...} |
---|
| 1191 | @code{XXXXXXXX} is the value to set the register to. Registers are in |
---|
| 1192 | the internal order for GDB, and the bytes in a register are in the same |
---|
| 1193 | order the machine uses. All values are in sequence starting with |
---|
| 1194 | register 0. All registers values are listed in the same packet. A sample |
---|
| 1195 | packet would look like @code{$G000000001111111122222222...#} |
---|
| 1196 | |
---|
| 1197 | returns @code{ACK} or @code{NAK} |
---|
| 1198 | |
---|
| 1199 | @item read memory @code{mAAAAAAAA,LLLL} |
---|
| 1200 | @code{AAAAAAAA} is address, @code{LLLL} is length. A sample packet would |
---|
| 1201 | look like @code{$m00005556,0024#}. This would request 24 bytes starting |
---|
| 1202 | at address @emph{00005556} |
---|
| 1203 | |
---|
| 1204 | returns @code{XXXXXXXX...} |
---|
| 1205 | @code{XXXXXXXX} is the memory contents. Fewer bytes than requested will |
---|
| 1206 | be returned if only part of the data can be read. This can be determined |
---|
| 1207 | by counting the values till the end of packet @code{#} is seen and |
---|
| 1208 | comparing that with the total count of bytes that was requested. |
---|
| 1209 | |
---|
| 1210 | @item write memory @code{MAAAAAAAA,LLLL:XXXXXXXX} |
---|
| 1211 | @code{AAAAAAAA} is the starting address, @code{LLLL} is the number of |
---|
| 1212 | bytes to be written, and @code{XXXXXXXX} is value to be written. A |
---|
| 1213 | sample packet would look like |
---|
| 1214 | @code{$M00005556,0024:101010101111111100000000...#} |
---|
| 1215 | |
---|
| 1216 | returns @code{ACK} or @code{NAK} for an error. @code{NAK} is also |
---|
| 1217 | returned when only part of the data is written. |
---|
| 1218 | |
---|
| 1219 | @item continue @code{cAAAAAAAAA} |
---|
| 1220 | @code{AAAAAAAA} is address to resume execution at. If @code{AAAAAAAA} is |
---|
| 1221 | omitted, resume at the curent address of the @code{pc} register. |
---|
| 1222 | |
---|
| 1223 | returns the same replay as @code{last signal}. There is no immediate |
---|
| 1224 | replay to @code{cont} until the next breakpoint is reached, and the |
---|
| 1225 | program stops executing. |
---|
| 1226 | |
---|
| 1227 | @item step sAA..AA |
---|
| 1228 | @code{AA..AA} is address to resume |
---|
| 1229 | If @code{AA..AA} is omitted, resume at same address. |
---|
| 1230 | |
---|
| 1231 | returns the same replay as @code{last signal}. There is no immediate |
---|
| 1232 | replay to @code{step} until the next breakpoint is reached, and the |
---|
| 1233 | program stops executing. |
---|
| 1234 | |
---|
| 1235 | @item last signal @code{?} |
---|
| 1236 | |
---|
| 1237 | This returns one of the following: |
---|
| 1238 | |
---|
| 1239 | @itemize @bullet |
---|
| 1240 | @item @code{SAA} |
---|
| 1241 | Where @code{AA} is the number of the last signal. |
---|
| 1242 | Exceptions on the target are converted to the most similar Unix style |
---|
| 1243 | signal number, like @code{SIGSEGV}. A sample response of this type would |
---|
| 1244 | look like @code{$S05#}. |
---|
| 1245 | |
---|
| 1246 | @item TAAnn:XXXXXXXX;nn:XXXXXXXX;nn:XXXXXXXX; |
---|
| 1247 | @code{AA} is the signal number. |
---|
| 1248 | @code{nn} is the register number. |
---|
| 1249 | @code{XXXXXXXX} is the register value. |
---|
| 1250 | |
---|
| 1251 | @item WAA |
---|
| 1252 | The process exited, and @code{AA} is the exit status. This is only |
---|
| 1253 | applicable for certains sorts of targets. |
---|
| 1254 | |
---|
| 1255 | @end itemize |
---|
| 1256 | |
---|
| 1257 | These are used in some GDB backends, but not all. |
---|
| 1258 | |
---|
| 1259 | @item write reg @code{Pnn=XXXXXXXX} |
---|
| 1260 | Write register @code{nn} with value @code{XXXXXXXX}. |
---|
| 1261 | |
---|
| 1262 | returns @code{ACK} or @code{NAK} |
---|
| 1263 | |
---|
| 1264 | @item kill request k |
---|
| 1265 | |
---|
| 1266 | @item toggle debug d |
---|
| 1267 | toggle debug flag (see 386 & 68k stubs) |
---|
| 1268 | |
---|
| 1269 | @item reset r |
---|
| 1270 | reset -- see sparc stub. |
---|
| 1271 | |
---|
| 1272 | @item reserved @code{other} |
---|
| 1273 | On other requests, the stub should ignore the request and send an empty |
---|
| 1274 | response @code{$#<checksum>}. This way we can extend the protocol and GDB |
---|
| 1275 | can tell whether the stub it is talking to uses the old or the new. |
---|
| 1276 | |
---|
| 1277 | @item search @code{tAA:PP,MM} |
---|
| 1278 | Search backwards starting at address @code{AA} for a match with pattern |
---|
| 1279 | PP and mask @code{MM}. @code{PP} and @code{MM} are 4 bytes. |
---|
| 1280 | |
---|
| 1281 | @item general query @code{qXXXX} |
---|
| 1282 | Request info about XXXX. |
---|
| 1283 | |
---|
| 1284 | @item general set @code{QXXXX=yyyy} |
---|
| 1285 | Set value of @code{XXXX} to @code{yyyy}. |
---|
| 1286 | |
---|
| 1287 | @item query sect offs @code{qOffsets} |
---|
| 1288 | Get section offsets. Reply is @code{Text=xxx;Data=yyy;Bss=zzz} |
---|
| 1289 | |
---|
| 1290 | @item console output Otext |
---|
| 1291 | Send text to stdout. The text gets display from the target side of the |
---|
| 1292 | serial connection. |
---|
| 1293 | |
---|
| 1294 | @end table |
---|
| 1295 | |
---|
| 1296 | Responses can be run-length encoded to save space. A @code{*}means that |
---|
| 1297 | the next character is an ASCII encoding giving a repeat count which |
---|
| 1298 | stands for that many repetitions of the character preceding the @code{*}. |
---|
| 1299 | The encoding is n+29, yielding a printable character where n >=3 |
---|
| 1300 | (which is where run length encoding starts to win). You can't use a |
---|
| 1301 | value of where n >126 because it's only a two byte value. An example |
---|
| 1302 | would be a @code{0*03} means the same thing as @code{0000}. |
---|
| 1303 | |
---|
| 1304 | @node Exception handler, ROM monitors, GNU remote protocol, GDB |
---|
| 1305 | @section A linked in exception handler |
---|
| 1306 | |
---|
| 1307 | A @emph{GDB stub} consists of two parts, support for the exception |
---|
| 1308 | handler, and the exception handler itself. The exception handler needs |
---|
| 1309 | to communicate to GDB on the host whenever there is a breakpoint |
---|
| 1310 | exception. When GDB starts a program running on the target, it's polling |
---|
| 1311 | the serial port during execution looking for any debug packets. So when |
---|
| 1312 | a breakpoint occurs, the exception handler needs to save state, and send |
---|
| 1313 | a GDB remote protocol packet to GDB on the host. GDB takes any output |
---|
| 1314 | that isn't a debug command packet and displays it in the command window. |
---|
| 1315 | |
---|
| 1316 | Support for the exception handler varies between processors, but the |
---|
| 1317 | minimum supported functions are those needed by GDB. These are functions |
---|
| 1318 | to support the reading and writing of registers, the reading and writing |
---|
| 1319 | of memory, start execution at an address, single step, and last signal. |
---|
| 1320 | Sometimes other functions for adjusting the baud rate, or resetting the |
---|
| 1321 | hardware are implemented. |
---|
| 1322 | |
---|
| 1323 | Once GDB gets the command packet from the breakpoint, it will read a few |
---|
| 1324 | registers and memory locations an then wait for the user. When the user |
---|
| 1325 | types @code{run} or @code{continue} a @code{continue} command is issued |
---|
| 1326 | to the backend, and control returns from the breakpoint routine to the |
---|
| 1327 | application. |
---|
| 1328 | |
---|
| 1329 | @node ROM monitors, Other remote protocols, Exception handler, GDB |
---|
| 1330 | @section Using a ROM monitor as a backend |
---|
| 1331 | GDB also can mimic a human user and use a ROM monitors normal debug |
---|
| 1332 | commands as a backend. This consists mostly of sending and parsing |
---|
| 1333 | @code{ASCII} strings. All the ROM monitor interfaces share a common set |
---|
| 1334 | of routines in @code{gdb/monitor.c}. This supports adding new ROM |
---|
| 1335 | monitor interfaces by filling in a structure with the common commands |
---|
| 1336 | GDB needs. GDb already supports several command ROM monitors, including |
---|
| 1337 | Motorola's @code{Bug} monitor for their VME boards, and the Rom68k |
---|
| 1338 | monitor by Integrated Systems, Inc. for various m68k based boards. GDB |
---|
| 1339 | also supports the custom ROM monitors on the WinBond and Oki PA based |
---|
| 1340 | targets. There is builtin support for loading files to ROM monitors |
---|
| 1341 | specifically. GDB can convert a binary into an srecord and then load it |
---|
| 1342 | as an ascii file, or using @code{xmodem}. |
---|
| 1343 | |
---|
| 1344 | @c FIXME: do I need trademark somethings here ? Is Integrated the right |
---|
| 1345 | @c company? |
---|
| 1346 | |
---|
| 1347 | @node Other remote protocols, ,ROM monitors, GDB |
---|
| 1348 | @section Adding support for new protocols |
---|
| 1349 | @c FIXME: write something here |
---|
| 1350 | |
---|
| 1351 | @node Binutils, Code Listings, GDB, Top |
---|
| 1352 | |
---|
| 1353 | @node Code Listings, idp.ld, Binutils, Top |
---|
| 1354 | @appendix Code Listings |
---|
| 1355 | |
---|
| 1356 | @menu |
---|
| 1357 | * idp.ld:: A m68k linker script. |
---|
| 1358 | * crt0.S:: Crt0.S for an m68k. |
---|
| 1359 | * glue.c:: C based support for for Stdio functions. |
---|
| 1360 | * mvme.S:: Rom monitor based I/O support in assembler. |
---|
| 1361 | * io.c:: C based for memory mapped I/O. |
---|
| 1362 | * leds.c:: C based LED routines. |
---|
| 1363 | @end menu |
---|
| 1364 | |
---|
| 1365 | @node idp.ld, crt0.S, Code Listings, Code Listings |
---|
| 1366 | @section Linker script for the IDP board |
---|
| 1367 | |
---|
| 1368 | This is the linker script script that is used on the Motorola IDP board. |
---|
| 1369 | |
---|
| 1370 | @example |
---|
| 1371 | STARTUP(crt0.o) |
---|
| 1372 | OUTPUT_ARCH(m68k) |
---|
| 1373 | INPUT(idp.o) |
---|
| 1374 | SEARCH_DIR(.) |
---|
| 1375 | __DYNAMIC = 0; |
---|
| 1376 | /* |
---|
| 1377 | * Setup the memory map of the MC68ec0x0 Board (IDP) |
---|
| 1378 | * stack grows up towards high memory. This works for |
---|
| 1379 | * both the rom68k and the mon68k monitors. |
---|
| 1380 | */ |
---|
| 1381 | MEMORY |
---|
| 1382 | @{ |
---|
| 1383 | ram : ORIGIN = 0x10000, LENGTH = 2M |
---|
| 1384 | @} |
---|
| 1385 | /* |
---|
| 1386 | * stick everything in ram (of course) |
---|
| 1387 | */ |
---|
| 1388 | SECTIONS |
---|
| 1389 | @{ |
---|
| 1390 | .text : |
---|
| 1391 | @{ |
---|
| 1392 | CREATE_OBJECT_SYMBOLS |
---|
| 1393 | *(.text) |
---|
| 1394 | etext = .; |
---|
| 1395 | __CTOR_LIST__ = .; |
---|
| 1396 | LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) |
---|
| 1397 | *(.ctors) |
---|
| 1398 | LONG(0) |
---|
| 1399 | __CTOR_END__ = .; |
---|
| 1400 | __DTOR_LIST__ = .; |
---|
| 1401 | LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) |
---|
| 1402 | *(.dtors) |
---|
| 1403 | LONG(0) |
---|
| 1404 | __DTOR_END__ = .; |
---|
| 1405 | *(.lit) |
---|
| 1406 | *(.shdata) |
---|
| 1407 | @} > ram |
---|
| 1408 | .shbss SIZEOF(.text) + ADDR(.text) : @{ |
---|
| 1409 | *(.shbss) |
---|
| 1410 | @} |
---|
| 1411 | .talias : @{ @} > ram |
---|
| 1412 | .data : @{ |
---|
| 1413 | *(.data) |
---|
| 1414 | CONSTRUCTORS |
---|
| 1415 | _edata = .; |
---|
| 1416 | @} > ram |
---|
| 1417 | |
---|
| 1418 | .bss SIZEOF(.data) + ADDR(.data) : |
---|
| 1419 | @{ |
---|
| 1420 | __bss_start = ALIGN(0x8); |
---|
| 1421 | *(.bss) |
---|
| 1422 | *(COMMON) |
---|
| 1423 | end = ALIGN(0x8); |
---|
| 1424 | _end = ALIGN(0x8); |
---|
| 1425 | __end = ALIGN(0x8); |
---|
| 1426 | @} |
---|
| 1427 | .mstack : @{ @} > ram |
---|
| 1428 | .rstack : @{ @} > ram |
---|
| 1429 | .stab . (NOLOAD) : |
---|
| 1430 | @{ |
---|
| 1431 | [ .stab ] |
---|
| 1432 | @} |
---|
| 1433 | .stabstr . (NOLOAD) : |
---|
| 1434 | @{ |
---|
| 1435 | [ .stabstr ] |
---|
| 1436 | @} |
---|
| 1437 | @} |
---|
| 1438 | @end example |
---|
| 1439 | |
---|
| 1440 | @node crt0.S, glue.c, idp.ld, Code Listings |
---|
| 1441 | @section crt0.S - The startup file |
---|
| 1442 | |
---|
| 1443 | @example |
---|
| 1444 | /* |
---|
| 1445 | * crt0.S -- startup file for m68k-coff |
---|
| 1446 | * |
---|
| 1447 | */ |
---|
| 1448 | |
---|
| 1449 | .title "crt0.S for m68k-coff" |
---|
| 1450 | |
---|
| 1451 | /* These are predefined by new versions of GNU cpp. */ |
---|
| 1452 | |
---|
| 1453 | #ifndef __USER_LABEL_PREFIX__ |
---|
| 1454 | #define __USER_LABEL_PREFIX__ _ |
---|
| 1455 | #endif |
---|
| 1456 | |
---|
| 1457 | #ifndef __REGISTER_PREFIX__ |
---|
| 1458 | #define __REGISTER_PREFIX__ |
---|
| 1459 | #endif |
---|
| 1460 | |
---|
| 1461 | /* ANSI concatenation macros. */ |
---|
| 1462 | |
---|
| 1463 | #define CONCAT1(a, b) CONCAT2(a, b) |
---|
| 1464 | #define CONCAT2(a, b) a ## b |
---|
| 1465 | |
---|
| 1466 | /* Use the right prefix for global labels. */ |
---|
| 1467 | |
---|
| 1468 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) |
---|
| 1469 | |
---|
| 1470 | /* Use the right prefix for registers. */ |
---|
| 1471 | |
---|
| 1472 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) |
---|
| 1473 | |
---|
| 1474 | #define d0 REG (d0) |
---|
| 1475 | #define d1 REG (d1) |
---|
| 1476 | #define d2 REG (d2) |
---|
| 1477 | #define d3 REG (d3) |
---|
| 1478 | #define d4 REG (d4) |
---|
| 1479 | #define d5 REG (d5) |
---|
| 1480 | #define d6 REG (d6) |
---|
| 1481 | #define d7 REG (d7) |
---|
| 1482 | #define a0 REG (a0) |
---|
| 1483 | #define a1 REG (a1) |
---|
| 1484 | #define a2 REG (a2) |
---|
| 1485 | #define a3 REG (a3) |
---|
| 1486 | #define a4 REG (a4) |
---|
| 1487 | #define a5 REG (a5) |
---|
| 1488 | #define a6 REG (a6) |
---|
| 1489 | #define fp REG (fp) |
---|
| 1490 | #define sp REG (sp) |
---|
| 1491 | |
---|
| 1492 | /* |
---|
| 1493 | * Set up some room for a stack. We just grab a chunk of memory. |
---|
| 1494 | */ |
---|
| 1495 | .set stack_size, 0x2000 |
---|
| 1496 | .comm SYM (stack), stack_size |
---|
| 1497 | |
---|
| 1498 | /* |
---|
| 1499 | * Define an empty environment. |
---|
| 1500 | */ |
---|
| 1501 | .data |
---|
| 1502 | .align 2 |
---|
| 1503 | SYM (environ): |
---|
| 1504 | .long 0 |
---|
| 1505 | |
---|
| 1506 | .align 2 |
---|
| 1507 | .text |
---|
| 1508 | .global SYM (stack) |
---|
| 1509 | |
---|
| 1510 | .global SYM (main) |
---|
| 1511 | .global SYM (exit) |
---|
| 1512 | /* |
---|
| 1513 | * This really should be __bss_start, not SYM (__bss_start). |
---|
| 1514 | */ |
---|
| 1515 | .global __bss_start |
---|
| 1516 | |
---|
| 1517 | /* |
---|
| 1518 | * start -- set things up so the application will run. |
---|
| 1519 | */ |
---|
| 1520 | SYM (start): |
---|
| 1521 | link a6, #-8 |
---|
| 1522 | moveal #SYM (stack) + stack_size, sp |
---|
| 1523 | |
---|
| 1524 | /* |
---|
| 1525 | * zerobss -- zero out the bss section |
---|
| 1526 | */ |
---|
| 1527 | moveal #__bss_start, a0 |
---|
| 1528 | moveal #SYM (end), a1 |
---|
| 1529 | 1: |
---|
| 1530 | movel #0, (a0) |
---|
| 1531 | leal 4(a0), a0 |
---|
| 1532 | cmpal a0, a1 |
---|
| 1533 | bne 1b |
---|
| 1534 | |
---|
| 1535 | /* |
---|
| 1536 | * Call the main routine from the application to get it going. |
---|
| 1537 | * main (argc, argv, environ) |
---|
| 1538 | * We pass argv as a pointer to NULL. |
---|
| 1539 | */ |
---|
| 1540 | pea 0 |
---|
| 1541 | pea SYM (environ) |
---|
| 1542 | pea sp@@(4) |
---|
| 1543 | pea 0 |
---|
| 1544 | jsr SYM (main) |
---|
| 1545 | movel d0, sp@@- |
---|
| 1546 | |
---|
| 1547 | /* |
---|
| 1548 | * _exit -- Exit from the application. Normally we cause a user trap |
---|
| 1549 | * to return to the ROM monitor for another run. |
---|
| 1550 | */ |
---|
| 1551 | SYM (exit): |
---|
| 1552 | trap #0 |
---|
| 1553 | @end example |
---|
| 1554 | |
---|
| 1555 | @node glue.c, mvme.S, crt0.S, Code Listings |
---|
| 1556 | @section C based "glue" code. |
---|
| 1557 | |
---|
| 1558 | @example |
---|
| 1559 | |
---|
| 1560 | /* |
---|
| 1561 | * glue.c -- all the code to make GCC and the libraries run on |
---|
| 1562 | * a bare target board. These should work with any |
---|
| 1563 | * target if inbyte() and outbyte() exist. |
---|
| 1564 | */ |
---|
| 1565 | |
---|
| 1566 | #include <sys/types.h> |
---|
| 1567 | #include <sys/stat.h> |
---|
| 1568 | #include <errno.h> |
---|
| 1569 | #ifndef NULL |
---|
| 1570 | #define NULL 0 |
---|
| 1571 | #endif |
---|
| 1572 | |
---|
| 1573 | /* FIXME: this is a hack till libc builds */ |
---|
| 1574 | __main() |
---|
| 1575 | @{ |
---|
| 1576 | return; |
---|
| 1577 | @} |
---|
| 1578 | |
---|
| 1579 | #undef errno |
---|
| 1580 | int errno; |
---|
| 1581 | |
---|
| 1582 | extern caddr_t _end; /* _end is set in the linker command file */ |
---|
| 1583 | extern int outbyte(); |
---|
| 1584 | extern unsigned char inbyte(); |
---|
| 1585 | extern int havebyte(); |
---|
| 1586 | |
---|
| 1587 | /* just in case, most boards have at least some memory */ |
---|
| 1588 | #ifndef RAMSIZE |
---|
| 1589 | # define RAMSIZE (caddr_t)0x100000 |
---|
| 1590 | #endif |
---|
| 1591 | |
---|
| 1592 | /* |
---|
| 1593 | * read -- read bytes from the serial port. Ignore fd, since |
---|
| 1594 | * we only have stdin. |
---|
| 1595 | */ |
---|
| 1596 | int |
---|
| 1597 | read(fd, buf, nbytes) |
---|
| 1598 | int fd; |
---|
| 1599 | char *buf; |
---|
| 1600 | int nbytes; |
---|
| 1601 | @{ |
---|
| 1602 | int i = 0; |
---|
| 1603 | |
---|
| 1604 | for (i = 0; i < nbytes; i++) @{ |
---|
| 1605 | *(buf + i) = inbyte(); |
---|
| 1606 | if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) @{ |
---|
| 1607 | (*(buf + i)) = 0; |
---|
| 1608 | break; |
---|
| 1609 | @} |
---|
| 1610 | @} |
---|
| 1611 | return (i); |
---|
| 1612 | @} |
---|
| 1613 | |
---|
| 1614 | /* |
---|
| 1615 | * write -- write bytes to the serial port. Ignore fd, since |
---|
| 1616 | * stdout and stderr are the same. Since we have no filesystem, |
---|
| 1617 | * open will only return an error. |
---|
| 1618 | */ |
---|
| 1619 | int |
---|
| 1620 | write(fd, buf, nbytes) |
---|
| 1621 | int fd; |
---|
| 1622 | char *buf; |
---|
| 1623 | int nbytes; |
---|
| 1624 | @{ |
---|
| 1625 | int i; |
---|
| 1626 | |
---|
| 1627 | for (i = 0; i < nbytes; i++) @{ |
---|
| 1628 | if (*(buf + i) == '\n') @{ |
---|
| 1629 | outbyte ('\r'); |
---|
| 1630 | @} |
---|
| 1631 | outbyte (*(buf + i)); |
---|
| 1632 | @} |
---|
| 1633 | return (nbytes); |
---|
| 1634 | @} |
---|
| 1635 | |
---|
| 1636 | /* |
---|
| 1637 | * open -- open a file descriptor. We don't have a filesystem, so |
---|
| 1638 | * we return an error. |
---|
| 1639 | */ |
---|
| 1640 | int |
---|
| 1641 | open(buf, flags, mode) |
---|
| 1642 | char *buf; |
---|
| 1643 | int flags; |
---|
| 1644 | int mode; |
---|
| 1645 | @{ |
---|
| 1646 | errno = EIO; |
---|
| 1647 | return (-1); |
---|
| 1648 | @} |
---|
| 1649 | |
---|
| 1650 | /* |
---|
| 1651 | * close -- close a file descriptor. We don't need |
---|
| 1652 | * to do anything, but pretend we did. |
---|
| 1653 | */ |
---|
| 1654 | int |
---|
| 1655 | close(fd) |
---|
| 1656 | int fd; |
---|
| 1657 | @{ |
---|
| 1658 | return (0); |
---|
| 1659 | @} |
---|
| 1660 | |
---|
| 1661 | /* |
---|
| 1662 | * sbrk -- changes heap size size. Get nbytes more |
---|
| 1663 | * RAM. We just increment a pointer in what's |
---|
| 1664 | * left of memory on the board. |
---|
| 1665 | */ |
---|
| 1666 | caddr_t |
---|
| 1667 | sbrk(nbytes) |
---|
| 1668 | int nbytes; |
---|
| 1669 | @{ |
---|
| 1670 | static caddr_t heap_ptr = NULL; |
---|
| 1671 | caddr_t base; |
---|
| 1672 | |
---|
| 1673 | if (heap_ptr == NULL) @{ |
---|
| 1674 | heap_ptr = (caddr_t)&_end; |
---|
| 1675 | @} |
---|
| 1676 | |
---|
| 1677 | if ((RAMSIZE - heap_ptr) >= 0) @{ |
---|
| 1678 | base = heap_ptr; |
---|
| 1679 | heap_ptr += nbytes; |
---|
| 1680 | return (base); |
---|
| 1681 | @} else @{ |
---|
| 1682 | errno = ENOMEM; |
---|
| 1683 | return ((caddr_t)-1); |
---|
| 1684 | @} |
---|
| 1685 | @} |
---|
| 1686 | |
---|
| 1687 | /* |
---|
| 1688 | * isatty -- returns 1 if connected to a terminal device, |
---|
| 1689 | * returns 0 if not. Since we're hooked up to a |
---|
| 1690 | * serial port, we'll say yes and return a 1. |
---|
| 1691 | */ |
---|
| 1692 | int |
---|
| 1693 | isatty(fd) |
---|
| 1694 | int fd; |
---|
| 1695 | @{ |
---|
| 1696 | return (1); |
---|
| 1697 | @} |
---|
| 1698 | |
---|
| 1699 | /* |
---|
| 1700 | * lseek -- move read/write pointer. Since a serial port |
---|
| 1701 | * is non-seekable, we return an error. |
---|
| 1702 | */ |
---|
| 1703 | off_t |
---|
| 1704 | lseek(fd, offset, whence) |
---|
| 1705 | int fd; |
---|
| 1706 | off_t offset; |
---|
| 1707 | int whence; |
---|
| 1708 | @{ |
---|
| 1709 | errno = ESPIPE; |
---|
| 1710 | return ((off_t)-1); |
---|
| 1711 | @} |
---|
| 1712 | |
---|
| 1713 | /* |
---|
| 1714 | * fstat -- get status of a file. Since we have no file |
---|
| 1715 | * system, we just return an error. |
---|
| 1716 | */ |
---|
| 1717 | int |
---|
| 1718 | fstat(fd, buf) |
---|
| 1719 | int fd; |
---|
| 1720 | struct stat *buf; |
---|
| 1721 | @{ |
---|
| 1722 | errno = EIO; |
---|
| 1723 | return (-1); |
---|
| 1724 | @} |
---|
| 1725 | |
---|
| 1726 | /* |
---|
| 1727 | * getpid -- only one process, so just return 1. |
---|
| 1728 | */ |
---|
| 1729 | #define __MYPID 1 |
---|
| 1730 | int |
---|
| 1731 | getpid() |
---|
| 1732 | @{ |
---|
| 1733 | return __MYPID; |
---|
| 1734 | @} |
---|
| 1735 | |
---|
| 1736 | /* |
---|
| 1737 | * kill -- go out via exit... |
---|
| 1738 | */ |
---|
| 1739 | int |
---|
| 1740 | kill(pid, sig) |
---|
| 1741 | int pid; |
---|
| 1742 | int sig; |
---|
| 1743 | @{ |
---|
| 1744 | if(pid == __MYPID) |
---|
| 1745 | _exit(sig); |
---|
| 1746 | return 0; |
---|
| 1747 | @} |
---|
| 1748 | |
---|
| 1749 | /* |
---|
| 1750 | * print -- do a raw print of a string |
---|
| 1751 | */ |
---|
| 1752 | int |
---|
| 1753 | print(ptr) |
---|
| 1754 | char *ptr; |
---|
| 1755 | @{ |
---|
| 1756 | while (*ptr) @{ |
---|
| 1757 | outbyte (*ptr++); |
---|
| 1758 | @} |
---|
| 1759 | @} |
---|
| 1760 | |
---|
| 1761 | /* |
---|
| 1762 | * putnum -- print a 32 bit number in hex |
---|
| 1763 | */ |
---|
| 1764 | int |
---|
| 1765 | putnum (num) |
---|
| 1766 | unsigned int num; |
---|
| 1767 | @{ |
---|
| 1768 | char buffer[9]; |
---|
| 1769 | int count; |
---|
| 1770 | char *bufptr = buffer; |
---|
| 1771 | int digit; |
---|
| 1772 | |
---|
| 1773 | for (count = 7 ; count >= 0 ; count--) @{ |
---|
| 1774 | digit = (num >> (count * 4)) & 0xf; |
---|
| 1775 | |
---|
| 1776 | if (digit <= 9) |
---|
| 1777 | *bufptr++ = (char) ('0' + digit); |
---|
| 1778 | else |
---|
| 1779 | *bufptr++ = (char) ('a' - 10 + digit); |
---|
| 1780 | @} |
---|
| 1781 | |
---|
| 1782 | *bufptr = (char) 0; |
---|
| 1783 | print (buffer); |
---|
| 1784 | return; |
---|
| 1785 | @} |
---|
| 1786 | @end example |
---|
| 1787 | |
---|
| 1788 | @node mvme.S, io.c, glue.c, Code Listings |
---|
| 1789 | @section I/O assembler code sample |
---|
| 1790 | |
---|
| 1791 | @example |
---|
| 1792 | /* |
---|
| 1793 | * mvme.S -- board support for m68k |
---|
| 1794 | */ |
---|
| 1795 | |
---|
| 1796 | .title "mvme.S for m68k-coff" |
---|
| 1797 | |
---|
| 1798 | /* These are predefined by new versions of GNU cpp. */ |
---|
| 1799 | |
---|
| 1800 | #ifndef __USER_LABEL_PREFIX__ |
---|
| 1801 | #define __USER_LABEL_PREFIX__ _ |
---|
| 1802 | #endif |
---|
| 1803 | |
---|
| 1804 | #ifndef __REGISTER_PREFIX__ |
---|
| 1805 | #define __REGISTER_PREFIX__ |
---|
| 1806 | #endif |
---|
| 1807 | |
---|
| 1808 | /* ANSI concatenation macros. */ |
---|
| 1809 | |
---|
| 1810 | #define CONCAT1(a, b) CONCAT2(a, b) |
---|
| 1811 | #define CONCAT2(a, b) a ## b |
---|
| 1812 | |
---|
| 1813 | /* Use the right prefix for global labels. */ |
---|
| 1814 | |
---|
| 1815 | #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) |
---|
| 1816 | |
---|
| 1817 | /* Use the right prefix for registers. */ |
---|
| 1818 | |
---|
| 1819 | #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) |
---|
| 1820 | |
---|
| 1821 | #define d0 REG (d0) |
---|
| 1822 | #define d1 REG (d1) |
---|
| 1823 | #define d2 REG (d2) |
---|
| 1824 | #define d3 REG (d3) |
---|
| 1825 | #define d4 REG (d4) |
---|
| 1826 | #define d5 REG (d5) |
---|
| 1827 | #define d6 REG (d6) |
---|
| 1828 | #define d7 REG (d7) |
---|
| 1829 | #define a0 REG (a0) |
---|
| 1830 | #define a1 REG (a1) |
---|
| 1831 | #define a2 REG (a2) |
---|
| 1832 | #define a3 REG (a3) |
---|
| 1833 | #define a4 REG (a4) |
---|
| 1834 | #define a5 REG (a5) |
---|
| 1835 | #define a6 REG (a6) |
---|
| 1836 | #define fp REG (fp) |
---|
| 1837 | #define sp REG (sp) |
---|
| 1838 | #define vbr REG (vbr) |
---|
| 1839 | |
---|
| 1840 | .align 2 |
---|
| 1841 | .text |
---|
| 1842 | .global SYM (_exit) |
---|
| 1843 | .global SYM (outln) |
---|
| 1844 | .global SYM (outbyte) |
---|
| 1845 | .global SYM (putDebugChar) |
---|
| 1846 | .global SYM (inbyte) |
---|
| 1847 | .global SYM (getDebugChar) |
---|
| 1848 | .global SYM (havebyte) |
---|
| 1849 | .global SYM (exceptionHandler) |
---|
| 1850 | |
---|
| 1851 | .set vbr_size, 0x400 |
---|
| 1852 | .comm SYM (vbr_table), vbr_size |
---|
| 1853 | |
---|
| 1854 | /* |
---|
| 1855 | * inbyte -- get a byte from the serial port |
---|
| 1856 | * d0 - contains the byte read in |
---|
| 1857 | */ |
---|
| 1858 | .align 2 |
---|
| 1859 | SYM (getDebugChar): /* symbol name used by m68k-stub */ |
---|
| 1860 | SYM (inbyte): |
---|
| 1861 | link a6, #-8 |
---|
| 1862 | trap #15 |
---|
| 1863 | .word inchr |
---|
| 1864 | moveb sp@@, d0 |
---|
| 1865 | extbl d0 |
---|
| 1866 | unlk a6 |
---|
| 1867 | rts |
---|
| 1868 | |
---|
| 1869 | /* |
---|
| 1870 | * outbyte -- sends a byte out the serial port |
---|
| 1871 | * d0 - contains the byte to be sent |
---|
| 1872 | */ |
---|
| 1873 | .align 2 |
---|
| 1874 | SYM (putDebugChar): /* symbol name used by m68k-stub */ |
---|
| 1875 | SYM (outbyte): |
---|
| 1876 | link fp, #-4 |
---|
| 1877 | moveb fp@@(11), sp@@ |
---|
| 1878 | trap #15 |
---|
| 1879 | .word outchr |
---|
| 1880 | unlk fp |
---|
| 1881 | rts |
---|
| 1882 | |
---|
| 1883 | /* |
---|
| 1884 | * outln -- sends a string of bytes out the serial port with a CR/LF |
---|
| 1885 | * a0 - contains the address of the string's first byte |
---|
| 1886 | * a1 - contains the address of the string's last byte |
---|
| 1887 | */ |
---|
| 1888 | .align 2 |
---|
| 1889 | SYM (outln): |
---|
| 1890 | link a6, #-8 |
---|
| 1891 | moveml a0/a1, sp@@ |
---|
| 1892 | trap #15 |
---|
| 1893 | .word outln |
---|
| 1894 | unlk a6 |
---|
| 1895 | rts |
---|
| 1896 | |
---|
| 1897 | /* |
---|
| 1898 | * outstr -- sends a string of bytes out the serial port without a CR/LF |
---|
| 1899 | * a0 - contains the address of the string's first byte |
---|
| 1900 | * a1 - contains the address of the string's last byte |
---|
| 1901 | */ |
---|
| 1902 | .align 2 |
---|
| 1903 | SYM (outstr): |
---|
| 1904 | link a6, #-8 |
---|
| 1905 | moveml a0/a1, sp@@ |
---|
| 1906 | trap #15 |
---|
| 1907 | .word outstr |
---|
| 1908 | unlk a6 |
---|
| 1909 | rts |
---|
| 1910 | |
---|
| 1911 | /* |
---|
| 1912 | * havebyte -- checks to see if there is a byte in the serial port, |
---|
| 1913 | * returns 1 if there is a byte, 0 otherwise. |
---|
| 1914 | */ |
---|
| 1915 | SYM (havebyte): |
---|
| 1916 | trap #15 |
---|
| 1917 | .word instat |
---|
| 1918 | beqs empty |
---|
| 1919 | movel #1, d0 |
---|
| 1920 | rts |
---|
| 1921 | empty: |
---|
| 1922 | movel #0, d0 |
---|
| 1923 | rts |
---|
| 1924 | |
---|
| 1925 | /* |
---|
| 1926 | * These constants are for the MVME-135 board's boot monitor. They |
---|
| 1927 | * are used with a TRAP #15 call to access the monitor's I/O routines. |
---|
| 1928 | * they must be in the word following the trap call. |
---|
| 1929 | */ |
---|
| 1930 | .set inchr, 0x0 |
---|
| 1931 | .set instat, 0x1 |
---|
| 1932 | .set inln, 0x2 |
---|
| 1933 | .set readstr, 0x3 |
---|
| 1934 | .set readln, 0x4 |
---|
| 1935 | .set chkbrk, 0x5 |
---|
| 1936 | |
---|
| 1937 | .set outchr, 0x20 |
---|
| 1938 | .set outstr, 0x21 |
---|
| 1939 | .set outln, 0x22 |
---|
| 1940 | .set write, 0x23 |
---|
| 1941 | .set writeln, 0x24 |
---|
| 1942 | .set writdln, 0x25 |
---|
| 1943 | .set pcrlf, 0x26 |
---|
| 1944 | .set eraseln, 0x27 |
---|
| 1945 | .set writd, 0x28 |
---|
| 1946 | .set sndbrk, 0x29 |
---|
| 1947 | |
---|
| 1948 | .set tm_ini, 0x40 |
---|
| 1949 | .set dt_ini, 0x42 |
---|
| 1950 | .set tm_disp, 0x43 |
---|
| 1951 | .set tm_rd, 0x44 |
---|
| 1952 | |
---|
| 1953 | .set redir, 0x60 |
---|
| 1954 | .set redir_i, 0x61 |
---|
| 1955 | .set redir_o, 0x62 |
---|
| 1956 | .set return, 0x63 |
---|
| 1957 | .set bindec, 0x64 |
---|
| 1958 | |
---|
| 1959 | .set changev, 0x67 |
---|
| 1960 | .set strcmp, 0x68 |
---|
| 1961 | .set mulu32, 0x69 |
---|
| 1962 | .set divu32, 0x6A |
---|
| 1963 | .set chk_sum, 0x6B |
---|
| 1964 | |
---|
| 1965 | @end example |
---|
| 1966 | |
---|
| 1967 | @node io.c, leds.c, mvme.S, Code Listings |
---|
| 1968 | @section I/O code sample |
---|
| 1969 | |
---|
| 1970 | @example |
---|
| 1971 | #include "w89k.h" |
---|
| 1972 | |
---|
| 1973 | /* |
---|
| 1974 | * outbyte -- shove a byte out the serial port. We wait till the byte |
---|
| 1975 | */ |
---|
| 1976 | int |
---|
| 1977 | outbyte(byte) |
---|
| 1978 | unsigned char byte; |
---|
| 1979 | @{ |
---|
| 1980 | while ((inp(RS232REG) & TRANSMIT) == 0x0) @{ @} ; |
---|
| 1981 | return (outp(RS232PORT, byte)); |
---|
| 1982 | @} |
---|
| 1983 | |
---|
| 1984 | /* |
---|
| 1985 | * inbyte -- get a byte from the serial port |
---|
| 1986 | */ |
---|
| 1987 | unsigned char |
---|
| 1988 | inbyte() |
---|
| 1989 | @{ |
---|
| 1990 | while ((inp(RS232REG) & RECEIVE) == 0x0) @{ @}; |
---|
| 1991 | return (inp(RS232PORT)); |
---|
| 1992 | @} |
---|
| 1993 | @end example |
---|
| 1994 | |
---|
| 1995 | @node leds.c, ,io.c, Code Listings |
---|
| 1996 | @section Led control sample |
---|
| 1997 | |
---|
| 1998 | @example |
---|
| 1999 | /* |
---|
| 2000 | * leds.h -- control the led's on a Motorola mc68ec0x0 board. |
---|
| 2001 | */ |
---|
| 2002 | |
---|
| 2003 | #ifndef __LEDS_H__ |
---|
| 2004 | #define __LEDS_H__ |
---|
| 2005 | |
---|
| 2006 | #define LED_ADDR 0xd00003 |
---|
| 2007 | #define LED_0 ~0x1 |
---|
| 2008 | #define LED_1 ~0x2 |
---|
| 2009 | #define LED_2 ~0x4 |
---|
| 2010 | #define LED_3 ~0x8 |
---|
| 2011 | #define LED_4 ~0x10 |
---|
| 2012 | #define LED_5 ~0x20 |
---|
| 2013 | #define LED_6 ~0x40 |
---|
| 2014 | #define LED_7 ~0x80 |
---|
| 2015 | #define LEDS_OFF 0xff |
---|
| 2016 | #define LEDS_ON 0x0 |
---|
| 2017 | |
---|
| 2018 | #define FUDGE(x) ((x >= 0xa && x <= 0xf) ? (x + 'a') & 0x7f : (x + '0') & 0x7f) |
---|
| 2019 | |
---|
| 2020 | extern void led_putnum( char ); |
---|
| 2021 | |
---|
| 2022 | #endif /* __LEDS_H__ */ |
---|
| 2023 | |
---|
| 2024 | /* |
---|
| 2025 | * leds.c -- control the led's on a Motorola mc68ec0x0 (IDP)board. |
---|
| 2026 | */ |
---|
| 2027 | #include "leds.h" |
---|
| 2028 | |
---|
| 2029 | void zylons(); |
---|
| 2030 | void led_putnum(); |
---|
| 2031 | |
---|
| 2032 | /* |
---|
| 2033 | * led_putnum -- print a hex number on the LED. the value of num must be a char with |
---|
| 2034 | * the ascii value. ie... number 0 is '0', a is 'a', ' ' (null) clears |
---|
| 2035 | * the led display. |
---|
| 2036 | * Setting the bit to 0 turns it on, 1 turns it off. |
---|
| 2037 | * the LED's are controlled by setting the right bit mask in the base |
---|
| 2038 | * address. |
---|
| 2039 | * The bits are: |
---|
| 2040 | * [d.p | g | f | e | d | c | b | a ] is the byte. |
---|
| 2041 | * |
---|
| 2042 | * The locations are: |
---|
| 2043 | * |
---|
| 2044 | * a |
---|
| 2045 | * ----- |
---|
| 2046 | * f | | b |
---|
| 2047 | * | g | |
---|
| 2048 | * ----- |
---|
| 2049 | * | | |
---|
| 2050 | * e | | c |
---|
| 2051 | * ----- |
---|
| 2052 | * d . d.p (decimal point) |
---|
| 2053 | */ |
---|
| 2054 | void |
---|
| 2055 | led_putnum ( num ) |
---|
| 2056 | char num; |
---|
| 2057 | @{ |
---|
| 2058 | static unsigned char *leds = (unsigned char *)LED_ADDR; |
---|
| 2059 | static unsigned char num_bits [18] = @{ |
---|
| 2060 | 0xff, /* clear all */ |
---|
| 2061 | 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */ |
---|
| 2062 | 0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */ |
---|
| 2063 | @}; |
---|
| 2064 | |
---|
| 2065 | if (num >= '0' && num <= '9') |
---|
| 2066 | num = (num - '0') + 1; |
---|
| 2067 | |
---|
| 2068 | if (num >= 'a' && num <= 'f') |
---|
| 2069 | num = (num - 'a') + 12; |
---|
| 2070 | |
---|
| 2071 | if (num == ' ') |
---|
| 2072 | num = 0; |
---|
| 2073 | |
---|
| 2074 | *leds = num_bits[num]; |
---|
| 2075 | @} |
---|
| 2076 | |
---|
| 2077 | /* |
---|
| 2078 | * zylons -- draw a rotating pattern. NOTE: this function never returns. |
---|
| 2079 | */ |
---|
| 2080 | void |
---|
| 2081 | zylons() |
---|
| 2082 | @{ |
---|
| 2083 | unsigned char *leds = (unsigned char *)LED_ADDR; |
---|
| 2084 | unsigned char curled = 0xfe; |
---|
| 2085 | |
---|
| 2086 | while (1) |
---|
| 2087 | @{ |
---|
| 2088 | *leds = curled; |
---|
| 2089 | curled = (curled >> 1) | (curled << 7); |
---|
| 2090 | delay ( 200 ); |
---|
| 2091 | @} |
---|
| 2092 | @} |
---|
| 2093 | @end example |
---|
| 2094 | |
---|
| 2095 | @page |
---|
| 2096 | @contents |
---|
| 2097 | @c second page break makes sure right-left page alignment works right |
---|
| 2098 | @c with a one-page toc, even though we don't have setchapternewpage odd. |
---|
| 2099 | @page |
---|
| 2100 | @bye |
---|