https://www.coreboot.org/api.php?action=feedcontributions&user=Whiterocker&feedformat=atom
coreboot - User contributions [en]
2024-03-28T22:52:49Z
User contributions
MediaWiki 1.40.0
https://www.coreboot.org/index.php?title=AMD_Geode_Porting_Guide&diff=10963
AMD Geode Porting Guide
2011-12-31T20:06:09Z
<p>Whiterocker: /* Manual build */ Fix link to AMD VSA image.</p>
<hr />
<div>Welcome! This is a collection on information to help you on your way to porting coreboot to an AMD Geode platform. Most of the information is about the Geode LX and CS5536 but may also be relevant to older versions of Geode. (Note that this does not cover the Geode NX).<br />
<br />
If you find something incorrect or other deficiencies in this information please fix them!<br />
<br />
== Documentation ==<br />
* [[Development Guidelines]]<br />
* [[Developer Manual]]<br />
* Many Geode LX systems are based on the [http://www.amd.com/us-en/ConnectivitySolutions/ProductInformation/0,,50_2330_9863_13022%5E13060,00.html DB800 reference design], so that is a good place to start.<br />
* [http://www.amd.com/files/connectivitysolutions/geode/geode_lx/33234H_LX_databook.pdf Geode LX CPU databook]<br />
* [http://www.amd.com/files/connectivitysolutions/geode/geode_lx/33238G_cs5536_db.pdf Geode CS5536 Southbridge databook]<br />
* [http://www.amd.com/us-en/ConnectivitySolutions/ProductInformation/0,,50_2330_9863_13022%5E11363,00.html Geode Linux webpage] - The VSA and GeodeROM Porting guides are interesting.<br />
* [http://linuxbios.org/images/8/88/Crouse-Reprint.pdf Breaking the Chains -- Using LinuxBIOS to Liberate Embedded x86 Processors] - was heavily influenced by the experience of the initial Geode LX port.<br />
<br />
== Build coreboot for Geode ==<br />
Use [[Buildrom|buildrom]]. It can handle the payload and VSA for you.<br />
<br />
$ svn co svn://coreboot.org/buildrom<br />
<br />
Checkout coreboot:<br />
<br />
$ svn co svn://coreboot.org/coreboot/trunk coreboot<br />
<br />
Build a db800 for starters and set buildrom to build your local svn directory in menuconfig.<br />
<br />
$ make menuconfig<br />
$ make<br />
<br />
From this point you can customize the db800 and then make the target, mainboard, and buildrom customization patches later. <br />
<br />
==== Manual build ====<br />
If you really want to get your hands dirty. Roll up your sleeves...<br />
<br />
Go get the current VSA binary, '''gpl_vsa_lx_102.bin.gz''', hosted by [[User:MJones|MJones]] [http://marcjonesconsulting.com/gplvsa/gpl_vsa_lx_102.bin.gz here]. Older versions like '''amd_vsa_lx_1.01.bin.gz''' are still available [http://support.amd.com/us/Embedded_TechDownloads/amd_vsa_lx_1.01.bin.gz here] and extract it. It will need to be compressed and padded to make the correct ROM size. For a typical Geode platform the binary should be 36KB. Calculate the padding as follows: 36864 - size of lx_vsa.nrv2b = padding. The current image requires padding of 3264.<br />
<br />
Then, find a [[Payloads|payload]] and build it.<br />
<br />
$ cd coreboot/targets<br />
$ ./buildtarget amd/db800<br />
$ cd amd/db800/db800<br />
$ cp /from/someplace/payloadx ./payload.elf<br />
$ make<br />
$ cp /from/someplace/gpl_vsa_lx_102.bin .<br />
$ fallback/nrv2b e gpl_vsa_lx_102.bin lx_vsa.nrv2b<br />
$ dd if=/dev/zero of=padding bs=1 count=3264 <br />
$ cat lx_vsa.nrv2b padding > lx_vsa.36k.bin<br />
$ cat lx_vsa.36k.bin db800.rom > amd-db800.rom<br />
<br />
You should now have a 512KB ROM image. You should be able to use [[flashrom]] or a ROM programmer to get the image onto your system. (Be prepared to brick it...)<br />
<br />
The current GPL VSA source is hosted by coreboot.org, <code>svn://coreboot.org/vsa/trunk/gplvsa2</code>.<br />
The original source is still available on [http://dev.laptop.org/git?p=geode-vsa;a=tree;h=10f157122acaae414431c88a2403ed692453c960;hb=10f157122acaae414431c88a2403ed692453c960 laptop.org].<br />
<br />
Although not currently functional: [[OpenVSA]] aims to provide VSA buildable with open tools.<br />
<br />
== Porting ==<br />
Now that you are building Geode coreboot images you are ready to make customizations to your platform. Most customizations can be handled in the mainboard directory.<br />
<br />
$ cd coreboot-v2/src/mainboard/amd/db800<br />
<br />
Make yourself familiar with this directory. There are not too many files.<br />
<br />
=== IRQ routing ===<br />
Almost every platform will require customization of the PIR table in '''irq_table.c'''.<br />
<br />
Make yourself familiar with the [http://www.microsoft.com/whdc/archive/pciirq.mspx PIR table specification].<br />
<br />
If you have the motherboard schematics adjusting the table is fairly simple. <br />
<br />
First check how many on board devices (including PCI slots) and update '''IRQ_SLOT_COUNT''' in Options.lb. Remember any time you change Options.lb or Config.lb you need to redo ./buildtarget.<br />
<br />
Next check the INT lines (GPIOs) into the CS5536.<br />
<br />
{| border="1"<br />
|+ CS5536<br />
! line !! CS5536 signal/pin <br />
|-<br />
! PCI$INTA_X<br />
| GPIO0 / INTA_L<br />
|-<br />
! PCI$INTB_X<br />
| GPIO7 / INTB_X <br />
|-<br />
! PCI$INTC_X <br />
| GPIO12 / INTR <br />
|-<br />
! PCI$INTD_X<br />
| GPIO13 / 8MI_L<br />
|}<br />
<br />
Based on this information you can setup the<br />
register "enable_gpio_int_route" = "0x0D0C0700"<br />
line in Config.lb.<br />
<br />
For each motherboard device check the INT pins. For example a PCI slot would look something like this:<br />
{| border="1"<br />
|+ PCI slot<br />
! pin !! device !! line <br />
|-<br />
! pin A6<br />
| INTA_X || PCI$INTB_X <br />
|-<br />
! pin A7<br />
| INTC_X || PCI$INTD_X <br />
|-<br />
! pin B7<br />
| INTB_X || PCI$INTC_X <br />
|-<br />
! pin B8<br />
| INTD_X || PCI$INTA_X <br />
|}<br />
<br />
Take a closer look at irq_tables.c.<br />
L_PIRQA is the chipset incoming IRQ line and M_PIRQA is the bitmap of IRQ numbers it can generate. These should not change. You can adjust the IRQs generated by changing PIRQA etc. Yes, it is fine if they all share 10 or 11 but it might be easier to debug if they all have a different IRQ.<br />
<br />
The table entries are the slot/device IRQ lines. I will break one entry down.<br />
<br />
/* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */<br />
{0x00, (0x01 << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, /* cpu */<br />
{0x00, (0x0F << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x0, 0x0}, /* chipset */<br />
{0x00, (0x0D << 3) | 0x0, {{L_PIRQB, M_PIRQB}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, /* ethernet */<br />
{0x00, (0x0E << 3) | 0x0, {{L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}}, 0x1, 0x0}, /* slot1 */<br />
<br />
I will break the last entry down.<br />
<br />
* '''0x00, (0x0E << 3) | 0x0''' &mdash; slot(device) address (IDSEL)<br />
* '''{L_PIRQC, M_PIRQC}''' &mdash; slot INT line A to chipset INT line C (L_PIRQC), it can generate IRQs (M_PIRQC)<br />
* '''{L_PIRQD, M_PIRQD}''' &mdash; slot INT line B to chipset INT line C (L_PIRQD), it can generate IRQs (M_PIRQD)<br />
* '''{L_PIRQA, M_PIRQA}''' &mdash; slot INT line C to chipset INT line A...<br />
* '''{L_PIRQB, M_PIRQB}''' &mdash; slot INT lineD to chipset INT line B...<br />
* '''0x1''' &mdash; arbitrary slot number<br />
* '''0x0''' &mdash; rfu, always 0<br />
<br />
If you don't have the schematics you will have to figure out the routing on your own. With '''lspci''' output and some trial and error you can figure it out. [[IRC]] or the [[Mailinglist|mailing list]] is a good place to get help if you are stuck.<br />
<br />
There's also a wiki entry on [[Creating Valid IRQ Tables|figuring out the routing table]].<br />
<br />
==== LPC Serial IRQs ====<br />
IRQs from [http://en.wikipedia.org/wiki/Low_Pin_Count LPC] need to be passed to the SC5536 [http://en.wikipedia.org/wiki/Intel_8259 PIC]. It is important to only enable the expected sources and to configure the polarity. Enables are a bit mask. It depends on the [http://en.wikipedia.org/wiki/Super_I/O SIO] but typically, the polarity is the inverse of the enables as you can see in the example below. (Note that the Geode MFGPT driver uses IRQ7 by default. That will conflict with LPC SIRQ for the LPT port if you require it.)<br />
<br />
Config.lb - <br />
# Invert mask = IRQ 12 and 1 are active high. Keyboard and Mouse, UARTs, etc IRQs. OK<br />
register "lpc_serirq_enable" = "0x0000105a"<br />
register "lpc_serirq_polarity" = "0x0000EFA5"<br />
register "lpc_serirq_mode" = "1"<br />
<br />
=== Memory ===<br />
On some systems the memory is soldered down and there is no SPD (Serial Presence Detect) which is required to properly setup DDR memory. In this case you will need to provide an SPD values in coreboot. This should be done by customizing '''spd_read_byte()''' in '''cache_as_ram_auto.c''' to do a table lookup. A good example can be found in [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/pcengines/alix1c/cache_as_ram_auto.c src/mainboard/pcengines/alix1c/cache_as_ram_auto.c].<br />
<br />
=== Power button ===<br />
By default the CS5536 code sets the power button up for the '''4 second soft off setting'''. If your system is booting and shuts off after four seconds check for a power button enable jumper. If your system doesn't have a power button and comes on when plugged in you will need to adjust the power button MSR. This is best done in cache_as_ram_main() in cache_as_ram_auto.c after the call to cs5536_early_setup(). The MSR name is PM Fail-Safe Delay and Enable (PM_FSD). (Yes, this could be made a Config.lb option)<br />
<br />
Add the following line:<br />
outl(0x00, PMS_IO_BASE + 0x40); // disable the power button<br />
<br />
=== Graphics ===<br />
For Geode graphics, use the upstreamed [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=drivers/video/geode;h=e680c13755a7bfd9fb40d7f41cb7b30b033fdd67;hb=HEAD Geode framebuffer driver] and the [http://gitweb.freedesktop.org/?p=xorg/driver/xf86-video-amd.git;a=summary Geode X driver]. There is no VGA ROM for Geode at this time.<br />
<br />
=== Debug ===<br />
<br />
==== Serial Output ====<br />
The Geode CS5536 has two serial ports but on many mainboards the SIO serial ports are used instead. Setup Config.lb and the serial initialization depending on the configuration of the mainboard.<br />
<br />
Config.lb -<br />
register "com1_enable" = "1"<br />
register "com1_address" = "0x3F8"<br />
register "com1_irq" = "4"<br />
register "com2_enable" = "1"<br />
register "com2_address" = "0x2F8"<br />
register "com2_irq" = "3"<br />
<br />
In this [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/amd/norwich/Config.lb case] ''' "1" ''' enables the CS5536 serial port and the address and irq are setup to these values. The other important part of serial output is to setup the ports very early. This is done in [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/amd/norwich/cache_as_ram_auto.c cache_as_ram_main()].<br />
<br />
For an example of using the SIO serial ports instead of the CS5536, see the [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/amd/db800/Config.lb DB800 mainboard].<br />
<br />
==== Dump System Configuration ====<br />
'''print_conf()''' in [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/northbridge/amd/lx/northbridge.c#L125 src/northbridge/amd/lx/northbridge.c] can help provide a good picture of the system configuration and should be one of the first tools you use to debug memory or other configuration issues.<br />
<br />
=== Other ===<br />
What are we missing?<br />
<br />
{{GPL}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Developer_Manual&diff=10302
Developer Manual
2011-01-03T20:01:41Z
<p>Whiterocker: /* View From The CPU: Intel Architecture */</p>
<hr />
<div></div>
Whiterocker
https://www.coreboot.org/index.php?title=Developer_Manual&diff=9316
Developer Manual
2010-02-13T19:50:17Z
<p>Whiterocker: /* View From The CPU: Intel Architecture */</p>
<hr />
<div></div>
Whiterocker
https://www.coreboot.org/index.php?title=Developer_Manual&diff=7633
Developer Manual
2008-12-01T06:34:10Z
<p>Whiterocker: /* Hardware Reset */</p>
<hr />
<div></div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=6012
Libpayload
2008-03-20T05:36:03Z
<p>Whiterocker: /* Libc Coverage */</p>
<hr />
<div>'''libpayload''' is a small BSD-licensed "library" (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads.<br />
<br />
== Overview ==<br />
<br />
The benefits of linking a coreboot payload against libpayload are:<br />
<br />
* Payloads do not have to implement and maintain low-level code for I/O, common functions, etc.<br />
* Payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future.<br />
* The libpayload functions can be tested and scrutinized outside payload development.<br />
* Payloads themselves may be partly host-tested, e.g. against an emulation libpayload.<br />
* Leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''Just give us a main() and a pocket full of dreams and we'll do the rest.''<br />
<br />
== Download ==<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/payloads/libpayload<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- <br />
| <code>double exp(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log10(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double pow(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sqrt(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ceil(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double floor(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fabs(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ldexp(double x, int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double frexp(double x, int* exp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double modf(double x, double* ip)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fmod(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double asin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double acos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan2(double y, double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sinh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cosh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tanh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- <br />
| <code>int setjmp(jmp_buf env)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void longjmp(jmp_buf env, int val)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- <br />
| <code>void (*signal(int sig, void (*handler)(int)))(int)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int raise(int sig)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- <br />
| <code>void va_start(va_list ap, lastarg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>type va_arg(va_list ap, type)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void va_end(va_list ap)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- <br />
| <code>FILE* fopen(const char* filename, const char* mode)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* freopen(const char* filename, const char* mode, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fflush(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fclose(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int remove(const char* filename)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rename(const char* oldname, const char* newname)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* tmpfile()</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* tmpnam(char s[L_tmpnam])</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int setvbuf(FILE* stream, char* buf, int mode, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void setbuf(FILE* stream, char* buf)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fprintf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int printf(const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int sprintf(char* s, const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vprintf(const char* format, va_list arg)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int vsprintf(char* s, const char* format, va_list arg)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int fscanf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int scanf(const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int sscanf(char* s, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fgets(char* s, int n, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fputc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fputs(const char* s, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getchar(void)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* gets(char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putchar(int c)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int puts(const char* s)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int ungetc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fseek(FILE* stream, long offset, int origin)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long ftell(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void rewind(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetpos(FILE* stream, fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fsetpos(FILE* stream, const fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void clearerr(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int feof(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ferror(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void perror(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- <br />
| <code>int abs(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long labs(long n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>div_t div(int num, int denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>ldiv_t ldiv(long num, long denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atof(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atoi(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long atol(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double strtod(const char* s, char** endp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long strtol(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>unsigned long strtoul(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* calloc(size_t nobj, size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* malloc(size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* realloc(void* p, size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void free(void* p)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void abort()</code><br />
| style="background:lime" | yes as <code>halt()</code><br />
<br />
|- <br />
| <code>void exit(int status)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atexit(void (*fcm)(void))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int system(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* getenv(const char* name)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* bsearch(const void* key, const void* base, size_t n, size_t size, int (*cmp)(const void* keyval, const void* datum))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rand(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void srand(unsigned int seed)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- <br />
| <code>char* strcpy(char* s, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strncpy(char* s, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strcat(char* s, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strncat(char* s, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strcmp(const char* cs, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strncmp(const char* cs, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strcoll(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strchr(const char* cs, int c)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strrchr(const char* cs, int c)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strcspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strpbrk(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strstr(const char* cs, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>size_t strlen(const char* cs)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strerror(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strtok(char* s, const char* t)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strxfrm(char* s, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memcpy(void* s, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* memmove(void* s, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int memcmp(const void* cs, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* memchr(const void* cs, int c, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memset(void* s, int c, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- <br />
| <code>clock_t clock(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t time(time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double difftime(time_t time2, time_t time1)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t mktime(struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* asctime(const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* ctime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* gmtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* localtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="red"<br />
| No Support<br />
|- bgcolor="yellow"<br />
| Partial Support<br />
|- bgcolor="lime"<br />
| Full Support<br />
|}<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<br />
<pre><br />
#include <libpayload.h><br />
<br />
int main(void)<br />
{<br />
printf("Hello, world!\n");<br />
halt();<br />
return 0;<br />
}<br />
</pre><br />
<br />
Build example (basic idea):<br />
<br />
gcc -o hello_payload hello_payload.c<br />
<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=6011
Libpayload
2008-03-20T05:34:38Z
<p>Whiterocker: /* Libc Coverage */ part 2</p>
<hr />
<div>'''libpayload''' is a small BSD-licensed "library" (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads.<br />
<br />
== Overview ==<br />
<br />
The benefits of linking a coreboot payload against libpayload are:<br />
<br />
* Payloads do not have to implement and maintain low-level code for I/O, common functions, etc.<br />
* Payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future.<br />
* The libpayload functions can be tested and scrutinized outside payload development.<br />
* Payloads themselves may be partly host-tested, e.g. against an emulation libpayload.<br />
* Leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''Just give us a main() and a pocket full of dreams and we'll do the rest.''<br />
<br />
== Download ==<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/payloads/libpayload<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- <br />
| <code>double exp(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log10(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double pow(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sqrt(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ceil(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double floor(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fabs(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ldexp(double x, int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double frexp(double x, int* exp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double modf(double x, double* ip)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fmod(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double asin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double acos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan2(double y, double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sinh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cosh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tanh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- <br />
| <code>int setjmp(jmp_buf env)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void longjmp(jmp_buf env, int val)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- <br />
| <code>void (*signal(int sig, void (*handler)(int)))(int)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int raise(int sig)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- <br />
| <code>void va_start(va_list ap, lastarg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>type va_arg(va_list ap, type)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void va_end(va_list ap)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- <br />
| <code>FILE* fopen(const char* filename, const char* mode)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* freopen(const char* filename, const char* mode, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fflush(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fclose(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int remove(const char* filename)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rename(const char* oldname, const char* newname)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* tmpfile()</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* tmpnam(char s[L_tmpnam])</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int setvbuf(FILE* stream, char* buf, int mode, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void setbuf(FILE* stream, char* buf)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fprintf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int printf(const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int sprintf(char* s, const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vprintf(const char* format, va_list arg)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int vsprintf(char* s, const char* format, va_list arg)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int fscanf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int scanf(const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int sscanf(char* s, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fgets(char* s, int n, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fputc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fputs(const char* s, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getchar(void)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* gets(char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putchar(int c)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int puts(const char* s)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int ungetc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fseek(FILE* stream, long offset, int origin)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long ftell(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void rewind(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetpos(FILE* stream, fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fsetpos(FILE* stream, const fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void clearerr(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int feof(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ferror(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void perror(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- <br />
| <code>int abs(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long labs(long n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>div_t div(int num, int denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>ldiv_t ldiv(long num, long denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atof(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atoi(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long atol(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double strtod(const char* s, char** endp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long strtol(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>unsigned long strtoul(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* calloc(size_t nobj, size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* malloc(size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* realloc(void* p, size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void free(void* p)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void abort()</code><br />
| style="background:lime" | yes as <code>halt()</code><br />
<br />
|- <br />
| <code>void exit(int status)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atexit(void (*fcm)(void))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int system(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* getenv(const char* name)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* bsearch(const void* key, const void* base, size_t n, size_t size, int (*cmp)(const void* keyval, const void* datum))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rand(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void srand(unsigned int seed)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- <br />
| <code>char* strcpy(char* s, const char* ct)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>char* strncpy(char* s, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strcat(char* s, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strncat(char* s, const char* ct, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int strcmp(const char* cs, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strncmp(const char* cs, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strcoll(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strchr(const char* cs, int c)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>char* strrchr(const char* cs, int c)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strcspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strpbrk(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strstr(const char* cs, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>size_t strlen(const char* cs)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strerror(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strtok(char* s, const char* t)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strxfrm(char* s, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memcpy(void* s, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* memmove(void* s, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int memcmp(const void* cs, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* memchr(const void* cs, int c, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memset(void* s, int c, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- <br />
| <code>clock_t clock(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t time(time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double difftime(time_t time2, time_t time1)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t mktime(struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* asctime(const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* ctime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* gmtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* localtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="red"<br />
| No Support<br />
|- bgcolor="yellow"<br />
| Partial Support<br />
|- bgcolor="lime"<br />
| Full Support<br />
|}<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<br />
<pre><br />
#include <libpayload.h><br />
<br />
int main(void)<br />
{<br />
printf("Hello, world!\n");<br />
halt();<br />
return 0;<br />
}<br />
</pre><br />
<br />
Build example (basic idea):<br />
<br />
gcc -o hello_payload hello_payload.c<br />
<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=6010
Libpayload
2008-03-20T05:20:41Z
<p>Whiterocker: /* Libc Coverage */ reflect reduction in coverage as per SVN commit</p>
<hr />
<div>'''libpayload''' is a small BSD-licensed "library" (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads.<br />
<br />
== Overview ==<br />
<br />
The benefits of linking a coreboot payload against libpayload are:<br />
<br />
* Payloads do not have to implement and maintain low-level code for I/O, common functions, etc.<br />
* Payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future.<br />
* The libpayload functions can be tested and scrutinized outside payload development.<br />
* Payloads themselves may be partly host-tested, e.g. against an emulation libpayload.<br />
* Leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''Just give us a main() and a pocket full of dreams and we'll do the rest.''<br />
<br />
== Download ==<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/payloads/libpayload<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- <br />
| <code>double exp(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log10(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double pow(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sqrt(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ceil(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double floor(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fabs(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ldexp(double x, int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double frexp(double x, int* exp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double modf(double x, double* ip)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fmod(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double asin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double acos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan2(double y, double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sinh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cosh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tanh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- <br />
| <code>int setjmp(jmp_buf env)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void longjmp(jmp_buf env, int val)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- <br />
| <code>void (*signal(int sig, void (*handler)(int)))(int)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int raise(int sig)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- <br />
| <code>void va_start(va_list ap, lastarg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>type va_arg(va_list ap, type)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void va_end(va_list ap)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- <br />
| <code>FILE* fopen(const char* filename, const char* mode)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* freopen(const char* filename, const char* mode, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fflush(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fclose(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int remove(const char* filename)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rename(const char* oldname, const char* newname)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* tmpfile()</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* tmpnam(char s[L_tmpnam])</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int setvbuf(FILE* stream, char* buf, int mode, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void setbuf(FILE* stream, char* buf)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fprintf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int printf(const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int sprintf(char* s, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vprintf(const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vsprintf(char* s, const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fscanf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int scanf(const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int sscanf(char* s, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fgets(char* s, int n, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fputc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fputs(const char* s, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getchar(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* gets(char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putchar(int c)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int puts(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ungetc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fseek(FILE* stream, long offset, int origin)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long ftell(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void rewind(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetpos(FILE* stream, fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fsetpos(FILE* stream, const fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void clearerr(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int feof(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ferror(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void perror(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- <br />
| <code>int abs(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long labs(long n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>div_t div(int num, int denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>ldiv_t ldiv(long num, long denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atof(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atoi(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long atol(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double strtod(const char* s, char** endp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long strtol(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>unsigned long strtoul(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* calloc(size_t nobj, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* malloc(size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* realloc(void* p, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void free(void* p)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void abort()</code><br />
| style="background:lime" | yes as <code>halt()</code><br />
<br />
|- <br />
| <code>void exit(int status)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atexit(void (*fcm)(void))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int system(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* getenv(const char* name)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* bsearch(const void* key, const void* base, size_t n, size_t size, int (*cmp)(const void* keyval, const void* datum))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rand(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void srand(unsigned int seed)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- <br />
| <code>char* strcpy(char* s, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strncpy(char* s, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strcat(char* s, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strncat(char* s, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int strcmp(const char* cs, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strncmp(const char* cs, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int strcoll(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strchr(const char* cs, int c)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strrchr(const char* cs, int c)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strcspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strpbrk(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strstr(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strlen(const char* cs)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strerror(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strtok(char* s, const char* t)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strxfrm(char* s, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memcpy(void* s, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* memmove(void* s, const void* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int memcmp(const void* cs, const void* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memchr(const void* cs, int c, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memset(void* s, int c, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- <br />
| <code>clock_t clock(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t time(time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double difftime(time_t time2, time_t time1)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t mktime(struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* asctime(const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* ctime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* gmtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* localtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="red"<br />
| No Support<br />
|- bgcolor="yellow"<br />
| Partial Support<br />
|- bgcolor="lime"<br />
| Full Support<br />
|}<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<br />
<pre><br />
#include <libpayload.h><br />
<br />
int main(void)<br />
{<br />
printf("Hello, world!\n");<br />
halt();<br />
return 0;<br />
}<br />
</pre><br />
<br />
Build example (basic idea):<br />
<br />
gcc -o hello_payload hello_payload.c<br />
<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=6009
Libpayload
2008-03-20T00:54:09Z
<p>Whiterocker: add download instructions</p>
<hr />
<div>'''libpayload''' is a small BSD-licensed "library" (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads.<br />
<br />
== Overview ==<br />
<br />
The benefits of linking a coreboot payload against libpayload are:<br />
<br />
* Payloads do not have to implement and maintain low-level code for I/O, common functions, etc.<br />
* Payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future.<br />
* The libpayload functions can be tested and scrutinized outside payload development.<br />
* Payloads themselves may be partly host-tested, e.g. against an emulation libpayload.<br />
* Leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''Just give us a main() and a pocket full of dreams and we'll do the rest.''<br />
<br />
== Download ==<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/payloads/libpayload<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- <br />
| <code>double exp(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log10(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double pow(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sqrt(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ceil(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double floor(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fabs(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ldexp(double x, int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double frexp(double x, int* exp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double modf(double x, double* ip)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fmod(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double asin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double acos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan2(double y, double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sinh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cosh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tanh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- <br />
| <code>int setjmp(jmp_buf env)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void longjmp(jmp_buf env, int val)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- <br />
| <code>void (*signal(int sig, void (*handler)(int)))(int)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int raise(int sig)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- <br />
| <code>void va_start(va_list ap, lastarg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>type va_arg(va_list ap, type)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void va_end(va_list ap)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- <br />
| <code>FILE* fopen(const char* filename, const char* mode)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* freopen(const char* filename, const char* mode, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fflush(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fclose(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int remove(const char* filename)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rename(const char* oldname, const char* newname)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* tmpfile()</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* tmpnam(char s[L_tmpnam])</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int setvbuf(FILE* stream, char* buf, int mode, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void setbuf(FILE* stream, char* buf)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fprintf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int printf(const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int sprintf(char* s, const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vprintf(const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vsprintf(char* s, const char* format, va_list arg)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int fscanf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int scanf(const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int sscanf(char* s, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fgets(char* s, int n, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fputc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fputs(const char* s, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getchar(void)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* gets(char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putchar(int c)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int puts(const char* s)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int ungetc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fseek(FILE* stream, long offset, int origin)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long ftell(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void rewind(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetpos(FILE* stream, fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fsetpos(FILE* stream, const fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void clearerr(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int feof(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ferror(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void perror(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- <br />
| <code>int abs(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long labs(long n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>div_t div(int num, int denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>ldiv_t ldiv(long num, long denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atof(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atoi(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long atol(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double strtod(const char* s, char** endp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long strtol(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>unsigned long strtoul(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* calloc(size_t nobj, size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* malloc(size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* realloc(void* p, size_t size)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void free(void* p)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void abort()</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void exit(int status)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atexit(void (*fcm)(void))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int system(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* getenv(const char* name)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* bsearch(const void* key, const void* base, size_t n, size_t size, int (*cmp)(const void* keyval, const void* datum))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rand(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void srand(unsigned int seed)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- <br />
| <code>char* strcpy(char* s, const char* ct)</code><br />
| style="background:red" | proto only<br />
<br />
|- <br />
| <code>char* strncpy(char* s, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strcat(char* s, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strncat(char* s, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strcmp(const char* cs, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strncmp(const char* cs, const char* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int strcoll(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strchr(const char* cs, int c)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strrchr(const char* cs, int c)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strcspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strpbrk(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strstr(const char* cs, const char* ct)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>size_t strlen(const char* cs)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>char* strerror(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strtok(char* s, const char* t)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strxfrm(char* s, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memcpy(void* s, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* memmove(void* s, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>int memcmp(const void* cs, const void* ct, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- <br />
| <code>void* memchr(const void* cs, int c, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memset(void* s, int c, size_t n)</code><br />
| style="background:lime" | yes<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- <br />
| <code>clock_t clock(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t time(time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double difftime(time_t time2, time_t time1)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t mktime(struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* asctime(const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* ctime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* gmtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* localtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="red"<br />
| No Support<br />
|- bgcolor="yellow"<br />
| Partial Support<br />
|- bgcolor="lime"<br />
| Full Support<br />
|}<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<br />
<pre><br />
#include <libpayload.h><br />
<br />
int main(void)<br />
{<br />
printf("Hello, world!\n");<br />
halt();<br />
return 0;<br />
}<br />
</pre><br />
<br />
Build example (basic idea):<br />
<br />
gcc -o hello_payload hello_payload.c<br />
<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=OpenVSA&diff=5773
OpenVSA
2008-03-07T23:11:31Z
<p>Whiterocker: </p>
<hr />
<div>'''VSA''', or '''Virtual System Architecture''' is a low-level software library included in the bootloader/BIOS for system using AMD Geode-series CPUs and companion chips.<br />
<br />
AMD released VSA sources under the name '''geode-vsa''' in 2006 (licensed under the terms of the GNU LGPL). Those sources were hosted by the OLPC project, and can be pulled with git from <code>git://dev.laptop.org/geode-vsa</code>. The '''OpenVSA''' sources include modified '''geode-vsa''' sources, as well as some new components also released under the GNU LGPL.<br />
<br />
The VSA code runs under x86 SMM (System Management Mode) which is like "real mode" with some extra opcodes, priviledges, and side-effects.<br />
<br />
As originally published, the VSA code compiled and assembled with older, commercially unavailable versions of Microsoft tools. The OpenVSA code has been modified in order to build under a GNU toolchain so that it may be maintained and enhanced by a wider group of users.<br />
<br />
== Status ==<br />
<br />
The current status of the OpenVSA is: '''''experimental'''''. Please do not use OpenVSA in your system unless you have access to a low-level re-flashing tools.<br />
<br />
== Download ==<br />
<br />
$ svn co svn://coreboot.org/openvsa/trunk/openvsa<br />
<br />
== Differences Between VSA and OpenVSA ==<br />
<br />
=== Summary ===<br />
<br />
{|<br />
|- bgcolor="#6699ff" <br />
!Category<br />
!VSA<br />
!OpenVSA<br />
<br />
|- bgcolor="#dddddd"<br />
|Assembler<br />
|MASM 6.11c or greater<br />
|GNU gas (part of binutils)<br />
<br />
|- bgcolor="#cccccc"<br />
|Make<br />
|NMAKE.EXE Version 1.40 or greater<br />
|GNU make<br />
<br />
|- bgcolor="#dddddd"<br />
|C-compiler<br />
|MSVC Version 1.52<br />
|GNU gcc<br />
<br />
|- bgcolor="#cccccc"<br />
|Final binary output<br />
|exe2bin.exe<br />
|GNU objcopy (part of binutils)<br />
<br />
|- bgcolor="#dddddd"<br />
|Assembly syntax<br />
|Microsoft/Intel<br />
|GNU gas/AT&T<br />
<br />
|- bgcolor="#cccccc"<br />
|Code Generation<br />
|16-bit, inherent to the toolchain commands used during build<br />
|16-bit assembly, generated by using <code>.code16</code> in assembly files; 32-bit from C, prefixes generated by using <code>.code16gcc</code> in C files<br />
<br />
|- bgcolor="#dddddd"<br />
|Memory Model<br />
|"tiny": merges CS and DS, inherent to the toolchain commands used during build<br />
|"tiny" model accomplished with specific section names and linker script statements<br />
<br />
|- bgcolor="#cccccc"<br />
|SMM-only opcode assembly<br />
|MASM macros<br />
|Perl script <code>smimac.pl</code> pre-processes to constant-sequences<br />
<br />
|- bgcolor="#dddddd"<br />
|Internal assembly functions: calling convention<br />
|custom/random, no apparent fixed pattern<br />
|unchanged<br />
<br />
|- bgcolor="#cccccc"<br />
|Assembly functions called from C: calling convention<br />
|Microsoft <code>pascal</code><br />
|GNU <code>__attribute__((fastcall))</code><br />
<br />
|- bgcolor="#dddddd"<br />
|C header file translation to assembly include<br />
|h2inc.exe<br />
|manual/static translation<br />
|}<br />
<br />
=== Calling Conventions And Stack ===<br />
<br />
==== VSA: MASM and Microsoft C ====<br />
<br />
The original VSA sources used 16-bit <code>MS PASCAL</code> calling convention (<code>__pascal</code>):<br />
* stack parameter order: left-to-right<br />
* called function cleans up the stack<br />
* all parameters are pushed onto the stack<br />
* return values to 16 bits returned in <code>AX</code><br />
* return values 17 to 32 bits returned in <code>DX:AX</code><br />
* scratch registers <code>AX, BX, CX, DX, ES</code><br />
<br />
<pre><br />
^ |<- 16 bits ->|<br />
| higher<br />
| address<br />
| (pop)<br />
<br />
-------------<br />
| first param |<br />
-------------<br />
...<br />
-------------<br />
| last param | 4(BP)<br />
-------------<br />
| return IP | 2(BP)<br />
-------------<br />
| old BP | <-- BP<br />
-------------<br />
(locals) -2(BP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
| (saved reg) | <-- SP<br />
-------------<br />
<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
<br />
</pre><br />
<br />
==== OpenVSA: GNU ====<br />
<br />
With GNU on the Intel 386, the fastcall attribute (<code>__attribute__(fastcall)</code>) calling convention:<br />
* stack parameter order: right-to-left<br />
* called function cleans up the stack<br />
* if the first one or two arguments are integers/pointers (<=32bit), they are passed via <code>ECX</code> and <code>EDX</code><br />
* all other parameters are pushed onto the stack<br />
* return values to 32 bits are returned in <code>EAX</code><br />
* scratch registers <code>EAX, ECX, EDX</code><br />
<br />
<pre><br />
^ |<- 32 bits ->|<br />
| higher<br />
| address<br />
| (pop) (uses (no<br />
frame) frame)<br />
<br />
-------------<br />
| last param |<br />
-------------<br />
...<br />
-------------<br />
| 3rd param | 8(EBP) 4(ESP)<br />
-------------<br />
| return EIP | <-- ESP<br />
-------------<br />
| saved EBP | <-- EBP<br />
-------------<br />
(locals) -4(EBP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
(saved reg) <-- ESP<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
</pre><br />
<br />
=== Notable C-Code Differences ===<br />
<br />
Microsoft C appears to accept a statement like:<br />
<br />
ULONG Data;<br />
...<br />
(UCHAR)Data = 0;<br />
<br />
This is not a portable construction, GCC rejects is, so has been changed to:<br />
<br />
*((UCHAR *) &Data) = 0;<br />
<br />
== Feature Wish List ==<br />
<br />
TODO.<br />
<br />
== Hacking Notes ==<br />
<br />
TODO.<br />
<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=5770
Libpayload
2008-03-07T21:31:17Z
<p>Whiterocker: /* Libc Coverage */ complete first-pass at libc coverage table</p>
<hr />
<div>'''libpayload''' is a small BSD-licensed "library" (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads.<br />
<br />
== Overview ==<br />
<br />
The benefits of linking a coreboot payload against libpayload are:<br />
<br />
* Payloads do not have to implement and maintain low-level code for I/O, common functions, etc.<br />
* Payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future.<br />
* The libpayload functions can be tested and scrutinized outside payload development.<br />
* Payloads themselves may be partly host-tested, e.g. against an emulation libpayload.<br />
* Leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''Just give us a main() and a pocket full of dreams and we'll do the rest.''<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- <br />
| <code>double exp(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log10(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double pow(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sqrt(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ceil(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double floor(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fabs(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ldexp(double x, int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double frexp(double x, int* exp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double modf(double x, double* ip)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fmod(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double asin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double acos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan2(double y, double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sinh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cosh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tanh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- <br />
| <code>int setjmp(jmp_buf env)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void longjmp(jmp_buf env, int val)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- <br />
| <code>void (*signal(int sig, void (*handler)(int)))(int)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int raise(int sig)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- <br />
| <code>void va_start(va_list ap, lastarg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>type va_arg(va_list ap, type)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void va_end(va_list ap)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- <br />
| <code>FILE* fopen(const char* filename, const char* mode)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* freopen(const char* filename, const char* mode, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fflush(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fclose(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int remove(const char* filename)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rename(const char* oldname, const char* newname)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* tmpfile()</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* tmpnam(char s[L_tmpnam])</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int setvbuf(FILE* stream, char* buf, int mode, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void setbuf(FILE* stream, char* buf)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fprintf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int printf(const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int sprintf(char* s, const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vprintf(const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vsprintf(char* s, const char* format, va_list arg)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int fscanf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int scanf(const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int sscanf(char* s, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fgets(char* s, int n, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fputc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fputs(const char* s, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getchar(void)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>char* gets(char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putchar(int c)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int puts(const char* s)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int ungetc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fseek(FILE* stream, long offset, int origin)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long ftell(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void rewind(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetpos(FILE* stream, fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fsetpos(FILE* stream, const fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void clearerr(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int feof(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ferror(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void perror(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- <br />
| <code>int abs(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long labs(long n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>div_t div(int num, int denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>ldiv_t ldiv(long num, long denom)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atof(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atoi(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long atol(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double strtod(const char* s, char** endp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long strtol(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>unsigned long strtoul(const char* s, char** endp, int base)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* calloc(size_t nobj, size_t size)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>void* malloc(size_t size)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>void* realloc(void* p, size_t size)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>void free(void* p)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>void abort()</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>void exit(int status)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int atexit(void (*fcm)(void))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int system(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* getenv(const char* name)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* bsearch(const void* key, const void* base, size_t n, size_t size, int (*cmp)(const void* keyval, const void* datum))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void qsort(void* base, size_t n, size_t size, int (*cmp)(const void*, const void*))</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rand(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void srand(unsigned int seed)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- <br />
| <code>char* strcpy(char* s, const char* ct)</code><br />
| style="background:red" | proto only<br />
<br />
|- <br />
| <code>char* strncpy(char* s, const char* ct, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>char* strcat(char* s, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strncat(char* s, const char* ct, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int strcmp(const char* cs, const char* ct)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int strncmp(const char* cs, const char* ct, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int strcoll(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strchr(const char* cs, int c)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>char* strrchr(const char* cs, int c)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strcspn(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strpbrk(const char* cs, const char* ct)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strstr(const char* cs, const char* ct)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>size_t strlen(const char* cs)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>char* strerror(int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* strtok(char* s, const char* t)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strxfrm(char* s, const char* ct, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memcpy(void* s, const void* ct, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>void* memmove(void* s, const void* ct, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int memcmp(const void* cs, const void* ct, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>void* memchr(const void* cs, int c, size_t n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void* memset(void* s, int c, size_t n)</code><br />
| style="background:green" | yes<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- <br />
| <code>clock_t clock(void)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t time(time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double difftime(time_t time2, time_t time1)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>time_t mktime(struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* asctime(const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* ctime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* gmtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct tm* localtime(const time_t* tp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t strftime(char* s, size_t smax, const char* fmt, const struct tm* tp)</code><br />
| style="background:red" | no<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="red"<br />
| No Support<br />
|- bgcolor="yellow"<br />
| Partial Support<br />
|- bgcolor="green"<br />
| Full Support<br />
|}<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<br />
<pre><br />
#include <libpayload.h><br />
<br />
int main(void)<br />
{<br />
printf("Hello, world!\n");<br />
halt();<br />
return 0;<br />
}<br />
</pre><br />
<br />
Build example (basic idea):<br />
<br />
gcc -o hello_payload hello_payload.c<br />
<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=5769
Libpayload
2008-03-07T21:08:09Z
<p>Whiterocker: fill in more of libc coverage table</p>
<hr />
<div>'''libpayload''' is a small BSD-licensed "library" (a lightweight implementation of common and useful functions) intended to be used as a basis for coreboot payloads.<br />
<br />
== Overview ==<br />
<br />
The benefits of linking a coreboot payload against libpayload are:<br />
<br />
* Payloads do not have to implement and maintain low-level code for I/O, common functions, etc.<br />
* Payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future.<br />
* The libpayload functions can be tested and scrutinized outside payload development.<br />
* Payloads themselves may be partly host-tested, e.g. against an emulation libpayload.<br />
* Leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''Just give us a main() and a pocket full of dreams and we'll do the rest.''<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- <br />
| <code>double exp(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double log10(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double pow(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sqrt(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ceil(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double floor(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fabs(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double ldexp(double x, int n)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double frexp(double x, int* exp)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double modf(double x, double* ip)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double fmod(double x, double y)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double asin(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double acos(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double atan2(double y, double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double sinh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double cosh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>double tanh(double x)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- <br />
| <code>int setjmp(jmp_buf env)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void longjmp(jmp_buf env, int val)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- <br />
| <code>void (*signal(int sig, void (*handler)(int)))(int)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int raise(int sig)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- <br />
| <code>void va_start(va_list ap, lastarg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>type va_arg(va_list ap, type)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void va_end(va_list ap)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="red"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- <br />
| <code>FILE* fopen(const char* filename, const char* mode)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* freopen(const char* filename, const char* mode, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fflush(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fclose(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int remove(const char* filename)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int rename(const char* oldname, const char* newname)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>FILE* tmpfile()</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* tmpnam(char s[L_tmpnam])</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int setvbuf(FILE* stream, char* buf, int mode, size_t size)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void setbuf(FILE* stream, char* buf)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fprintf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int printf(const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int sprintf(char* s, const char* format, ...)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int vfprintf(FILE* stream, const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vprintf(const char* format, va_list arg)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int vsprintf(char* s, const char* format, va_list arg)</code><br />
| style="background:yellow" | partial<br />
<br />
|- <br />
| <code>int fscanf(FILE* stream, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int scanf(const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int sscanf(char* s, const char* format, ...)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fgets(char* s, int n, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fputc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>char* fputs(const char* s, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getc(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int getchar(void)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>char* gets(char* s)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int putchar(int c)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int puts(const char* s)</code><br />
| style="background:green" | yes<br />
<br />
|- <br />
| <code>int ungetc(int c, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fread(void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>size_t fwrite(const void* ptr, size_t size, size_t nobj, FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fseek(FILE* stream, long offset, int origin)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>long ftell(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void rewind(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fgetpos(FILE* stream, fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int fsetpos(FILE* stream, const fpos_t* ptr)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void clearerr(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int feof(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ferror(FILE* stream)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>void perror(const char* s)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="yellow"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="red"<br />
| No Support<br />
|- bgcolor="yellow"<br />
| Partial Support<br />
|- bgcolor="green"<br />
| Full Support<br />
|}<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<br />
<pre><br />
#include <libpayload.h><br />
<br />
int main(void)<br />
{<br />
printf("Hello, world!\n");<br />
halt();<br />
return 0;<br />
}<br />
</pre><br />
<br />
Build example (basic idea):<br />
<br />
gcc -o hello_payload hello_payload.c<br />
<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=OpenVSA&diff=5764
OpenVSA
2008-03-07T17:46:46Z
<p>Whiterocker: /* Summary */ beautify table</p>
<hr />
<div>== About ==<br />
<br />
The current status of the OpenVSA is: '''''experimental'''''. Please do not use OpenVSA in your system unless you have access to a low-level re-flashing tools.<br />
<br />
To obtain the OpenVSA sources, refer to [[download coreboot]].<br />
<br />
== Context ==<br />
<br />
VSA, or Virtual System Architecture is a low-level software library included in the bootloader/BIOS for system using AMD Geode-series CPUs and companion chips.<br />
<br />
AMD released VSA sources under the GNU LGPL in 2006. Those sources were hosted by the OLPC project, and can be pulled with git from <code>git://dev.laptop.org/geode-vsa</code>. The OpenVSA sources include modified Geode VSA sources, as well as some new components also released under the GNU LGPL.<br />
<br />
The VSA code runs under x86 SMM (System Management Mode) which is like "real mode" with some extra opcodes, priviledges, and side-effects. <br />
<br />
As originally published, the VSA code compiled and assembled with older, commercially unavailable versions of Microsoft tools. The OpenVSA code has been modified in order to build under a GNU toolchain so that it may be maintained and enhanced by a wider group of users.<br />
<br />
== Differences Between VSA and OpenVSA ==<br />
<br />
=== Summary ===<br />
<br />
{|<br />
|- bgcolor="#6699ff" <br />
!Category<br />
!VSA<br />
!OpenVSA<br />
<br />
|-<br />
|Assembler<br />
|MASM 6.11c or greater<br />
|GNU gas (part of binutils)<br />
<br />
|- bgcolor="#cccccc"<br />
|Make<br />
|NMAKE.EXE Version 1.40 or greater<br />
|GNU make<br />
<br />
|-<br />
|C-compiler<br />
|MSVC Version 1.52<br />
|GNU gcc<br />
<br />
|- bgcolor="#cccccc"<br />
|Final binary output<br />
|exe2bin.exe<br />
|GNU objcopy (part of binutils)<br />
<br />
|-<br />
|Assembly syntax<br />
|Microsoft/Intel<br />
|GNU gas/AT&T<br />
<br />
|- bgcolor="#cccccc"<br />
|Code Generation<br />
|16-bit, inherent to the toolchain commands used during build<br />
|16-bit assembly, generated by using <code>.code16</code> in assembly files; 32-bit from C, prefixes generated by using <code>.code16gcc</code> in C files<br />
<br />
|- <br />
|Memory Model<br />
|"tiny": merges CS and DS, inherent to the toolchain commands used during build<br />
|"tiny" model accomplished with specific section names and linker script statements<br />
<br />
|- bgcolor="#cccccc"<br />
|SMM-only opcode assembly<br />
|MASM macros<br />
|Perl script <code>smimac.pl</code> pre-processes to constant-sequences<br />
<br />
|-<br />
|Internal assembly functions: calling convention<br />
|custom/random, no apparent fixed pattern<br />
|unchanged<br />
<br />
|- bgcolor="#cccccc"<br />
|Assembly functions called from C: calling convention<br />
|Microsoft <code>pascal</code><br />
|GNU <code>__attribute__((fastcall))</code><br />
<br />
|-<br />
|C header file translation to assembly include<br />
|h2inc.exe<br />
|manual/static translation<br />
|}<br />
<br />
=== Calling Conventions And Stack ===<br />
<br />
==== VSA: MASM and Microsoft C ====<br />
<br />
The original VSA sources used 16-bit <code>MS PASCAL</code> calling convention (<code>__pascal</code>):<br />
* stack parameter order: left-to-right<br />
* called function cleans up the stack<br />
* all parameters are pushed onto the stack<br />
* return values to 16 bits returned in <code>AX</code><br />
* return values 17 to 32 bits returned in <code>DX:AX</code><br />
* scratch registers <code>AX, BX, CX, DX, ES</code><br />
<br />
<pre><br />
^ |<- 16 bits ->|<br />
| higher<br />
| address<br />
| (pop)<br />
<br />
-------------<br />
| first param |<br />
-------------<br />
...<br />
-------------<br />
| last param | 4(BP)<br />
-------------<br />
| return IP | 2(BP)<br />
-------------<br />
| old BP | <-- BP<br />
-------------<br />
(locals) -2(BP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
| (saved reg) | <-- SP<br />
-------------<br />
<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
<br />
</pre><br />
<br />
==== OpenVSA: GNU ====<br />
<br />
With GNU on the Intel 386, the fastcall attribute (<code>__attribute__(fastcall)</code>) calling convention:<br />
* stack parameter order: right-to-left<br />
* called function cleans up the stack<br />
* if the first one or two arguments are integers/pointers (<=32bit), they are passed via <code>ECX</code> and <code>EDX</code><br />
* all other parameters are pushed onto the stack<br />
* return values to 32 bits are returned in <code>EAX</code><br />
* scratch registers <code>EAX, ECX, EDX</code><br />
<br />
<pre><br />
^ |<- 32 bits ->|<br />
| higher<br />
| address<br />
| (pop) (uses (no<br />
frame) frame)<br />
<br />
-------------<br />
| last param |<br />
-------------<br />
...<br />
-------------<br />
| 3rd param | 8(EBP) 4(ESP)<br />
-------------<br />
| return EIP | <-- ESP<br />
-------------<br />
| saved EBP | <-- EBP<br />
-------------<br />
(locals) -4(EBP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
(saved reg) <-- ESP<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
</pre><br />
<br />
=== Notable C-Code Differences ===<br />
<br />
Microsoft C appears to accept a statement like:<br />
<br />
ULONG Data;<br />
...<br />
(UCHAR)Data = 0;<br />
<br />
This is not a portable construction, GCC rejects is, so has been changed to:<br />
<br />
*((UCHAR *) &Data) = 0;<br />
<br />
== Feature Wish List ==<br />
<br />
TODO.<br />
<br />
== Hacking Notes ==<br />
<br />
TODO.<br />
<br />
== Licenses ==<br />
<br />
=== OpenVSA Software ===<br />
<br />
{{LGPL}}<br />
<br />
=== This Article ===<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=5763
Libpayload
2008-03-07T17:40:20Z
<p>Whiterocker: add place-holder for libpayload software licence info, add PD dedication for article</p>
<hr />
<div>== Overview ==<br />
<br />
Currently a concept rather than shipping code, libpayload is a coreboot subproject that intends to provide a lightweight implementation of common and useful functions for coreboot payloads. The benefits of linking a coreboot payload against libpayload are:<br />
* payloads do not have to implement and maintain low-level code for I/O, common functions, etc,<br />
* payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future,<br />
* libpayload functions tested and scrutinized outside payload development,<br />
* payloads themselves may be partly host-tested, e.g. against an emulation libpayload,<br />
* leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''just give us a main() and a pocket full of dreams and we'll do the rest''<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="#ff0000"<br />
| No Support<br />
|- bgcolor="#ffff00"<br />
| Partial Support<br />
|- bgcolor="#00ff00"<br />
| Full Support<br />
|}<br />
<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<pre><br />
#include <stdio.h><br />
<br />
int main( void )<br />
{<br />
printf( "Hello, world!\n" );<br />
return 0;<br />
}<br />
</pre><br />
<br />
build:<br />
<pre><br />
libpayload-gcc -o hello_payload hello_payload.c<br />
</pre><br />
<br />
== Licenses ==<br />
<br />
=== Libpaylod Software ===<br />
<br />
TBD<br />
<br />
=== This Article ===<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=5762
Libpayload
2008-03-07T07:55:48Z
<p>Whiterocker: Start libc coverage table</p>
<hr />
<div>== Overview ==<br />
<br />
Currently a concept rather than shipping code, libpayload is a coreboot subproject that intends to provide a lightweight implementation of common and useful functions for coreboot payloads. The benefits of linking a coreboot payload against libpayload are:<br />
* payloads do not have to implement and maintain low-level code for I/O, common functions, etc,<br />
* payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future,<br />
* libpayload functions tested and scrutinized outside payload development,<br />
* payloads themselves may be partly host-tested, e.g. against an emulation libpayload,<br />
* leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''just give us a main() and a pocket full of dreams and we'll do the rest''<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Libc Coverage ==<br />
<br />
{| border="0" <br />
|- bgcolor="#6699ff" <br />
! align="left" | Function/Macro/Variable<br />
! align="left" | Status<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | assert.h<br />
<br />
|- <br />
| <code>assert( )</code> (macro)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | ctype.h<br />
<br />
|- <br />
| <code>int isalnum(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isalpha(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int iscntrl(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isgraph(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int islower(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isprint(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int ispunct(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isspace(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| i<code>nt isupper(int character)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>int isxdigit(int character)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | errno.h<br />
<br />
|- <br />
| <code>errno</code> (global)<br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | float.h<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | limits.h<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | locale.h<br />
<br />
|- <br />
| <code>char *setlocale(int category, const char *locale)</code><br />
| style="background:red" | no<br />
<br />
|- <br />
| <code>struct lconv *localeconv(void)</code><br />
| style="background:red" | no<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | math.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | setjmp.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | signal.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | stdarg.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ff0000"<br />
| colspan=2 align="center" | stddef.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | stdio.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | stdlib.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | string.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|- bgcolor="#ffff00"<br />
| colspan=2 align="center" | time.h<br />
<br />
|- colspan=2 <br />
| TODO<br />
<br />
|}<br />
<br />
<br />
{| border="1" <br />
|- bgcolor="#ff0000"<br />
| No Support<br />
|- bgcolor="#ffff00"<br />
| Partial Support<br />
|- bgcolor="#00ff00"<br />
| Full Support<br />
|}<br />
<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<pre><br />
#include <stdio.h><br />
<br />
int main( void )<br />
{<br />
printf( "Hello, world!\n" );<br />
return 0;<br />
}<br />
</pre><br />
<br />
build:<br />
<pre><br />
libpayload-gcc -o hello_payload hello_payload.c<br />
</pre></div>
Whiterocker
https://www.coreboot.org/index.php?title=OpenVSA&diff=5746
OpenVSA
2008-03-04T00:24:28Z
<p>Whiterocker: </p>
<hr />
<div>== About ==<br />
<br />
The current status of the OpenVSA is: '''''experimental'''''. Please do not use OpenVSA in your system unless you have access to a low-level re-flashing tools.<br />
<br />
To obtain the OpenVSA sources, refer to [[download coreboot]].<br />
<br />
== Context ==<br />
<br />
VSA, or Virtual System Architecture is a low-level software library included in the bootloader/BIOS for system using AMD Geode-series CPUs and companion chips.<br />
<br />
AMD released VSA sources under the GNU LGPL in 2006. Those sources were hosted by the OLPC project, and can be pulled with git from <code>git://dev.laptop.org/geode-vsa</code>. The OpenVSA sources include modified Geode VSA sources, as well as some new components also released under the GNU LGPL.<br />
<br />
The VSA code runs under x86 SMM (System Management Mode) which is like "real mode" with some extra opcodes, priviledges, and side-effects. <br />
<br />
As originally published, the VSA code compiled and assembled with older, commercially unavailable versions of Microsoft tools. The OpenVSA code has been modified in order to build under a GNU toolchain so that it may be maintained and enhanced by a wider group of users.<br />
<br />
== Differences Between VSA and OpenVSA ==<br />
<br />
=== Summary ===<br />
<br />
{|<br />
|-<br />
!Category<br />
!VSA<br />
!OpenVSA<br />
|-<br />
|Assembler<br />
|MASM 6.11c or greater<br />
|GNU gas (part of binutils)<br />
|-<br />
|Make<br />
|NMAKE.EXE Version 1.40 or greater<br />
|GNU make<br />
|-<br />
|C-compiler<br />
|MSVC Version 1.52<br />
|GNU gcc<br />
|-<br />
|Final binary output<br />
|exe2bin.exe<br />
|GNU objcopy (part of binutils)<br />
|-<br />
|Assembly syntax<br />
|Microsoft/Intel<br />
|GNU gas/AT&T<br />
|-<br />
|Code Generation<br />
|16-bit, inherent to the toolchain commands used during build<br />
|16-bit assembly, generated by using <code>.code16</code> in assembly files; 32-bit from C, prefixes generated by using <code>.code16gcc</code> in C files<br />
|-<br />
|Memory Model<br />
|"tiny": merges CS and DS, inherent to the toolchain commands used during build<br />
|"tiny" model accomplished with specific section names and linker script statements<br />
|-<br />
|SMM-only opcode assembly<br />
|MASM macros<br />
|Perl script <code>smimac.pl</code> pre-processes to constant-sequences<br />
|-<br />
|Internal assembly functions: calling convention<br />
|custom/random, no apparent fixed pattern<br />
|unchanged<br />
|-<br />
|Assembly functions called from C: calling convention<br />
|Microsoft <code>pascal</code><br />
|GNU <code>__attribute__((fastcall))</code><br />
|-<br />
|C header file translation to assembly include<br />
|h2inc.exe<br />
|manual/static translation<br />
|}<br />
<br />
=== Calling Conventions And Stack ===<br />
<br />
==== VSA: MASM and Microsoft C ====<br />
<br />
The original VSA sources used 16-bit <code>MS PASCAL</code> calling convention (<code>__pascal</code>):<br />
* stack parameter order: left-to-right<br />
* called function cleans up the stack<br />
* all parameters are pushed onto the stack<br />
* return values to 16 bits returned in <code>AX</code><br />
* return values 17 to 32 bits returned in <code>DX:AX</code><br />
* scratch registers <code>AX, BX, CX, DX, ES</code><br />
<br />
<pre><br />
^ |<- 16 bits ->|<br />
| higher<br />
| address<br />
| (pop)<br />
<br />
-------------<br />
| first param |<br />
-------------<br />
...<br />
-------------<br />
| last param | 4(BP)<br />
-------------<br />
| return IP | 2(BP)<br />
-------------<br />
| old BP | <-- BP<br />
-------------<br />
(locals) -2(BP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
| (saved reg) | <-- SP<br />
-------------<br />
<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
<br />
</pre><br />
<br />
==== OpenVSA: GNU ====<br />
<br />
With GNU on the Intel 386, the fastcall attribute (<code>__attribute__(fastcall)</code>) calling convention:<br />
* stack parameter order: right-to-left<br />
* called function cleans up the stack<br />
* if the first one or two arguments are integers/pointers (<=32bit), they are passed via <code>ECX</code> and <code>EDX</code><br />
* all other parameters are pushed onto the stack<br />
* return values to 32 bits are returned in <code>EAX</code><br />
* scratch registers <code>EAX, ECX, EDX</code><br />
<br />
<pre><br />
^ |<- 32 bits ->|<br />
| higher<br />
| address<br />
| (pop) (uses (no<br />
frame) frame)<br />
<br />
-------------<br />
| last param |<br />
-------------<br />
...<br />
-------------<br />
| 3rd param | 8(EBP) 4(ESP)<br />
-------------<br />
| return EIP | <-- ESP<br />
-------------<br />
| saved EBP | <-- EBP<br />
-------------<br />
(locals) -4(EBP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
(saved reg) <-- ESP<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
</pre><br />
<br />
=== Notable C-Code Differences ===<br />
<br />
Microsoft C appears to accept a statement like:<br />
<br />
ULONG Data;<br />
...<br />
(UCHAR)Data = 0;<br />
<br />
This is not a portable construction, GCC rejects is, so has been changed to:<br />
<br />
*((UCHAR *) &Data) = 0;<br />
<br />
== Feature Wish List ==<br />
<br />
TODO.<br />
<br />
== Hacking Notes ==<br />
<br />
TODO.<br />
<br />
== Licenses ==<br />
<br />
=== OpenVSA Software ===<br />
<br />
{{LGPL}}<br />
<br />
=== This Article ===<br />
<br />
{{PD-self}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=Template:LGPL&diff=5745
Template:LGPL
2008-03-04T00:19:31Z
<p>Whiterocker: New page: {| {{GNU-Layout}} | GNU head | ''This work is free software; you can redistribute it and/or modify it under the terms of the ...</p>
<hr />
<div>{| {{GNU-Layout}}<br />
| [[Image:Heckert gnu.big.png|64px|GNU head]]<br />
| ''This work is [[wikipedia:Free software|free software]]; you can redistribute it and/or modify it under the terms of the '''[[wikipedia:LGPL|GNU Lesser General Public License]]''' as published by the [[wikipedia:Free Software Foundation|Free Software Foundation]]; either version 2.1 of the License, or any later version. This work is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the [http://www.gnu.org/copyleft/lgpl.html GNU Lesser General Public License] for more details.''<br />
|}<includeonly>[[Category:LGPL|{{PAGENAME}}]]</includeonly><br />
<noinclude>[[Category:License tags|{{PAGENAME}}]]</noinclude></div>
Whiterocker
https://www.coreboot.org/index.php?title=User:Whiterocker&diff=5734
User:Whiterocker
2008-03-03T18:45:08Z
<p>Whiterocker: New page: === Chris Kilgour === EE and Software Developer in Vancouver, Canada.</p>
<hr />
<div>=== Chris Kilgour ===<br />
<br />
EE and Software Developer in Vancouver, Canada.</div>
Whiterocker
https://www.coreboot.org/index.php?title=AMD_Geode_Porting_Guide&diff=5733
AMD Geode Porting Guide
2008-03-02T06:20:50Z
<p>Whiterocker: /* Manual build */</p>
<hr />
<div>Welcome! This is a collection on information to help you on your way to porting coreboot to an AMD Geode platform. Most of the information is about the Geode LX and CS5536 but may also be relevant to older versions of Geode. (Note that this does not cover the Geode NX).<br />
<br />
If you find something incorrect or other deficiencies in this information please fix them!<br />
<br />
== Documentation ==<br />
* [[Development Guidelines]]<br />
* [[Developer Manual]]<br />
* Many Geode LX systems are based on the [http://www.amd.com/us-en/ConnectivitySolutions/ProductInformation/0,,50_2330_9863_13022%5E13060,00.html DB800 reference design], so that is a good place to start.<br />
* [http://www.amd.com/files/connectivitysolutions/geode/geode_lx/33234F_LX_databook.pdf Geode LX CPU databook]<br />
* [http://www.amd.com/files/connectivitysolutions/geode/geode_lx/33238G_cs5536_db.pdf Geode CS5536 Southbridge databook]<br />
* [http://www.amd.com/us-en/ConnectivitySolutions/ProductInformation/0,,50_2330_9863_13022%5E11363,00.html Geode Linux webpage] - The VSA and GeodeROM Porting guides are interesting.<br />
* [http://linuxbios.org/images/8/88/Crouse-Reprint.pdf Breaking the Chains -- Using LinuxBIOS to Liberate Embedded x86 Processors] - was heavily influenced by the experience of the initial Geode LX port.<br />
<br />
== Build coreboot for Geode ==<br />
Use [[Buildrom|buildrom]]. It can handle the payload and VSA for you.<br />
<br />
$ svn co svn://coreboot.org/buildrom<br />
<br />
Checkout coreboot:<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/coreboot-v2<br />
<br />
Build a db800 for starters and set buildrom to build your local svn directory in menuconfig.<br />
<br />
$ make menuconfig<br />
$ make<br />
<br />
From this point you can customize the db800 and then make the target, mainboard, and buildrom customization patches later. <br />
<br />
==== Manual build ====<br />
If you really want to get your hands dirty. Roll up your sleeves...<br />
<br />
Go get VSA '''amd_vsa_lx_1.01.bin.gz''' [http://www.amd.com/files/connectivitysolutions/geode/geode_lx/amd_vsa_lx_1.01.bin.gz here] and extract it. It will need to be compressed and padded to make the correct ROM size. For a typical Geode platform the binary should be 36KB. Calculate the padding as follows: 36864 - size of lx_vsa.nrv2b = padding. The current image requires padding of 3264.<br />
<br />
Then, find a [[Payloads|payload]] and build it.<br />
<br />
$ cd coreboot-v2/targets<br />
$ ./buildtarget amd/db800<br />
$ cd amd/db800/db800<br />
$ cp /from/someplace/payloadx ./payload.elf<br />
$ make<br />
$ cp /from/someplace/amd_vsa_lx_1.01.bin .<br />
$ fallback/nrv2b e amd_vsa_lx_1.01.bin lx_vsa.nrv2b<br />
$ dd if=/dev/zero of=padding bs=1 count=3264 <br />
$ cat lx_vsa.nrv2b padding > lx_vsa.36k.bin<br />
$ cat lx_vsa.36k.bin db800.rom > amd-db800.rom<br />
<br />
You should now have a 512KB ROM image. You should be able to use [[flashrom]] or a ROM programmer to get the image onto your system. (Be prepared to brick it...)<br />
<br />
If you want the VSA source it is located [http://dev.laptop.org/git?p=geode-vsa;a=tree;h=10f157122acaae414431c88a2403ed692453c960;hb=10f157122acaae414431c88a2403ed692453c960 here].<br />
<br />
Although not currently functional: [[OpenVSA]] aims to provide VSA buildable with open tools.<br />
<br />
== Porting ==<br />
Now that you are building Geode coreboot images you are ready to make customizations to your platform. Most customizations can be handled in the mainboard directory.<br />
<br />
$ cd coreboot-v2/src/mainboard/amd/db800<br />
<br />
Make yourself familiar with this directory. There are not too many files.<br />
<br />
=== IRQ routing ===<br />
Almost every platform will require customization of the PIR table in '''irq_table.c'''.<br />
<br />
Make yourself familiar with the [http://www.microsoft.com/whdc/archive/pciirq.mspx PIR table specification].<br />
<br />
If you have the motherboard schematics adjusting the table is fairly simple. <br />
<br />
First check how many on board devices (including PCI slots) and update '''IRQ_SLOT_COUNT''' in Options.lb. Remember any time you change Options.lb or Config.lb you need to redo ./buildtarget.<br />
<br />
Next check the INT lines (GPIOs) into the CS5536.<br />
<br />
{| border="1"<br />
|+ CS5536<br />
! line !! CS5536 signal/pin <br />
|-<br />
! PCI$INTA_X<br />
| GPIO0 / INTA_L<br />
|-<br />
! PCI$INTB_X<br />
| GPIO7 / INTB_X <br />
|-<br />
! PCI$INTC_X <br />
| GPIO12 / INTR <br />
|-<br />
! PCI$INTD_X<br />
| GPIO13 / 8MI_L<br />
|}<br />
<br />
Based on this information you can setup the<br />
register "enable_gpio_int_route" = "0x0D0C0700"<br />
line in Config.lb.<br />
<br />
For each motherboard device check the INT pins. For example a PCI slot would look something like this:<br />
{| border="1"<br />
|+ PCI slot<br />
! pin !! device !! line <br />
|-<br />
! pin A6<br />
| INTA_X || PCI$INTB_X <br />
|-<br />
! pin A7<br />
| INTC_X || PCI$INTD_X <br />
|-<br />
! pin B7<br />
| INTB_X || PCI$INTC_X <br />
|-<br />
! pin B8<br />
| INTD_X || PCI$INTA_X <br />
|}<br />
<br />
Take a closer look at irq_tables.c.<br />
L_PIRQA is the chipset incoming IRQ line and M_PIRQA is the bitmap of IRQ numbers it can generate. These should not change. You can adjust the IRQs generated by changing PIRQA etc. Yes, it is fine if they all share 10 or 11 but it might be easier to debug if they all have a different IRQ.<br />
<br />
The table entries are the slot/device IRQ lines. I will break one entry down.<br />
<br />
/* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */<br />
{0x00, (0x01 << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, /* cpu */<br />
{0x00, (0x0F << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x0, 0x0}, /* chipset */<br />
{0x00, (0x0D << 3) | 0x0, {{L_PIRQB, M_PIRQB}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, /* ethernet */<br />
{0x00, (0x0E << 3) | 0x0, {{L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}}, 0x1, 0x0}, /* slot1 */<br />
<br />
I will break the last entry down.<br />
<br />
* '''0x00, (0x0E << 3) | 0x0''' &mdash; slot(device) address (IDSEL)<br />
* '''{L_PIRQC, M_PIRQC}''' &mdash; slot INT line A to chipset INT line C (L_PIRQC), it can generate IRQs (M_PIRQC)<br />
* '''{L_PIRQD, M_PIRQD}''' &mdash; slot INT line B to chipset INT line C (L_PIRQD), it can generate IRQs (M_PIRQD)<br />
* '''{L_PIRQA, M_PIRQA}''' &mdash; slot INT line C to chipset INT line A...<br />
* '''{L_PIRQB, M_PIRQB}''' &mdash; slot INT lineD to chipset INT line B...<br />
* '''0x1''' &mdash; arbitrary slot number<br />
* '''0x0''' &mdash; rfu, always 0<br />
<br />
If you don't have the schematics you will have to figure out the routing on your own. With '''lspci''' output and some trial and error you can figure it out. [[IRC]] or the [[Mailinglist|mailing list]] is a good place to get help if you are stuck.<br />
<br />
There's also a wiki entry on [[Creating Valid IRQ Tables|figuring out the routing table]].<br />
<br />
==== LPC Serial IRQs ====<br />
IRQs from [http://en.wikipedia.org/wiki/Low_Pin_Count LPC] need to be passed to the SC5536 [http://en.wikipedia.org/wiki/Intel_8259 PIC]. It is important to only enable the expected sources and to configure the polarity. Enables are a bit mask. It depends on the [http://en.wikipedia.org/wiki/Super_I/O SIO] but typically, the polarity is the inverse of the enables as you can see in the example below. <br />
<br />
Config.lb - <br />
# Invert mask = IRQ 12 and 1 are active high. Keyboard and Mouse, UARTs, etc IRQs. OK<br />
register "lpc_serirq_enable" = "0x000010da"<br />
register "lpc_serirq_polarity" = "0x0000EF25"<br />
register "lpc_serirq_mode" = "1"<br />
<br />
=== Memory ===<br />
On some systems the memory is soldered down and there is no SPD (Serial Presence Detect) which is required to properly setup DDR memory. In this case you will need to provide an SPD values in coreboot. This should be done by customizing '''spd_read_byte()''' in '''cache_as_ram_auto.c''' to do a table lookup. A good example can be found in [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/pcengines/alix1c/cache_as_ram_auto.c src/mainboard/pcengines/alix1c/cache_as_ram_auto.c].<br />
<br />
=== Power button ===<br />
By default the CS5536 code sets the power button up for the '''4 second soft off setting'''. If your system is booting and shuts off after four seconds check for a power button enable jumper. If your system doesn't have a power button and comes on when plugged in you will need to adjust the power button MSR. This is best done in cache_as_ram_main() in cache_as_ram_auto.c after the call to cs5536_early_setup(). The MSR name is PM Fail-Safe Delay and Enable (PM_FSD). (Yes, this could be made a Config.lb option)<br />
<br />
Add the following line:<br />
outl(0x00, PMS_IO_BASE + 0x40); // disable the power button<br />
<br />
=== Graphics ===<br />
For Geode graphics, use the upstreamed [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=drivers/video/geode;h=e680c13755a7bfd9fb40d7f41cb7b30b033fdd67;hb=HEAD Geode framebuffer driver] and the [http://gitweb.freedesktop.org/?p=xorg/driver/xf86-video-amd.git;a=summary Geode X driver]. There is no VGA ROM for Geode at this time.<br />
<br />
=== Debug ===<br />
<br />
==== Serial Output ====<br />
The Geode CS5536 has two serial ports but on many mainboards the SIO serial ports are used instead. Setup Config.lb and the serial initialization depending on the configuration of the mainboard.<br />
<br />
Config.lb -<br />
register "com1_enable" = "1"<br />
register "com1_address" = "0x3F8"<br />
register "com1_irq" = "4"<br />
register "com2_enable" = "1"<br />
register "com2_address" = "0x2F8"<br />
register "com2_irq" = "3"<br />
<br />
In this [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/amd/norwich/Config.lb case] ''' "1" ''' enables the CS5536 serial port and the address and irq are setup to these values. The other important part of serial output is to setup the ports very early. This is done in [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/amd/norwich/cache_as_ram_auto.c cache_as_ram_main()].<br />
<br />
For an example of using the SIO serial ports instead of the CS5536, see the [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/amd/db800/Config.lb DB800 mainboard].<br />
<br />
==== Dump System Configuration ====<br />
'''print_conf()''' in [http://tracker.coreboot.org/trac/coreboot/browser/trunk/coreboot-v2/src/mainboard/amd/norwich/mainboard.c src/mainboard/amd/norwich/mainboard.c] can help provide a good picture of the system configuration and should be one of the first tools you use to debug memory or other configuration issues.<br />
<br />
=== Other ===<br />
What are we missing?<br />
<br />
{{GPL}}</div>
Whiterocker
https://www.coreboot.org/index.php?title=OpenVSA&diff=5732
OpenVSA
2008-03-02T06:16:17Z
<p>Whiterocker: Initial creation</p>
<hr />
<div>The current status of the OpenVSA is: '''''experimental'''''. Please do not use OpenVSA in your system unless you have access to a low-level re-flashing tools.<br />
<br />
To obtain the OpenVSA sources, refer to [[download coreboot]].<br />
<br />
== Context ==<br />
<br />
VSA, or Virtual System Architecture is a low-level software library included in the bootloader/BIOS for system using AMD Geode-series CPUs and companion chips.<br />
<br />
AMD released VSA sources under the GNU LGPL in 2006. Those sources were hosted by the OLPC project, and can be pulled with git from <code>git://dev.laptop.org/geode-vsa</code>. The OpenVSA sources include modified Geode VSA sources, as well as some new components also released under the GNU LGPL.<br />
<br />
The VSA code runs under x86 SMM (System Management Mode) which is like "real mode" with some extra opcodes, priviledges, and side-effects. <br />
<br />
As originally published, the VSA code compiled and assembled with older, commercially unavailable versions of Microsoft tools. The OpenVSA code has been modified in order to build under a GNU toolchain so that it may be maintained and enhanced by a wider group of users.<br />
<br />
== Differences Between VSA and OpenVSA ==<br />
<br />
=== Summary ===<br />
<br />
{|<br />
|-<br />
!Category<br />
!VSA<br />
!OpenVSA<br />
|-<br />
|Assembler<br />
|MASM 6.11c or greater<br />
|GNU gas (part of binutils)<br />
|-<br />
|Make<br />
|NMAKE.EXE Version 1.40 or greater<br />
|GNU make<br />
|-<br />
|C-compiler<br />
|MSVC Version 1.52<br />
|GNU gcc<br />
|-<br />
|Final binary output<br />
|exe2bin.exe<br />
|GNU objcopy (part of binutils)<br />
|-<br />
|Assembly syntax<br />
|Microsoft/Intel<br />
|GNU gas/AT&T<br />
|-<br />
|Code Generation<br />
|16-bit, inherent to the toolchain commands used during build<br />
|16-bit assembly, generated by using <code>.code16</code> in assembly files; 32-bit from C, prefixes generated by using <code>.code16gcc</code> in C files<br />
|-<br />
|Memory Model<br />
|"tiny": merges CS and DS, inherent to the toolchain commands used during build<br />
|"tiny" model accomplished with specific section names and linker script statements<br />
|-<br />
|SMM-only opcode assembly<br />
|MASM macros<br />
|Perl script <code>smimac.pl</code> pre-processes to constant-sequences<br />
|-<br />
|Internal assembly functions: calling convention<br />
|custom/random, no apparent fixed pattern<br />
|unchanged<br />
|-<br />
|Assembly functions called from C: calling convention<br />
|Microsoft <code>pascal</code><br />
|GNU <code>__attribute__((fastcall))</code><br />
|-<br />
|C header file translation to assembly include<br />
|h2inc.exe<br />
|manual/static translation<br />
|}<br />
<br />
=== Calling Conventions And Stack ===<br />
<br />
==== VSA: MASM and Microsoft C ====<br />
<br />
The original VSA sources used 16-bit <code>MS PASCAL</code> calling convention (<code>__pascal</code>):<br />
* stack parameter order: left-to-right<br />
* called function cleans up the stack<br />
* all parameters are pushed onto the stack<br />
* return values to 16 bits returned in <code>AX</code><br />
* return values 17 to 32 bits returned in <code>DX:AX</code><br />
* scratch registers <code>AX, BX, CX, DX, ES</code><br />
<br />
<pre><br />
^ |<- 16 bits ->|<br />
| higher<br />
| address<br />
| (pop)<br />
<br />
-------------<br />
| first param |<br />
-------------<br />
...<br />
-------------<br />
| last param | 4(BP)<br />
-------------<br />
| return IP | 2(BP)<br />
-------------<br />
| old BP | <-- BP<br />
-------------<br />
(locals) -2(BP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
| (saved reg) | <-- SP<br />
-------------<br />
<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
<br />
</pre><br />
<br />
==== OpenVSA: GNU ====<br />
<br />
With GNU on the Intel 386, the fastcall attribute (<code>__attribute__(fastcall)</code>) calling convention:<br />
* stack parameter order: right-to-left<br />
* called function cleans up the stack<br />
* if the first one or two arguments are integers/pointers (<=32bit), they are passed via <code>ECX</code> and <code>EDX</code><br />
* all other parameters are pushed onto the stack<br />
* return values to 32 bits are returned in <code>EAX</code><br />
* scratch registers <code>EAX, ECX, EDX</code><br />
<br />
<pre><br />
^ |<- 32 bits ->|<br />
| higher<br />
| address<br />
| (pop) (uses (no<br />
frame) frame)<br />
<br />
-------------<br />
| last param |<br />
-------------<br />
...<br />
-------------<br />
| 3rd param | 8(EBP) 4(ESP)<br />
-------------<br />
| return EIP | <-- ESP<br />
-------------<br />
| saved EBP | <-- EBP<br />
-------------<br />
(locals) -4(EBP)<br />
-------------<br />
(saved regs)<br />
-------------<br />
(saved reg) <-- ESP<br />
| lower<br />
| address<br />
| (push)<br />
v<br />
</pre><br />
<br />
=== Notable C-Code Differences ===<br />
<br />
Microsoft C appears to accept a statement like:<br />
<br />
ULONG Data;<br />
...<br />
(UCHAR)Data = 0;<br />
<br />
This is not a portable construction, GCC rejects is, so has been changed to:<br />
<br />
*((UCHAR *) &Data) = 0;<br />
<br />
== Feature Wish List ==<br />
<br />
TODO.<br />
<br />
== Hacking Notes ==<br />
<br />
TODO.</div>
Whiterocker
https://www.coreboot.org/index.php?title=Download_coreboot&diff=5731
Download coreboot
2008-03-02T04:56:49Z
<p>Whiterocker: /* Anonymous access */ Add OpenVSA</p>
<hr />
<div>__NOTOC__<br />
'''Note: These snapshots are for people, who use Linux as operating system and are able to build software from the source code.''' <br />
<br />
There is no ''easy to install package'' for people who want to quickly try out a new BIOS on their computer, yet. For this purpose we will soon provide a disk image, which you can use with the [[QEMU]] emulator to test coreboot on your Linux, OS X and Windows computers (without having to do any hardware changes).<br />
<br />
== Snapshots ==<br />
<br />
There is an archive of snapshots available at [http://qa.coreboot.org/ qa.coreboot.org]. There is a .bz2 tar file that gets updated when the repository changes. Older snapshots are maintained as well. You can also [http://www.coreboot.org/viewvc/trunk/coreboot-v2.tar.gz?view=tar download the most current snapshot] directly.<br />
<br />
== Subversion checkout ==<br />
<br />
coreboot keeps its development tree in a [http://subversion.tigris.org/ Subversion] repository. <br />
<br />
=== Anonymous access ===<br />
<br />
You can check it out as follows:<br />
<br />
If you want the new and '''still in development coreboot v3''' (ca. 11 MB data as of 09/2007):<br />
<br />
$ svn co svn://coreboot.org/repository/coreboot-v3<br />
<br />
If you want the '''current stable version coreboot v2''' (ca. 58 MB data as of 09/2007):<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/coreboot-v2<br />
<br />
If you want a '''specific revision''' (see the [[Confirmed working svn revisions]] page):<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/coreboot-v2 -r 2100<br />
<br />
If you want the [[OpenVSA]] sources:<br />
<br />
$ svn co svn://coreboot.org/openvsa/trunk/openvsa<br />
<br />
If you want the '''old, unmaintained and unsupported coreboot v1''' tree (ca. 47 MB data as of 09/2007):<br />
<br />
$ svn co svn://coreboot.org/repos/trunk/coreboot-v1<br />
<br />
If your company installed a '''firewall that blocks the svn port''' (3690) you can also '''check out using the webdav frontend''':<br />
<br />
$ svn co <nowiki>https://coreboot.org/svn/trunk/coreboot-v2</nowiki><br />
<br />
=== Developer access with write permission ===<br />
<br />
Access for developers with write permission, is very similar to anonymous access. Just add your Subversion username as follows when checking out the repository:<br />
<br />
$ svn co svn://<username>@coreboot.org/repos/trunk/coreboot-v2<br />
<br />
== Source code browsing ==<br />
<br />
You can also browse the coreboot Subversion repository online using the [http://coreboot.org/viewvc/?root=coreboot ViewVC interface] or the [http://tracker.coreboot.org/trac/coreboot/browser Trac interface].</div>
Whiterocker
https://www.coreboot.org/index.php?title=Libpayload&diff=5724
Libpayload
2008-02-28T00:02:09Z
<p>Whiterocker: Provide starting text for libpayload</p>
<hr />
<div>== Overview ==<br />
<br />
Currently a concept rather than shipping code, libpayload is a coreboot subproject that intends to provide a lightweight implementation of common and useful functions for coreboot payloads. The benefits of linking a coreboot payload against libpayload are:<br />
* payloads do not have to implement and maintain low-level code for I/O, common functions, etc,<br />
* payloads can be recompiled and deployed for CPU architectures supported by coreboot in the future,<br />
* libpayload functions tested and scrutinized outside payload development,<br />
* payloads themselves may be partly host-tested, e.g. against an emulation libpayload,<br />
* leads to the possibility of payloads using dynamic linking, reducing total payload footprint.<br />
<br />
''just give us a main() and a pocket full of dreams and we'll do the rest''<br />
<br />
== Feature Wish List ==<br />
<br />
* Basics<br />
** coreboot services and structures (e.g. read CMOS, device tree)<br />
** subset of C-library functions (e.g. printf, puts, getch)<br />
** light ncurses from the Google Summer Of Code project<br />
* Fancies<br />
** directFB<br />
** TWIN<br />
<br />
== Usage Example ==<br />
<br />
hello_payload.c:<br />
<pre><br />
#include <stdio.h><br />
<br />
int main( void )<br />
{<br />
printf( "Hello, world!\n" );<br />
return 0;<br />
}<br />
</pre><br />
<br />
build:<br />
<pre><br />
libpayload-gcc -o hello_payload hello_payload.c<br />
</pre></div>
Whiterocker
https://www.coreboot.org/index.php?title=Developer_Manual&diff=5682
Developer Manual
2008-02-22T21:29:27Z
<p>Whiterocker: describe the path an Intel architecture mainboard takes from reset to payload execution</p>
<hr />
<div></div>
Whiterocker