This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Loading linux image through redboot.


>         Is it possible to load linux image for x86 system through redboot.If
> it is possible then at which location the setup code and system code must be
> loaded and whether it     
>         requires change in source code ?

I solved this problem by stripping the setup code from the start of the
linux image and booting that directly in protected mode. It's a bit of a
hack, but I was able to make it work.

1) Create raw image without the realmode header. This corresponds to
arch/i386/boot/compressed/bvmlinux.out

	dd if=bzImage of=kernel bs=1024 skip=3

2) Load the file 'kernel' onto the board at 0x100000 using whatever
method you choose.

3) Build the attached .c and .S into RedBoot. Note that these have been
stripped down to the basics removing some device specific stuff. They
are completely untested (not even built), although the non-stripped down
version works for my application. You may need to tweak them. If so you
should read the kernel docs carefully. Especially
Documentation/i386/boot.txt. Also read the the source for the real mode
part, in particular arch/i386/boot/setup.S.

The .c file attempts to setup the same environment as the real mode
header in linux does. The .S part then resets the GDT to match linux and
begins executing the code.

Perhaps someone would like to massage into something suitable for the
generic i386 arch directory, unfortunately I don't have time right at
the minute.

Cheers,
Ian.
-- 
Ian Campbell
Design Engineer

Arcom Control Systems Ltd,
Clifton Road,
Cambridge CB1 7EA
United Kingdom

Tel: +44 (0)1223 403465
E-Mail: icampbell@arcomcontrols.com
Web: http://www.arcomcontrols.com


________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs SkyScan
service. For more information on a proactive anti-virus service working
around the clock, around the globe, visit http://www.messagelabs.com
________________________________________________________________________
#include <redboot.h>
#include <cyg/io/flash.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/drv_api.h>
#include <cyg/devs/eth/rtl8139c.h>

#define RAM_KERNEL_BASE (0x00100000)

static void do_linux(int argc, char **argv);

RedBoot_cmd("linux",
	    "Boot linux",
	    "[-n [-f <filename>] ] [-c \"<command line>\"]",
	    do_linux
    );

extern void do_linux_boot(void);

static void
do_linux(int argc, char **argv)
{
	bool command_line_set = false;
	char *command_line = NULL;
	cyg_uint32 mem_size;
	cyg_uint32 int15_e801;

	struct option_info opts[1];

    unsigned long oldints;

    init_opts(&opts[0], 'c', true, OPTION_ARG_TYPE_STR, 
              (void **)&command_line, (bool *)&command_line_set, "command line");
    if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, NULL)) {
        return;
    }

    mem_size = 0x4000; // MEMORY SIZE IN KiloBytes
    // Result of int15 ax=0xe801
    int15_e801 = mem_size - 1024; // 1M+ only
    diag_printf("Memory Size: %dM\n", mem_size >> 10);

    extern void cyg_pci_init(void);
    cyg_pci_init();

    HAL_DISABLE_INTERRUPTS(oldints);
    HAL_DCACHE_SYNC();
    HAL_ICACHE_DISABLE();
    HAL_DCACHE_DISABLE();
    HAL_DCACHE_SYNC();
    HAL_ICACHE_INVALIDATE_ALL();
    HAL_DCACHE_INVALIDATE_ALL();

    // Clear the data area
    memset ( (void*)0x90000, 512, 4 );

    if ( command_line_set ) {
        diag_printf("Using specified command line\n");
        strcpy( (char*)0x93400, command_line);
    } else {
        diag_printf("Using default command line\n");
	strcpy( (char*)0x93400, "root=1f02 console=ttyS0,115200n8 ro");
    }
    diag_printf("Command Line: %s\n", (char*)0x93400 );

    // Pointer to the command line
    *(cyg_uint32*)(0x90228) = 0x93400;
    // Loader type
    *(cyg_uint8*)(0x90210) = 0x40; // Etherboot
    *(cyg_uint8*)(0x90211) = 0x1; // Kernel loaded high
    *(cyg_uint32*)(0x90214) = 0x100000; // Kernel load address

    // Memory sizes
    *(cyg_uint16*)(0x90002) = 0; // force use of e801 result below.
    *(cyg_uint32*)(0x901e0) = int15_e801;

    // No e820 map!
    *(cyg_uint8*) (0x901e8) = 0; // Length of map

    // Video stuff
    *(cyg_uint8*) (0x90000) = 0; // orig_x
    *(cyg_uint8*) (0x90001) = 0; // orig_y
    *(cyg_uint8*) (0x90006) = 2; // orig_video_mode
    *(cyg_uint8*) (0x90007) = 80; // orig_video_cols
    *(cyg_uint8*) (0x9000E) = 25; // orig_video_lines
    *(cyg_uint8*) (0x9000F) = 0; // orig_video_isVGA

    // Reset eth controller, or it'll continue to DMA over our page tables later :-(
    extern void rtl8139c_reset(void);
    rtl8139c_reset();
    
    diag_printf("Booting Linux image from 0x%08X\n", RAM_KERNEL_BASE);
    do_linux_boot();    
}

Attachment: linux.S
Description: Text document

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]