Libpayload: Difference between revisions
Whiterocker (talk | contribs) (→Libc Coverage: complete first-pass at libc coverage table) |
m (Fixed downloading from Subversion to Git) |
||
(35 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
'''libpayload''' is a small BSD-licensed | '''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 9: | Line 7: | ||
* The libpayload functions can be tested and scrutinized outside payload development. | * The libpayload functions can be tested and scrutinized outside payload development. | ||
* Payloads themselves may be partly host-tested, e.g. against an emulation libpayload. | * 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.'' | ''Just give us a main() and a pocket full of dreams and we'll do the rest.'' | ||
== | == Features == | ||
* Provides a [[Libpayload#Libc_coverage|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. | |||
== Design == | |||
* [[Payload API|Discussion of the API for passing parameters to the payload]] | |||
== 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. | |||
* [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 == | |||
== | {| border="0" valign="top" | ||
| valign="top"| | |||
{| border="0" | {| border="0" style="font-size: smaller" | ||
|- bgcolor="#6699ff" | |- bgcolor="#6699ff" | ||
! align="left" | Status | |||
! align="left" | Function/Macro/Variable | ! align="left" | Function/Macro/Variable | ||
|- bgcolor=" | |- bgcolor="#6699ff" | ||
| colspan=2 | | colspan=2 | '''assert.h''' | ||
|- | |||
|- bgcolor="#eeeeee" valign="top" | |||
| style="background:lime" | no | |||
| assert() | |||
|- bgcolor="#6699ff" | |||
| colspan=2 | '''ctype.h''' | |||
|- | |||
|- bgcolor="#eeeeee" valign="top" | |||
| style="background:lime" | yes | |||
| int isalnum(int character) | |||
|- | |||
|- bgcolor="#dddddd" valign="top" | |||
| style="background:lime" | yes | |||
| int isalpha(int character) | |||
|- | |||
|- bgcolor="#dddddd" valign="top" | |||
| style="background:lime" | yes | |||
| int isascii(int character) | |||
|- | |- | ||
| | |- bgcolor="#dddddd" valign="top" | ||
| 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: | | 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: | | style="background:lime" | yes | ||
| int islower(int character) | |||
|- | |- | ||
| | |- bgcolor="#eeeeee" valign="top" | ||
| style="background: | | style="background:lime" | yes | ||
| int isprint(int character) | |||
|- | |- | ||
| | |- bgcolor="#dddddd" valign="top" | ||
| style="background: | | style="background:lime" | yes | ||
| int ispunct(int character) | |||
|- | |- | ||
| | |- bgcolor="#eeeeee" valign="top" | ||
| style="background: | | style="background:lime" | yes | ||
| int isspace(int character) | |||
|- | |- | ||
| | |- bgcolor="#dddddd" valign="top" | ||
| style="background: | | style="background:lime" | yes | ||
| int isupper(int character) | |||
|- | |- | ||
| | |- bgcolor="#eeeeee" valign="top" | ||
| style="background: | | style="background:lime" | yes | ||
| int isxdigit(int character) | |||
|- | |- | ||
| | |- bgcolor="#eeeeee" valign="top" | ||
| style="background: | | 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 | |||
| <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: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 | |||
| <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> | |||
| | |} | ||
| | | 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 | |||
| <code>void* realloc(void* p, size_t size)</code> | | <code>void* realloc(void* p, size_t size)</code> | ||
|- | |- | ||
| style="background:lime" | yes | |||
| <code>void free(void* p)</code> | | <code>void free(void* p)</code> | ||
|- | |- | ||
| 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 | |||
| <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 | |||
| <code>int strcmp(const char* cs, const char* ct)</code> | | <code>int strcmp(const char* cs, const char* ct)</code> | ||
|- | |- | ||
| 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 | |||
| <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 | |||
| <code>char* strerror(int n)</code> | | <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 | |||
| <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 | |||
| <code>int memcmp(const void* cs, const void* ct, size_t n)</code> | | <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> | | <code>void* memchr(const void* cs, int c, size_t n)</code> | ||
|- | |- | ||
| style="background:lime" | yes | |||
| <code>void* memset(void* s, int c, size_t n)</code> | | <code>void* memset(void* s, int c, size_t n)</code> | ||
|- bgcolor="#6699ff" | |||
| colspan=2 | '''time.h''' | |||
|- | |- | ||
| 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 | ||
| <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 == | ||
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 659: | Line 609: | ||
return 0; | return 0; | ||
} | } | ||
</ | </source> | ||
Building the payload: | |||
$ '''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.
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.
Design
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).
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
Documentation
See the autogenerated documentation for libpayload here.
Libc coverage
|
|
Usage example
Here's an example of a very simple payload (hello.c) and how to build it:
<source lang="C">
- include <libpayload.h>
int main(void) {
printf("Hello, world!\n"); halt(); return 0;
} </source>
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: |