OSDN Git Service

Enable to track git://github.com/monaka/binutils.git
[pf3gnuchains/pf3gnuchains3x.git] / rda / HOWTO.old
diff --git a/rda/HOWTO.old b/rda/HOWTO.old
new file mode 100644 (file)
index 0000000..2bde93e
--- /dev/null
@@ -0,0 +1,332 @@
+How to implement a stub or server using RDA (Red Hat Debug Agent and library).
+==================================================
+Andrew Cagney <cagney@cygnus.com>
+Fernando Nasser <fnasser@cygnus.com>
+Frank Eigler <fche@cygnus.com>
+
+Introduction
+------------
+
+This is the implementation of a server for the gdb remote protocol.
+It is available as a host library that provides most of the common code
+required.  By adding a relatively small amount of target dependent code,
+one can build a server that allows gdb to connect to that target using
+the gdb "target remote" command.
+
+Gdb connects to this server through a TCP/IP connection.  The server
+waits for a connection from GDB by listening to a non-restricted TCP port.
+Anyone with GDB (or even telnet) network connectivity to the machine
+running the server can initiate a connection to it.
+
+Note: The user of this software is advised to ensure
+that access to the TCP port being used is restricted to
+secure siblings.  For instance, the user may need to take
+action that ensures that `The Internet' is not able to access
+the TCP port being used.
+
+Architecture
+------------
+
+The following diagram shows the components of RDA.
+
+       (GDB) <---"remote"---> CLIENT <--> SERVER <--> TARGET
+       -------                 ------------------------------
+     The client.                         The server.
+
+Where:
+
+       CLIENT  Provides the raw interface between
+               GDB and the internal SERVER
+               mechanism.
+
+               The client passes on any data relevant
+               to the server.  The SERVER presents
+               CLIENT with raw output to be returned
+               to GDB.
+
+       SERVER  Implements the state-machine that
+               is capable of decoding / processing
+               various GDB remote protocol requests.
+
+       TARGET  The embedded system proper.  SERVER
+               passes decoded requests onto the TARGET
+               while TARGET notifies the SERVER of any
+               target state changes.
+
+
+Looking at SERVER in more detail, that component consists of three sub
+components INPUT, OUTPUT and STATE.  Visually:
+
+                                    .------------ fromtarget_*
+                                   \|/
+       fromclient_*   -> INPUT -> STATE (M/C) -> target->*
+                          /|\         |
+                            |
+                          \|/         |
+       client->write  <- OUTPUT <----'
+
+Where:
+
+       INPUT   Filters the raw input stream from the client
+               breaking it up into complete packets and
+               passing them onto STATE.
+
+               This component co-operates with OUTPUT for
+               the ACK/NAK of input packets.
+
+       OUTPUT  Wraps up and then passes onto the client
+               raw output packets ready for transmission
+               on the output stream.
+
+               This component  co-operates with INPUT for
+               the ACK/NAK of output packets.
+
+       STATE   The state machine proper.
+
+
+The Appendix provides various scenarios showing in some detail how typical
+operations are handled by these components.  It may be convenient to read the
+next section first before turning to the Appendix.
+
+
+Adding the target dependent code
+--------------------------------
+
+In the following discussion, assume your debugger (gdb) is using 
+the remote protocol to communicate with the code you are building here.
+The "target" is a simulator, hardware device, board, program or whatever you
+are interfacing to with your stub/server.
+
+The library provides gdbsocket_*() and gdbserv_fromtarget_*() routines that
+must be called and requires you to set a series of callback routines.
+You make these callbacks known/available to the library by filling the entries
+of a "gdbserv_target" object.  You must also provide an extra function that
+will be invoked when a new connection is detected on the input port (a socket).
+
+
+Handling the connection:
+
+The server is capable of handling several connections (named, sessions)
+simultaneously.  This is possible because each session data is kept on
+an instance of a GDBSERV object.  A routine called gdbserv_fromclient_attach()
+is called when a connection request is received by the socket.
+If the connection is accepted, a new instance of a GDBSERV object is returned,
+otherwise NULL is returned indicating that it has been rejected (a EOF will be
+sensed on the other end).
+
+The server will, in turn, pass the request onto the target.  The target can
+either reject the connection (returning NULL) or accept the connection
+(returning a target object).  That is where you come in.
+
+You must provide a routine like (please see the precise API in the header file
+include/gdbserv-client.h):
+
+typedef struct gdbserv_target *(gdbserv_target_attach) (struct gdbserv *gdbserv,                                                        void *attatch_data);
+
+This will be called by the server to notify that the client has initiated a
+connection.  You must return a GDBSERV_TARGET struct for the session or null
+if your target has rejected the connection.
+
+The recommended way to create your gdbserv_target object is:
+
+struct gdbserv_target *gdbtarget = malloc (sizeof (struct gdbserv_target));
+memset (gdbtarget, 0, sizeof (*gdbtarget));
+gdbtarget->process_get_gen = process_get_gen;
+(...)
+
+If you initialize it like this, you will not have to change your code even if
+new entries are added to this struct.
+
+
+Handling target events:
+
+The fromtarget_* routines may be called by your target.  Before you
+despair, let me tell you that they are only three: reset, break and
+exit.  They indicate that some interesting condition happened in your
+target that requires debugger attention.  Reset and exit are quite
+obvious and break is for everything else.  These routines must *not*
+be called from within a gdbserv_target callback function, so it may be
+necessary for your target to set some flags to signal state change
+calls later.
+
+If your target is a simulator, call those when the corresponding
+condition arises in your simulated target.  If it is a board, it will
+probably be called from your ISRs.  A special case occurs if your
+target is a device that has to be polled in order to detect state
+changes.  If this is the case, you will call these routines from the
+polling code.
+
+
+The main loop:
+
+At some point you must get things going by:
+
+1) looking for connection requests from gdb and 
+2) causing remote protocol commands to be read from the input port (socket).
+
+You must (repeatedly) call a function called gdbloop_poll().  This
+will be in your main loop.  If it is a server it will be in your
+main() function.  If it is a simulator that also accepts input from
+other sources, it will have to be added to the existing main loop. If
+it is a board, it will probably be called from the timer ISR.
+
+Before doing that you must initialize your socket interface.  Look in
+the main() routine of the sample program to see what to call.  When
+calling gdbsocket_startup() you must give the address of the callback
+that handles connection requests for your target.
+
+If your target has to be polled for state changes, you will have to alternate 
+calls to poll() and to check your target status.  As I mentioned before,
+your status checking routine must call the appropriate fromtarget_* function.
+
+
+The callbacks:
+
+All that is left now is to implement your callbacks, which are, directly or
+indirectly, called as a result of a remote protocol packet being received and
+processed by some fromclient_* routine.  I will assume that the remote
+protocol packets are known.  If not, please refer to the "Remote Protocol"
+section of the gdb manual.  There you will find how your target should be
+affected by each packet and what the response should be.  It is always
+useful to look at what some other remote targets do as well.
+
+The list of all callbacks with the situation in which they are invoked can be
+found in the header file lib/gdbserv-target.h.
+
+Have fun!
+
+
+
+Appendix
+--------
+
+SCENARIOS
+
+
+ATTACH: Creating a connection into the server/target.
+
+Client receives a connect request from the remote GDB.  A socket
+interface would see this as an attach.  For Cygmon this is the
+``transfer'' command.
+
+The client creates an output object (struct gdbserv_client) and passes
+that and the target side attach function onto GDBSERV.  SERVER will
+then initialize itself and call ``to_target_attach'' for final
+approval of the request.
+
+       struct gdbserv_client *client;
+       ...
+       client->write = client_write_to_output_port;
+       client->data = ... local state ...
+       server = gdbserv_fromclient_attach (client, to_target_attach,
+                                           target_data);
+
+The target_attach() function is expected to either create and return a
+gdbserv_target object or return NULL.  The latter indicates that the
+connection request is rejected.
+
+Finally gdbserv_fromclient_attach() returns a SERVER state object that
+should be passed to all client->server calls.
+
+
+DATA-IN: Data being sent to the client from the remote GDB
+
+The client passes the data vis:
+
+       len = read (fd, buf, sizeof (buf));
+       gdbserv_fromclient_data (server, buf, len);
+
+
+BREAK-IN: Request to stop sent to the client from the remote GDB
+
+The client passes the request to SERVER:
+
+       server.c:
+
+       volatile
+       break_handler ()
+       {
+         gdbserv_fromclient_break (server);
+       }
+
+If the target is currently running, the server will in turn pass the
+request onto the TARGET:
+
+       ->target->break_program (server);
+
+and the target will record the break request and then return control
+back to the SERVER.  The server returning control to the client.
+
+Later, once the target has halted, the SERVER is notified of the state
+change vis:
+
+       target.c:
+
+         gdbserv_fromtarget_break (server);
+
+
+NB: Often ``break'' is sent across the stream interface as a special
+character sequence.
+
+FIXME: gdbserv-input.c should be able to parse such character
+sequences.
+
+
+DATA-OUT: Data for the remote GDB from SERVER
+
+The ``write'' function specified in the ``struct gdbserv_client''
+object is called.
+
+
+DETACH: Remote GDB disconnects from the SERVER
+
+The CLIENT notifies SERVER via the gdbserv_fromclient_detach() call.
+
+
+HARD-RESET:  A hard reset is performed on a serial board.
+
+Assuming a standalone system, the client/target side sequences would
+be performed:
+
+       /* create the server */
+       server = gdbserv_fromclient_attach (...);
+       /* notify the server that the target was just reset */
+       gdbserv_fromtarget_reset (server);
+
+
+WRITE-MEMORY: GDB sends the server a write-memory packet.
+
+Eventually SERVER passes the request onto the TARGET with the call:
+
+       ->target->process_set_mem (server, addr, len);
+
+where ADDR and LEN contain the uninterpreted address/length of the
+data to follow.  target_process_set_mem() might be implemented as:
+
+       long long addr;
+       long int;
+       gdbserv_reg_to_ulonglong (server, reg_addr, &addr);
+       gdbserv_reg_to_ulong (server, reg_len, &len);
+       /* just blat local memory */
+       len = gdbserv_input_bytes (server, addr, len);
+       
+
+READ-MEMORY: GDB requests memory from the target.
+
+Eventually target_process_get_mem() function is called.  An
+implementation may look like:
+
+       gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr);
+       gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
+       /* assume we're reading raw memory from the local mc */
+       gdbserv_output_bytes (gdbserv, addr, len);
+
+
+TARGET-RESUME: GDB requests that the target resume execution.
+
+Eventually ->target->continue_program() is called.  That function
+should record the request and then wait for SERVER to exit before
+actually continuing the target.
+
+--
+