Wednesday, October 20, 2010

compile coreboot and flash BIOS

I successfully compiled coreboot on centos 5.5.
Below are the details.

First of all, you need to install subversion, make, gcc, g++.
If you cannot find package by using: yum install, you can do: yum search

Below are the problems I had:

1. need ncurses-dev for make menuconfig
The error messasge is: curses.h no such file
solutions is:  $ yum install ncurses-devel ncurses

2. need to update ld in binutils
The error message is: /usr/bin/ld: unrecgonized option '--build-id=none'
It is because the version of binutils is not the lastest version. ld cannot recgonize "build-id" option. Even if you tried:
yum update binutils
It is still the old version on centos. I think it is because the repository of centos 5.5 haven't update the binutils.
You can find the latest version of binutils from:
http://ftp.gnu.org/gnu/binutils/
I just downloaded the last version is:
[   ] binutils-2.20.1.tar.gz            03-Mar-2010 10:21   22M 
 
 After download the binutils, you need to build it. Read the README file. and install it.

3. you also need to install following package from coreboot howto website
  • doxygen (for generating/viewing documentation)
  • iasl (for targets with ACPI support)
  • gdb (for better debugging facilities on some targets)
  • flex and bison (for regenerating parsers)

 you could install them by using:
yum install
but package iasl you cannot find it.
you need to download it from
http://www.acpica.org/downloads/
you need to download first file, untar it, and build the iasl in compile folder.
From the Readme file, we know the makfile doesn't have "make install" function. So we need to copy the binary file iasl manually to /usr/bin directory.

Now, I think you have successful build coreboot.

In addition, for the make meneconfig, there are something you need to know:
you need to specify the motherboard factory, motherboard model, and the size of BIOS(some of them is 512kb, some of them are 1024kb).
you also need to specify the payload, the payload I am using the seabios. You could compile your own seabios, or you could download binary seabios from coreboot website.
I also have another post about linking the vagbios.bin in the configuration file.

For FlashBIOS, you need to download flashrom tool from coreboot.org
and run:
$ flashrom -w coreboot.rom // write coreboot.rom file to BIOS

uuencode

uuencode uudecode

Ubuntu: sudo apt-get install uuencode
Centos: yum install sharutils

Copy past need to include begin and end\n keyword


e.g. ( this article has an uuencoding file brazil_SMM.tgz )
http://www.phrack.com/issues.html?issue=65&id=7#article


A uuencoded file starts with a header line of the form:
 begin <mode> <file><newline>


e.g.,

begin 644 cat.txt
#0V%T
`
end


wiki explains uuencoding:
http://en.wikipedia.org/wiki/Uuencoding

Tuesday, October 19, 2010

write to port

(1) http://www.faqs.org/docs/Linux-mini/IO-Port-Programming.html

(2) http://ubuntuforums.org/showthread.php?t=1211949

resource 1, we need to change the include file
from
#include <asm/io.h>
to
#include <sys/io.h>

resource 2 is another example of IO programming in C

We also could use in and out assembly instructions to write something to port.
However, in and out instruction have been locked in protected mode.

mov 0xff %al
mov 0xb2 %dx
out %al %dx

write 0xff to port 0xb2

inline gcc assembly

http://wiki.osdev.org/Inline_Assembly/Examples

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

E.G.


int a=10, b;
        asm ("movl %1, %%eax; 
              movl %%eax, %0;"
             :"=r"(b)        /* output */
             :"r"(a)         /* input */
             :"%eax"         /* clobbered register */
             );       


Above code will have compile errors, but if you put assembly code line2 and line3 together, it will compile. Or you could change it to:


int a=10, b;
        asm ("movl %1, %%eax;" 
             "movl %%eax, %0;"
             :"=r"(b)        /* output */
             :"r"(a)         /* input */
             :"%eax"         /* clobbered register */
             );       

This time, it will work.


Explaining:

Here what we did is we made the value of ’b’ equal to that of ’a’ using assembly instructions. Some points of interest are:

  • "b" is the output operand, referred to by %0 and "a" is the input operand, referred to by %1.
  • "r" is a constraint on the operands. We’ll see constraints in detail later. For the time being, "r" says to GCC to use any register for storing the operands. output operand constraint should have a constraint modifier "=". And this modifier says that it is the output operand and is write-only.
  • There are two %’s prefixed to the register name. This helps GCC to distinguish between the operands and registers. operands have a single % as prefix.
  • The clobbered register %eax after the third colon tells GCC that the value of %eax is to be modified inside "asm", so GCC won’t use this register to store any other value.

When the execution of "asm" is complete, "b" will reflect the updated value, as it is specified as an output operand. In other words, the change made to "b" inside "asm" is supposed to be reflected outside the "asm".

Now we may look each field in detail.

Friday, October 15, 2010

Read printk() statement from coreboot source code

the printk() statement in coreboot writes its content to first serial port on the board.
We could use a serial-to-USB cable connect your target machine to your laptop. By using mincom (a tool for setting up reading serial port data), we could read the data from hyperterminal (mincom) from the laptop.

VGA BIOS

by using command:
lspci -vn (-n is for PCI vendor and device ID)
we could find the VGA device vedor IDs.
For ASUS MZV-MX mainboard is: 1106-3230

After we get this, we could find the VGA module on regular BIOS.
We use BISO modification tool, mmtool, to extract VGA module from BIOS.
Then include this vgabios.bin file in the coreboot configuration file.
After we compile and build our BIOS using coreboot, we have a BIOS enable VGA

Wednesday, October 6, 2010

C calling conventaion && active record && stack

The fast way to understand C calling convention is to write a C program and compile it into assembly, and understand the assembly code. For exmaple:
## test.c ##
#include <stdio.h>
int sum(int a, int b)
{
  int c;
  c= a+b;
  return c;


}
int main(void)
{
  int a = 1;
  int b = 2;
  sum(a, b);
  return 1;
}




## compile ##
gcc -S test.c


## assembly ##
    .file    "test.c"
    .text
.globl sum
    .type    sum, @function
sum:
    pushl    %ebp                             // save previous ebp, which is ebp in main()
    movl    %esp, %ebp                   // set the new ebp of sum() = current esp value
    subl    $16, %esp                       // esp = esp -16
    movl    12(%ebp), %eax            // *(%ebp+12), this is value b, put in eax
    movl    8(%ebp), %edx              // put value a into edx
    leal    (%edx,%eax), %eax        //
    movl    %eax, -4(%ebp)             //*(ebp-4): this is local variable c.
    movl    -4(%ebp), %eax            // put c into eax again, becase return value in eax
    leave                                       // movl %ebp, %esp; pop %ebp
                                                   // set the value of esp = the value of ebp, pop the 
                                                   // first element in stack, which is the saved ebp    ret                                        // pop %eip, pop the return address, and save to eip
    .size    sum, .-sum
.globl main
    .type    main, @function
main:
    pushl    %ebp                           // save ebp
    movl    %esp, %ebp                 // the value in ebp reigster = the value in esp reg
    subl    $24, %esp                     // esp = esp -24


/*push the local variables into stack*/
    movl    $1, -4(%ebp)                // put value 1 into stack. this is local variable.
                                                    // ebp always point to the top of local variables
    movl    $2, -8(%ebp)                // put value 2 into stack, (int b)


/*push the paramters of sum function into statck*/
/*remember, C convention push the last parameter into stack first*/
    movl    -8(%ebp), %eax           // value of eax = content of ((value of ebp) - 8)
                                                   // integers are 4 bytes. This is "int b"
    movl    %eax, 4(%esp)            // content of ((value of esp)+4) = value of eax
    movl    -4(%ebp), %eax          // this is "int a" of sum() parameters
    movl    %eax, (%esp)             // even we assignment two paramaters on the
                                                  // stack, but we didn't change the value of esp
                                                  // "push", "pop", "call", ret" instructions change esp
/*start to call subprogram*/
    call    sum                             // push %eip;  movl sum, %eip
                                                 // this will save the return address of sum()




/*end this function*/
    movl    $1, %eax                   // put 1 into eax, this is the return value.
    leave                                     // movl %ebp, %esp; pop %ebp
                                                 // set the value of esp = the value of ebp, pop the 
                                                 // first element in stack, which is the saved ebp
    ret                                        // pop %eip, pop the return address, and save to eip


    .size    main, .-main
    .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits










In active record, the sequence is:


..................4G......................


parameter n
parameter n-1
paremeter 1
Return address
previous ebp ______________current ebp point to here(betwen "perv ebp" & v1)
local variable1
local vraible2


.................. 0 .......................


esp suppose point to the top of stack. instrunction like push pop will change esp automatically. some other instruction like call, ret which include "push" or "pop" could also change esp.

Friday, October 1, 2010

Ctr+Z

CTR+Z set the program into sleep. if you want to wake up the process.
you could use fg command.

for example;
evince simple.pdf
CTR+z
fg evince