Difference between revisions of "Libpayload"
m (Fixed downloading from Subversion to Git) |
|||
| (27 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. |
| − | * [http:// | + | * [[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). | ||
| − | == | + | == 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 == |
| − | | | + | |
| − | | style=" | + | {| border="0" valign="top" |
| + | | valign="top"| | ||
| + | |||
| + | {| border="0" style="font-size: smaller" | ||
| + | |- bgcolor="#6699ff" | ||
| + | ! align="left" | Status | ||
| + | ! align="left" | Function/Macro/Variable | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''assert.h''' | ||
|- | |- | ||
| − | | | + | |- bgcolor="#eeeeee" valign="top" |
| − | | style="background: | + | | style="background:lime" | no |
| + | | assert() | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''ctype.h''' | ||
|- | |- | ||
| − | | | + | |- bgcolor="#eeeeee" valign="top" |
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | int isalnum(int character) | |
|- | |- | ||
| − | | | + | |- bgcolor="#dddddd" valign="top" |
| − | | style="background: | + | | style="background:lime" | yes |
| − | + | | int isalpha(int character) | |
|- | |- | ||
| − | | | + | |- bgcolor="#dddddd" valign="top" |
| − | | style="background: | + | | style="background:lime" | yes |
| − | + | | int isascii(int character) | |
|- | |- | ||
| − | | | + | |- bgcolor="#dddddd" valign="top" |
| − | | style="background: | + | | style="background:lime" | yes |
| − | + | | int isblanc(int character) | |
|- | |- | ||
| − | | | + | |- bgcolor="#eeeeee" valign="top" |
| − | | style="background: | + | | style="background:lime" | yes |
| − | + | | int iscntrl(int character) | |
|- | |- | ||
| − | | | + | |- bgcolor="#dddddd" valign="top" |
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | int isdigit(int character) | |
|- | |- | ||
| − | | | + | |- bgcolor="#eeeeee" valign="top" |
| − | | style="background: | + | | style="background:lime" | yes |
| − | + | | int isgraph(int character) | |
| + | |- | ||
| + | |- bgcolor="#dddddd" valign="top" | ||
| + | | style="background:lime" | yes | ||
| + | | int islower(int character) | ||
| + | |- | ||
| + | |- bgcolor="#eeeeee" valign="top" | ||
| + | | style="background:lime" | yes | ||
| + | | int isprint(int character) | ||
| + | |- | ||
| + | |- bgcolor="#dddddd" valign="top" | ||
| + | | style="background:lime" | yes | ||
| + | | int ispunct(int character) | ||
|- | |- | ||
| − | | | + | |- bgcolor="#eeeeee" valign="top" |
| − | | style="background: | + | | style="background:lime" | yes |
| − | + | | int isspace(int character) | |
| − | |- bgcolor=" | + | |- |
| − | | | + | |- 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" | ||
| + | | colspan=2 | '''errno.h''' | ||
|- | |- | ||
| + | | style="background:lime" | no | ||
| <code>errno</code> (global) | | <code>errno</code> (global) | ||
| − | |||
| − | |- bgcolor=" | + | |- bgcolor="#6699ff" |
| − | | colspan=2 | + | | colspan=2 | '''float.h''' |
| − | |- bgcolor=" | + | |- bgcolor="#6699ff" |
| − | | colspan=2 | + | | colspan=2 | '''limits.h''' |
| − | + | ||
| − | + | ||
| − | + | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''locale.h''' | ||
|- | |- | ||
| + | | style="background:red" | no | ||
| <code>char *setlocale(int category, const char *locale)</code> | | <code>char *setlocale(int category, const char *locale)</code> | ||
| + | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| + | | <code>struct lconv *localeconv(void)</code> | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''math.h''' | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double exp(double x)</code> | |
| − | | | + | |
| − | + | ||
| − | + | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double log(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double log10(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double pow(double x, double y)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double sqrt(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double ceil(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double floor(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double fabs(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double ldexp(double x, int n)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double frexp(double x, int* exp)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double modf(double x, double* ip)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double fmod(double x, double y)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double sin(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double cos(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double tan(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double asin(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double acos(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double atan(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double atan2(double y, double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double sinh(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double cosh(double x)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| + | | <code>double tanh(double x)</code> | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''setjmp.h''' | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int setjmp(jmp_buf env)</code> | |
| − | + | ||
| − | + | ||
| − | + | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| + | | <code>void longjmp(jmp_buf env, int val)</code> | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''signal.h''' | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>void (*signal(int sig, void (*handler)(int)))(int)</code> | |
| − | + | ||
| − | + | ||
| − | + | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| + | | <code>int raise(int sig)</code> | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''stdarg.h''' | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>void va_start(va_list ap, lastarg)</code> | |
| − | | | + | |
| − | + | ||
| − | + | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>type va_arg(va_list ap, type)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | |||
| − | |||
| <code>void va_end(va_list ap)</code> | | <code>void va_end(va_list ap)</code> | ||
| − | |||
| − | |- bgcolor=" | + | |- bgcolor="#6699ff" |
| − | | colspan=2 | + | | colspan=2 | '''stddef.h''' |
|- colspan=2 | |- colspan=2 | ||
| TODO | | TODO | ||
| − | |- bgcolor=" | + | |- bgcolor="#6699ff" |
| − | | colspan=2 | + | | colspan=2 | '''stdio.h''' |
| − | + | ||
|- | |- | ||
| + | | style="background:red" | no | ||
| <code>FILE* fopen(const char* filename, const char* mode)</code> | | <code>FILE* fopen(const char* filename, const char* mode)</code> | ||
| + | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>FILE* freopen(const char* filename, const char* mode, FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int fflush(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int fclose(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int remove(const char* filename)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int rename(const char* oldname, const char* newname)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>FILE* tmpfile()</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>char* tmpnam(char s[L_tmpnam])</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int setvbuf(FILE* stream, char* buf, int mode, size_t size)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>void setbuf(FILE* stream, char* buf)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | |||
| − | |||
| <code>int fprintf(FILE* stream, const char* format, ...)</code> | | <code>int fprintf(FILE* stream, const char* format, ...)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>int printf(const char* format, ...)</code> | | <code>int printf(const char* format, ...)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>int sprintf(char* s, const char* format, ...)</code> | | <code>int sprintf(char* s, const char* format, ...)</code> | ||
| − | | style="background: | + | |- |
| − | + | | 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> | |
|- | |- | ||
| + | | 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: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 | ||
| <code>int fscanf(FILE* stream, const char* format, ...)</code> | | <code>int fscanf(FILE* stream, const char* format, ...)</code> | ||
| + | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int scanf(const char* format, ...)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int sscanf(char* s, const char* format, ...)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int fgetc(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>char* fgets(char* s, int n, FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int fputc(int c, FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>char* fputs(const char* s, FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | |||
| − | |||
| <code>int getc(FILE* stream)</code> | | <code>int getc(FILE* stream)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>int getchar(void)</code> | | <code>int getchar(void)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:red" | no | ||
| <code>char* gets(char* s)</code> | | <code>char* gets(char* s)</code> | ||
| + | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | |||
| − | |||
| <code>int putc(int c, FILE* stream)</code> | | <code>int putc(int c, FILE* stream)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>int putchar(int c)</code> | | <code>int putchar(int c)</code> | ||
| + | |- | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | |||
| − | |||
| <code>int puts(const char* s)</code> | | <code>int puts(const char* s)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:red" | no | ||
| <code>int ungetc(int c, FILE* stream)</code> | | <code>int ungetc(int c, FILE* stream)</code> | ||
| + | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int fseek(FILE* stream, long offset, int origin)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>long ftell(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>void rewind(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int fgetpos(FILE* stream, fpos_t* ptr)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int fsetpos(FILE* stream, const fpos_t* ptr)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>void clearerr(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int feof(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int ferror(FILE* stream)</code> | |
|- | |- | ||
| − | |||
| 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" | ||
| + | | colspan=2 | '''stdlib.h''' | ||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>int abs(int n)</code> | | <code>int abs(int n)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | 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 | ||
| − | + | | <code>div_t div(int num, int denom)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>ldiv_t ldiv(long num, long denom)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double atof(const char* s)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int atoi(const char* s)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>long atol(const char* s)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | |||
| − | |||
| <code>double strtod(const char* s, char** endp)</code> | | <code>double strtod(const char* s, char** endp)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | 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: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> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>void* calloc(size_t nobj, size_t size)</code> | | <code>void* calloc(size_t nobj, size_t size)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>void* malloc(size_t size)</code> | | <code>void* malloc(size_t size)</code> | ||
| + | |- | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | <code>void* realloc(void* p, size_t size)</code> | |
|- | |- | ||
| − | |||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | <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:lime" | no | ||
| <code>void exit(int status)</code> | | <code>void exit(int status)</code> | ||
| + | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int atexit(void (*fcm)(void))</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>int system(const char* s)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | |||
| − | |||
| <code>char* getenv(const char* name)</code> | | <code>char* getenv(const char* name)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <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, <br />int (*cmp)(const void*, const void*))</code> | |
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>int rand(void)</code> | | <code>int rand(void)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>void srand(unsigned int seed)</code> | | <code>void srand(unsigned int seed)</code> | ||
| − | |||
| − | |||
| − | |||
| − | |||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''string.h''' | ||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>char* strcpy(char* s, const char* ct)</code> | | <code>char* strcpy(char* s, const char* ct)</code> | ||
| + | |- | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | |||
| − | |||
| <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:lime" | no | ||
| <code>char* strcat(char* s, const char* ct)</code> | | <code>char* strcat(char* s, const char* ct)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>char* strncat(char* s, const char* ct, size_t n)</code> | | <code>char* strncat(char* s, const char* ct, size_t n)</code> | ||
| + | |- | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | <code>int strcmp(const char* cs, const char* ct)</code> | |
|- | |- | ||
| − | |||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | |||
| − | |||
| <code>int strncmp(const char* cs, const char* ct, size_t n)</code> | | <code>int strncmp(const char* cs, const char* ct, size_t n)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:red" | no | ||
| <code>int strcoll(const char* cs, const char* ct)</code> | | <code>int strcoll(const char* cs, const char* ct)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>char* strchr(const char* cs, int c)</code> | | <code>char* strchr(const char* cs, int c)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | no | ||
| <code>char* strrchr(const char* cs, int c)</code> | | <code>char* strrchr(const char* cs, int c)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | 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:lime" | no | ||
| <code>size_t strcspn(const char* cs, const char* ct)</code> | | <code>size_t strcspn(const char* cs, const char* ct)</code> | ||
| + | |- | ||
| style="background:red" | no | | style="background:red" | no | ||
| − | |||
| − | |||
| <code>char* strpbrk(const char* cs, const char* ct)</code> | | <code>char* strpbrk(const char* cs, const char* ct)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>char* strstr(const char* cs, const char* ct)</code> | | <code>char* strstr(const char* cs, const char* ct)</code> | ||
| + | |- | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | <code>size_t strlen(const char* cs)</code> | |
|- | |- | ||
| − | |||
| style="background:lime" | yes | | 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> | |
|- | |- | ||
| + | | 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 | ||
| − | |||
| − | |||
| <code>size_t strxfrm(char* s, const char* ct, size_t n)</code> | | <code>size_t strxfrm(char* s, const char* ct, size_t n)</code> | ||
| − | |||
| − | |||
|- | |- | ||
| + | | style="background:lime" | yes | ||
| <code>void* memcpy(void* s, const void* ct, size_t n)</code> | | <code>void* memcpy(void* s, const void* ct, size_t n)</code> | ||
| + | |- | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | |||
| − | |||
| <code>void* memmove(void* s, const void* ct, size_t n)</code> | | <code>void* memmove(void* s, const void* ct, size_t n)</code> | ||
| + | |- | ||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | <code>int memcmp(const void* cs, const void* ct, size_t n)</code> | |
| + | |- | ||
| + | | style="background:red" | no | ||
| + | | <code>void* memchr(const void* cs, int c, size_t n)</code> | ||
|- | |- | ||
| − | |||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| + | | <code>void* memset(void* s, int c, size_t n)</code> | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''time.h''' | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>clock_t clock(void)</code> | |
|- | |- | ||
| − | |||
| style="background:lime" | yes | | style="background:lime" | yes | ||
| − | + | | <code>int gettimeofday (struct timeval *tv, void *tz)</code> | |
| − | | | + | |
| − | + | ||
| − | + | ||
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>time_t time(time_t* tp)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>double difftime(time_t time2, time_t time1)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>time_t mktime(struct tm* tp)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>char* asctime(const struct tm* tp)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>char* ctime(const time_t* tp)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>struct tm* gmtime(const time_t* tp)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| − | + | | <code>struct tm* localtime(const time_t* tp)</code> | |
|- | |- | ||
| − | |||
| style="background:red" | no | | style="background:red" | no | ||
| + | | <code>size_t strftime(char* s, size_t smax, const char* fmt,<br />const struct tm* tp)</code> | ||
| + | |- bgcolor="#6699ff" | ||
| + | | colspan=2 | '''unistd.h''' | ||
|- | |- | ||
| − | | <code> | + | | 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 671: | 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: |