summaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2007-07-05 18:01:56 +0200
committerSascha Hauer <sha@octopus.labnet.pengutronix.de>2007-07-05 18:01:56 +0200
commitd299862aaf0ca6fbd6ddd8a7df48551d604f00b9 (patch)
treeabcb17997141d1fb8e8fdc1868d9e8b7adaa31cd /Documentation
parent17f9b2c9ac8e253e7ab0d00b2bf8e4bb67e14852 (diff)
downloadbarebox-d299862aaf0ca6fbd6ddd8a7df48551d604f00b9.tar.gz
barebox-d299862aaf0ca6fbd6ddd8a7df48551d604f00b9.tar.xz
svn_rev_464
add Documentation
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/devices_drivers.txt79
-rw-r--r--Documentation/parameters.txt52
-rw-r--r--Documentation/porting.txt106
-rw-r--r--Documentation/timekeeping.txt13
4 files changed, 250 insertions, 0 deletions
diff --git a/Documentation/devices_drivers.txt b/Documentation/devices_drivers.txt
new file mode 100644
index 0000000000..5a95c91732
--- /dev/null
+++ b/Documentation/devices_drivers.txt
@@ -0,0 +1,79 @@
+
+---------- Devices and drivers in U-Boot --------------
+
+We follow a rather simplistic driver model here. There is a struct device which
+describes a particular device present in the system. A struct driver represents
+a driver present in the system. Both structs find together via the members
+'type' (int) and 'name' (char *). If both members match, the driver's probe
+function is called with the struct device as argument. People familiar with
+the Linux platform bus will recognize this behaviour and in fact many things were
+stolen from there. Some selected members of the structs will be described in this
+document.
+Currently all devices and drivers are handled in simple linked lists. When it comes
+to USB or PCI it may be desirable to have a tree structure, but this may also be
+unnecessary overhead.
+
+struct device
+-------------
+
+char name[MAX_DRIVER_NAME];
+
+This member (and 'type' described below) is used to match with a driver. This is
+a descriptive name and could be MPC5XXX_ether or imx_serial.
+
+char id[MAX_DRIVER_NAME];
+
+The id is used to uniquely identify a device in the system. The id will show up
+under /dev/ as the device's name. Usually this is something like eth0 or nor0.
+
+unsigned long type;
+
+This describes the type (or class) of this device. Have a look at include/driver.h
+to see a list of known device types. Currently this includes DEVICE_TYPE_ETHER,
+DEVICE_TYPE_CONSOLE and others.
+
+void *type_data;
+
+Devices of a particular class normaly need to store more information than struct
+device holds. This entry holds a pointer to the type specific struct, so a
+a device of type DEVICE_TYPE_ETHER sets this to a struct eth_device.
+
+void *priv;
+
+Used by the device driver to store private information.
+
+void *platform_data;
+
+This is used to carry information of board specific data from the board code to the
+device driver.
+
+struct param_d *param;
+
+The parameters for this device. See Documentation/parameters.txt for more info.
+
+struct driver_d
+---------------
+
+char name[MAX_DRIVER_NAME];
+unsigned long type;
+
+See above.
+
+int (*probe) (struct device_d *);
+int (*remove)(struct device_d *);
+
+These are called if a instance of a device is found or gone.
+
+ssize_t (*read) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
+ssize_t (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
+
+The standard read/write functions. These are called as a response to the read/write
+system calls. No driver needs to implement these.
+
+void *type_data;
+
+This is somewhat redundant with the type data in struct device. Currently the
+filesystem implementation uses this field while ethernet drivers use the same
+field in struct device. Probably one of both should be removed.
+
+
diff --git a/Documentation/parameters.txt b/Documentation/parameters.txt
new file mode 100644
index 0000000000..219440b40c
--- /dev/null
+++ b/Documentation/parameters.txt
@@ -0,0 +1,52 @@
+---------- Device parameters --------------
+
+Devices have several parameters. In case of a network device this may be the
+ip address, networking mask or similar and users need access to these
+parameters. in U-Boot this is solved with device paramters. Device parameters
+are always strings, although there are functions to interpret them as
+something else. hush users can access parameters as a local variable which
+have a dot (.) in them. So setting the ip address of the first ethernet
+device is a matter of typing 'eth0.ip=192.168.0.7' on the console and can
+then be read back with 'echo $eth0.ip'. The devinfo command shows a summary
+about all devices currently present. If called with a device id as parameter
+it shows the parameters available for a device.
+
+Device parameters programming API
+---------------------------------
+
+struct param_d {
+ char* (*get)(struct device_d *, struct param_d *param);
+ int (*set)(struct device_d *, struct param_d *param, const char *val);
+ ulong flags;
+ char *name;
+ struct param_d *next;
+ char *value;
+};
+
+int dev_add_param(struct device_d *dev, struct param_d *par);
+
+This function adds a new parameter to a device. At least the name field in
+the new parameter struct has to be initialized. The 'get' and 'set' fields
+can be set to NULL in which case the framework handles them. It is also
+allowed to implement only one of the get/set functions. Care must be taken
+with the initial value of the parameter. If the framework handles the set
+function it will try to free the value of the parameter. If this is a
+static array bad things will happen. A parameter can have the flag
+PARAM_FLAG_RO which means that the parameter is readonly. It is perfectly ok
+then to point value to a static array.
+
+const char *dev_get_param(struct device_d *dev, const char *name);
+
+This function returns a pointer to the value of the parameter specified
+with dev and name.
+If the framework handles the get/set functions the parameter value strings
+are alloceted with malloc and freed with free when another value is set for
+this parameter. Drivers implementing set/get themselves are allowed to
+return values in static arrays. This means that the pointers returned from
+dev_get_param() are only valid until the next call to dev_get_param. If this
+is not long enough strdup() or similar must be used.
+
+int dev_set_param(struct device_d *dev, const char *name, const char *val);
+
+Set the value of a parameter.
+
diff --git a/Documentation/porting.txt b/Documentation/porting.txt
new file mode 100644
index 0000000000..167a11c4b2
--- /dev/null
+++ b/Documentation/porting.txt
@@ -0,0 +1,106 @@
+
+When porting from old U-Boot the follwing steps must be taken (please complain
+if there's something missing here ;)
+
+
+- Most of the macros in include/configs/yourboard.h can be removed, espacially
+ the CONFIG_COMMANDS section. The goal is to remove this file entirely, but
+ for now some values are still needed here. If you think some things are better
+ configured with the Kconfig system feel free to add them there.
+
+- The linker script needs a new section for the initcalls. The handling of the
+ U-Boot command table has changed also (The commands are now sorted by the
+ linker instead in runtime). To change it you need an entry like the following
+ in your linker script:
+
+#include <asm-generic/u-boot.lds.h>
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { U_BOOT_CMDS }
+ __u_boot_cmd_end = .;
+
+ __u_boot_initcalls_start = .;
+ .u_boot_initcalls : { INITCALLS }
+ __u_boot_initcalls_end = .;
+
+- Rename your linker script to u-boot.lds.S and add the following entry to the
+ Makefile to make sure the linker script is generated:
+
+extra-y += u-boot.lds
+
+- Register the devices present in your system in the board specific .c file.
+ To see anything you at least have to register a console. In scb9328.c this
+ looks like this:
+
+static struct device_d scb9328_serial_device = {
+ .name = "imx_serial",
+ .id = "cs0",
+ .map_base = IMX_UART1_BASE,
+ .size = 4096,
+ .type = DEVICE_TYPE_CONSOLE,
+};
+
+static int scb9328_console_init(void)
+{
+ register_device(&scb9328_serial_device);
+ return 0;
+}
+
+- For most boards you will have to register a cfi_flash device. NAND flash
+ is not ported yet.
+
+- Call dev_add_partition() to add an environment partition for your device:
+ dev_add_partition(&cfi_dev, 0x40000, 0x20000, "env");
+ This will add an area starting at 0x40000 of size 0x20000 of the device
+ cfi_dev as env0.
+
+console_initcall(scb9328_console_init);
+
+- Port missing drivers. Depending on the driver this can a be rather simple
+ process:
+
+ Serial drivers
+ - Declare all functions static.
+ - register a device of type DEVICE_TYPE_CONSOLE
+ - in your probe function fill in a struct console_device and register it
+ with console_register()
+
+ Ethernet drivers
+ - Basically do the same as with serial drivers.
+ - Identify the parts of the driver which handle the MAC address. There are
+ now two fields in struct eth_device. get_mac_address() shall retrieve the
+ MAC address from the EEPROM if one is connected. If you don't have an
+ EEPROM just return -1. set_mac_address() shall set the MAC address in
+ the device. All magic previously done with getenv/setenv(ethaddr) must be
+ removed.
+
+- Add a clocksource for your system. PowerPCs have a generic decrementer
+ counter, so if you have a PowerPC aou have nothing to do here. on ARM
+ this is SoC dependend. See Documentation/timekeeping.txt for further
+ information.
+
+- Adjust start.S. These files share a lot of common code, so they should be
+ reworked in general. On Arm you have to fix CFG_MALLOC_LEN. Most start.S
+ under cpu/arm* do a "sub r0, r0, #CFG_MALLOC_LEN". If you increase
+ the malloc space the value CFG_MALLOC_LEN does not fit into the instruction.
+ See cpu/arm920t/start.S how it is done.
+ On PowerpC there is at least the Problem that the relocation offset is
+ defined at compile time. It is easily possible to determine the address
+ U-Boot is currently starting from at runtime and thus allowing it U-Boot
+ to be started at any address. Look at the relocation code and replace
+ TEXT_BASE with the following calculation of the runtime address:
+
+ bl calc_source /* Calculate Source Address */
+calc_source:
+ mfspr r4, LR
+ subi r4, r4, (calc_source - _start)
+ subi r4, r4, 0x100
+
+ (I'm almost sure that PowerPC has a dedicated instruction for this, un-
+ fortunately I know next to nothing of PowerPC assembler)
+
+ U-Boot runs now from the address it was linked to, so on PowerPC you have
+ to adjust TEXT_BASE to be in RAM. This makes the various fixup functions
+ unnecessary. It also simplifies debugging because you will see the
+ correct addresses in the objdump.
+
diff --git a/Documentation/timekeeping.txt b/Documentation/timekeeping.txt
new file mode 100644
index 0000000000..9d778117c1
--- /dev/null
+++ b/Documentation/timekeeping.txt
@@ -0,0 +1,13 @@
+------------ U-Boot timekeeping -------------
+
+In U-Boot we use the clocksource mechanism from the Linux Kernel. This makes
+it fairly easy to add timer functionality for a new board or architecture.
+Apart from initialization there is only one function required:
+clocksource_read(). This function returns the current value of a free running
+counter. Other functions like udelay() and get_time_ns() are derived from this
+function. The only thing you have to implement is a clocksource driver. See
+cpu/arm920t/imx/interrupts.c for an example. clocksource drivers from the
+Linux Kernel can be used nearly 1:1, except for the register accesses.
+
+for clocksources the __lshrdi3 symbol is needed. You can find the function for
+your architecture in the Linux Kernel or a libc of your choice.