Find the answer to your Linux question:
Results 1 to 4 of 4
Hi, I have chosen to implement a 'TINY' kernel as my final year project. To make things simple I have planned to work on 8086 processor. Reasons for choosing 8086 ...
  1. #1
    Just Joined!
    Join Date
    Jan 2009
    Posts
    12

    How to boot from a C program

    Hi,

    I have chosen to implement a 'TINY' kernel as my final year project.

    To make things simple I have planned to work on 8086 processor.

    Reasons for choosing 8086 are:

    1) primarily because this is the first time I am working "close" to the system
    2) Compared to its successors, 8086 has relatively fewer instructions that could be mastered with ease.
    3) It has got only one mode of operation(real mode) unlike its successors which support more than a single mode (real and protected mode, but I believe there are more)
    I was told that no serious kernel programmer would write a kernel in real mode.
    I certainly cannot defend myself against what I was told, as I need a lot of time to make progress from 8086 to high-end processors.

    So far:

    1) I have written a trivial boot loader that resides in the first sector of a floppy disk.
    2) My kernel so far is a shell that displays "$hell>", prompting the user to enter commands
    The user could type any sequence of alphanumeric characters.

    Upon keying enter, it echoes the typed text.
    The commands are not implemented yet.

    To summarize, the kernel so far recognizes the keys typed and echoes them back to the screen in a new line.

    This minute kernel is made to reside in the floppy disk starting from sector 2 following the boot-loader.

    3) Upon booting from the floppy, my tiny bootloader is conventionally loaded to 0000:7c00 and is executed.
    The boot-loader fetches the kernel from the floppy to a predetermined memory location and passes control to it.

    4) As a result the kernel executes and stays in an infinite loop performing just the echo functionality as explained in point 2

    So far I have just been using BIOS interrupts to get my job done. I am not sure when I'll come across coding the peripheral controllers myself.

    PROBLEM:

    To make the programming aspect easier I want to code in C.

    I have done a sample program to print a string on the screen by using inline assembly.
    I made sure that I am not using any library functions and therefore I have not included any header files.

    However, the compiler seems to add certain headers to the object file and the executable file of this sample
    program.

    The actual machine code of my program is embedded between these headers.
    So when my bootloader loads the kernel and passes the control to it, this undesired hexa code is being executed.
    How do I circumvent this problem?

    How do the Linux kernel developers manage to get JUST the kernel binaries without the headers after compiling the kernel?

    Thank you.

  2. #2
    Linux User
    Join Date
    Dec 2007
    Location
    Idaho USA
    Posts
    351
    I'm sure there are some programers here that can help ,but in meantime would look at Programmer's Heaven - Ruby, .NET, C#, C++, PHP, Python, Java - It's all here!
    and do a google for "program in real mode".

  3. #3
    Linux Engineer GNU-Fan's Avatar
    Join Date
    Mar 2008
    Posts
    935
    Quote Originally Posted by kdeveloper View Post
    2) Compared to its successors, 8086 has relatively fewer instructions that could be mastered with ease.
    3) It has got only one mode of operation(real mode) unlike its successors which support more than a single mode (real and protected mode, but I believe there are more)
    I was told that no serious kernel programmer would write a kernel in real mode.
    I certainly cannot defend myself against what I was told, as I need a lot of time to make progress from 8086 to high-end processors.
    Yes and no. All x86 compatibles boot up in real mode (done by BIOS), so this isn't any workload for you. Nobody pressures you to use the new instructions either, but the >286s have a lot more registers to stuff temporary data into, making a programmer's life easier.

    Quote Originally Posted by kdeveloper View Post
    However, the compiler seems to add certain headers to the object file and the executable file of this sample program.

    The actual machine code of my program is embedded between these headers.
    So when my bootloader loads the kernel and passes the control to it, this undesired hexa code is being executed.
    Because the frontend of your compiler assumes you develop for the GNU/Linux operating system. The actual binary code gets embedded in metadata so that the operating system knows for example where the programm actually starts.
    Wikipedia for "elf" executable file format.

    Quote Originally Posted by kdeveloper View Post
    How do I circumvent this problem?
    You could tell the compiler to stop right after the compiling and before the assembling stage. Then you will get an assembler listing as output.
    I forget the actual option switch, it might have been "-s" or "-S".

    Also remember that it is not carved into stone that every program starts at "main". You might need to tell this to the linker manually.
    Debian GNU/Linux -- You know you want it.

  4. #4
    Just Joined!
    Join Date
    Jan 2009
    Posts
    12
    Hi,

    We have used bcc to compile our program test.c. as :

    bcc -ansi test.c

    It has generated the conventional a.out file.
    Using khexEdit, I looked at the contents of the a.out file.

    The size of a.out file was around 960 bytes.

    Amidst the random hex code, we found the following:

    auto_start, startup, _main, _errno, syscallx, syscalls, syscalli, __exit, and so on..

    As certain predefined constants and calls are being used, we have tried a different way

    bcc -ansi -S test.c //generated test.s
    as86 test.s -o test.o
    ld86 -d test.o -o test

    This generated the binary file called 'test' which turned out to be only 100 bytes in size and which doesn't seem to have the list of things I have mentioned above.

    But booting from 'test' also failed.

    So using emu8086 (an 8086 emulator) we have loaded the 'test' file and emulated. We didn't get the expected outcome.

    Instead of emulating a binary file, we have taken the test.s generated previously and tried to generate a .bin file using the emulator.

    But the emulator has shown a lot of errors in the assembler code generated by the bcc command.

    The manual of bcc says that the command converts C to 8086 compatible instructions.

    However, that doesn't seem to be the case.

    What should I do to locate the desired machine code amidst all this?

    Thank you

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...