Difference between revisions of "Libpayload"
m (→Payloads using libpayload) |
m (Fixed downloading from Subversion to Git) |
||
| (21 intermediate revisions by 6 users not shown) | |||
| Line 1: | Line 1: | ||
| − | '''libpayload''' is a small BSD-licensed static library (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads. | + | '''libpayload''' is a small BSD-licensed static library (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot [[payloads]]. |
| − | + | ||
| − | + | ||
The benefits of linking a coreboot payload against libpayload are: | The benefits of linking a coreboot payload against libpayload are: | ||
| Line 11: | Line 9: | ||
''Just give us a main() and a pocket full of dreams and we'll do the rest.'' | ''Just give us a main() and a pocket full of dreams and we'll do the rest.'' | ||
| − | |||
| − | |||
| − | |||
| − | |||
== Features == | == Features == | ||
| − | * Provides a [[Libpayload# | + | * Provides a [[Libpayload#Libc_coverage|subset of libc functions]] (e.g. malloc, printf, strcmp, etc). |
* Provides an optional tiny (n)curses implementation. | * Provides an optional tiny (n)curses implementation. | ||
* Provides various small drivers for | * Provides various small drivers for | ||
| Line 27: | Line 21: | ||
** VGA | ** VGA | ||
** Geode framebuffer | ** Geode framebuffer | ||
| + | ** USB stack | ||
* Reads and parses the coreboot table. | * Reads and parses the coreboot table. | ||
| + | |||
| + | == Design == | ||
| + | |||
| + | * [[Payload API|Discussion of the API for passing parameters to the payload]] | ||
== Payloads using libpayload == | == Payloads using libpayload == | ||
| − | * [[coreinfo]] is a small payload which can display system information such as PCI info, an NVRAM dump | + | * [[FILO]] is a bootloader which loads boot images from a local filesystem, without help from legacy BIOS services. |
| − | * [[ | + | * [[coreinfo]] is a small payload which can display system information such as PCI info, or an NVRAM dump. |
| − | * [[tint]] (a | + | * [[GRUB invaders]] has been ported successfully to libpayload (patch pending). |
| + | * [[tint]] (a "falling blocks" game) has been successfully ported to libpayload. | ||
* [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=scripts/kconfig/lxdialog;hb=HEAD lxdialog] from the Linux '''kconfig''' utility has been ported to be usable when linked with libpayload (patch pending). | * [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=scripts/kconfig/lxdialog;hb=HEAD lxdialog] from the Linux '''kconfig''' utility has been ported to be usable when linked with libpayload (patch pending). | ||
| − | == Libc | + | == Downloading and building libpayload == |
| + | |||
| + | It is now in main coreboot git tree (see [[Download_coreboot]] for additional reference) | ||
| + | |||
| + | $ '''git clone http://review.coreboot.org/p/coreboot''' | ||
| + | $ '''cd payloads/libpayload''' | ||
| + | $ '''make menuconfig''' | ||
| + | $ '''make install''' | ||
| + | |||
| + | Here [http://review.coreboot.org/#/q/status:open+project:coreboot+message:libpayload,n,z gerrit] you can find pending patches for libpayload | ||
| + | |||
| + | == Documentation == | ||
| + | |||
| + | See the autogenerated documentation for libpayload [http://qa.coreboot.org/docs/libpayload/ here]. | ||
| + | |||
| + | == Libc coverage == | ||
| + | |||
| + | {| border="0" valign="top" | ||
| + | | valign="top"| | ||
| − | {| border="0" | + | {| border="0" style="font-size: smaller" |
|- bgcolor="#6699ff" | |- bgcolor="#6699ff" | ||
! align="left" | Status | ! align="left" | Status | ||
| Line 46: | Line 64: | ||
| colspan=2 | '''assert.h''' | | colspan=2 | '''assert.h''' | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#eeeeee" valign="top" |
| − | | | + | | style="background:lime" | no |
| + | | assert() | ||
|- bgcolor="#6699ff" | |- bgcolor="#6699ff" | ||
| colspan=2 | '''ctype.h''' | | colspan=2 | '''ctype.h''' | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#eeeeee" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int isalnum(int character) | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#dddddd" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int isalpha(int character) | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#dddddd" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int isascii(int character) | ||
|- | |- | ||
| + | |- bgcolor="#dddddd" valign="top" | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | | | + | | int isblanc(int character) |
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#eeeeee" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int iscntrl(int character) | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#dddddd" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int isdigit(int character) | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#eeeeee" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int isgraph(int character) | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#dddddd" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int islower(int character) | ||
|- | |- | ||
| + | |- bgcolor="#eeeeee" valign="top" | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | | | + | | int isprint(int character) |
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#dddddd" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int ispunct(int character) | ||
|- | |- | ||
| − | | style="background: | + | |- bgcolor="#eeeeee" valign="top" |
| − | | | + | | style="background:lime" | yes |
| + | | int isspace(int character) | ||
| + | |- | ||
| + | |- bgcolor="#dddddd" valign="top" | ||
| + | | style="background:lime" | yes | ||
| + | | int isupper(int character) | ||
| + | |- | ||
| + | |- bgcolor="#eeeeee" valign="top" | ||
| + | | style="background:lime" | yes | ||
| + | | int isxdigit(int character) | ||
| + | |- | ||
| + | |- bgcolor="#eeeeee" valign="top" | ||
| + | | style="background:lime" | yes | ||
| + | | int tolower(int character) | ||
| + | |- | ||
| + | |- bgcolor="#eeeeee" valign="top" | ||
| + | | style="background:lime" | yes | ||
| + | | int toupper(int character) | ||
|- bgcolor="#6699ff" | |- bgcolor="#6699ff" | ||
| colspan=2 | '''errno.h''' | | colspan=2 | '''errno.h''' | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>errno</code> (global) | | <code>errno</code> (global) | ||
| Line 247: | Line 293: | ||
| <code>int fprintf(FILE* stream, const char* format, ...)</code> | | <code>int fprintf(FILE* stream, const char* format, ...)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>int printf(const char* format, ...)</code> | | <code>int printf(const char* format, ...)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>int sprintf(char* s, const char* format, ...)</code> | | <code>int sprintf(char* s, const char* format, ...)</code> | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| + | | <code>int snprintf(char* s, size_t size, const char* format, ...)</code> | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code> | | <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>int vprintf(const char* format, va_list arg)</code> | | <code>int vprintf(const char* format, va_list arg)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>int vsprintf(char* s, const char* format, va_list arg)</code> | | <code>int vsprintf(char* s, const char* format, va_list arg)</code> | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| + | | <code>int vsnprintf(char* s, size_t size, const char* format, va_list arg)</code> | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| Line 336: | Line 388: | ||
| style="background:red" | no | | style="background:red" | no | ||
| <code>void perror(const char* s)</code> | | <code>void perror(const char* s)</code> | ||
| + | |||
| + | |} | ||
| + | |||
| + | | valign="top"| | ||
| + | |||
| + | {| border="0" style="font-size: smaller" | ||
| + | |- bgcolor="#6699ff" | ||
| + | ! align="left" | Status | ||
| + | ! align="left" | Function/Macro/Variable | ||
|- bgcolor="#6699ff" | |- bgcolor="#6699ff" | ||
| colspan=2 | '''stdlib.h''' | | colspan=2 | '''stdlib.h''' | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>int abs(int n)</code> | | <code>int abs(int n)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>long labs(long n)</code> | | <code>long labs(long n)</code> | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| + | | <code>long long llabs(long long n)</code> | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| Line 364: | Line 428: | ||
| <code>double strtod(const char* s, char** endp)</code> | | <code>double strtod(const char* s, char** endp)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>long strtol(const char* s, char** endp, int base)</code> | | <code>long strtol(const char* s, char** endp, int base)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>unsigned long strtoul(const char* s, char** endp, int base)</code> | | <code>unsigned long strtoul(const char* s, char** endp, int base)</code> | ||
|- | |- | ||
| Line 382: | Line 446: | ||
| <code>void free(void* p)</code> | | <code>void free(void* p)</code> | ||
|- | |- | ||
| − | | style="background:lime" | yes | + | | style="background:lime" | yes |
| + | | <code>void * memalign (size_t align, size_t size)</code> | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| <code>void abort()</code> | | <code>void abort()</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>void exit(int status)</code> | | <code>void exit(int status)</code> | ||
|- | |- | ||
| Line 398: | Line 465: | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | | <code>void* bsearch(const void* key, const void* base, size_t n, size_t size, int (*cmp)(const void* keyval, const void* datum))</code> | + | | <code>void* bsearch(const void* key, const void* base, size_t n,<br />size_t size, int (*cmp)(const void* keyval, const void* datum))</code> |
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | | <code>void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*))</code> | + | | <code>void qsort(void* base, size_t n, size_t size, <br />int (*cmp)(const void*, const void*))</code> |
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>int rand(void)</code> | | <code>int rand(void)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | yes |
| <code>void srand(unsigned int seed)</code> | | <code>void srand(unsigned int seed)</code> | ||
| Line 418: | Line 485: | ||
| <code>char* strncpy(char* s, const char* ct, size_t n)</code> | | <code>char* strncpy(char* s, const char* ct, size_t n)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>char* strcat(char* s, const char* ct)</code> | | <code>char* strcat(char* s, const char* ct)</code> | ||
|- | |- | ||
| Line 436: | Line 503: | ||
| <code>char* strchr(const char* cs, int c)</code> | | <code>char* strchr(const char* cs, int c)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>char* strrchr(const char* cs, int c)</code> | | <code>char* strrchr(const char* cs, int c)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>size_t strspn(const char* cs, const char* ct)</code> | | <code>size_t strspn(const char* cs, const char* ct)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>size_t strcspn(const char* cs, const char* ct)</code> | | <code>size_t strcspn(const char* cs, const char* ct)</code> | ||
|- | |- | ||
| Line 453: | Line 520: | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| <code>size_t strlen(const char* cs)</code> | | <code>size_t strlen(const char* cs)</code> | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| + | | <code>size_t strnlen(const char* cs, size_t maxlen)</code> | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| + | | <code>char * strdup (const char *s)</code> | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| <code>char* strerror(int n)</code> | | <code>char* strerror(int n)</code> | ||
|- | |- | ||
| − | | style="background: | + | | style="background:lime" | no |
| <code>char* strtok(char* s, const char* t)</code> | | <code>char* strtok(char* s, const char* t)</code> | ||
| + | |- | ||
| + | | style="background:lime" | no | ||
| + | | <code>char* strtok_r(char* s, const char* t, char **p)</code> | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| Line 483: | Line 559: | ||
| style="background:red" | no | | style="background:red" | no | ||
| <code>clock_t clock(void)</code> | | <code>clock_t clock(void)</code> | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| + | | <code>int gettimeofday (struct timeval *tv, void *tz)</code> | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| Line 506: | Line 585: | ||
|- | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | | <code>size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp)</code> | + | | <code>size_t strftime(char* s, size_t smax, const char* fmt,<br />const struct tm* tp)</code> |
| − | | | + | |- bgcolor="#6699ff" |
| + | | colspan=2 | '''unistd.h''' | ||
| + | |- | ||
| + | | style="background:lime" | yes | ||
| + | | <code>int exec (long addr, int argc, char **argv)</code> | ||
| − | + | |} | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
|} | |} | ||
| − | == Usage | + | == Usage example == |
| − | hello.c: | + | Here's an example of a very simple payload (hello.c) and how to build it: |
| − | < | + | <source lang="C"> |
#include <libpayload.h> | #include <libpayload.h> | ||
| Line 533: | Line 609: | ||
return 0; | return 0; | ||
} | } | ||
| − | </ | + | </source> |
| − | + | Building the payload: | |
| − | lpgcc -o hello.elf hello.c | + | $ '''lpgcc -o hello.elf hello.c''' |
{{PD-self}} | {{PD-self}} | ||
Latest revision as of 10:23, 1 June 2012
libpayload is a small BSD-licensed static library (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads.
The benefits of linking a coreboot payload against libpayload are:
- Payloads do not have to implement and maintain low-level code for I/O, common functions, etc.
- Payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future.
- The libpayload functions can be tested and scrutinized outside payload development.
- Payloads themselves may be partly host-tested, e.g. against an emulation libpayload.
Just give us a main() and a pocket full of dreams and we'll do the rest.
Contents |
[edit] Features
- Provides a subset of libc functions (e.g. malloc, printf, strcmp, etc).
- Provides an optional tiny (n)curses implementation.
- Provides various small drivers for
- keyboard
- PC speaker
- NVRAM/CMOS access
- serial console
- VGA
- Geode framebuffer
- USB stack
- Reads and parses the coreboot table.
[edit] Design
[edit] Payloads using libpayload
- FILO is a bootloader which loads boot images from a local filesystem, without help from legacy BIOS services.
- coreinfo is a small payload which can display system information such as PCI info, or an NVRAM dump.
- GRUB invaders has been ported successfully to libpayload (patch pending).
- tint (a "falling blocks" game) has been successfully ported to libpayload.
- lxdialog from the Linux kconfig utility has been ported to be usable when linked with libpayload (patch pending).
[edit] Downloading and building libpayload
It is now in main coreboot git tree (see Download_coreboot for additional reference)
$ git clone http://review.coreboot.org/p/coreboot $ cd payloads/libpayload $ make menuconfig $ make install
Here gerrit you can find pending patches for libpayload
[edit] Documentation
See the autogenerated documentation for libpayload here.
[edit] Libc coverage
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[edit] Usage example
Here's an example of a very simple payload (hello.c) and how to build it:
#include <libpayload.h> int main(void) { printf("Hello, world!\n"); halt(); return 0; }
Building the payload:
$ lpgcc -o hello.elf hello.c
| |
I, the copyright holder of this work, hereby release it into the public domain. This applies worldwide.
In case this is not legally possible: |