Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / arch / i386-pc / bootloader / bootloader_init.c
blobc013aa1d3828e1d863e26f790fc03b32ed1fb908
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Bootloader information initialisation.
6 */
8 #include <exec/types.h>
9 #include <exec/memory.h>
10 #include <exec/resident.h>
11 #include <utility/utility.h>
12 #include <proto/exec.h>
13 #include <proto/bootloader.h>
15 #include <aros/symbolsets.h>
16 #include <aros/bootloader.h>
17 #include <aros/multiboot.h>
18 #include "bootloader_intern.h"
19 #include LC_LIBDEFS_FILE
21 #define DEBUG 1
22 #include <aros/debug.h>
24 #include <string.h>
27 * What you see here is a Multiboot-compatible header. We don't need a
28 * sophisticated information package from the multiboot loader.
30 * AROS defines only the first three fields as it is now in ELF executable
31 * format. All other things like load address or entry point are already
32 * in the kernel image.
35 #define MB_MAGIC 0x1BADB002 /* Magic value */
36 #define MB_FLAGS 0x00000003 /* Need 4KB alignment for modules */
38 const struct
40 ULONG magic;
41 ULONG flags;
42 ULONG chksum;
43 } multiboot_header __attribute__((section(".text"))) =
45 MB_MAGIC,
46 MB_FLAGS,
47 -(MB_MAGIC+MB_FLAGS)
50 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR BootLoaderBase)
52 struct arosmb *mb = (struct arosmb *)0x1000;
54 NEWLIST(&(BootLoaderBase->Args));
55 NEWLIST(&(BootLoaderBase->DriveInfo));
57 /* Right. Now we extract the data currently placed in 0x1000 by exec */
58 if (mb->magic == MBRAM_VALID)
60 /* Yay. There is data here */
61 if (mb->flags & MB_FLAGS_LDRNAME)
63 STRPTR temp;
65 temp = AllocMem(200,MEMF_ANY);
66 if (temp)
68 strcpy(temp,mb->ldrname);
69 BootLoaderBase->LdrName = temp;
70 BootLoaderBase->Flags |= MB_FLAGS_LDRNAME;
71 D(bug("[BootLdr] Init: Loadername = %s\n",BootLoaderBase->LdrName));
73 else
74 bug("[BootLdr] Init: Failed to alloc memory for string\n");
76 if (mb->flags & MB_FLAGS_CMDLINE)
78 STRPTR cmd,buff;
79 ULONG temp;
80 struct Node *node;
82 /* First make a working copy of the command line */
83 if ((buff = AllocMem(200,MEMF_ANY|MEMF_CLEAR)))
85 strcpy(buff,mb->cmdline);
86 /* remove any leading spaces */
87 cmd = stpblk(buff);
88 while(cmd[0])
90 /* Split the command line */
91 temp = strcspn(cmd," ");
92 cmd[temp++] = 0x00;
93 D(bug("[BootLdr] Init: Argument %s\n",cmd));
94 /* Allocate node and insert into list */
95 node = AllocMem(sizeof(struct Node),MEMF_ANY|MEMF_CLEAR);
96 node->ln_Name = cmd;
97 AddTail(&(BootLoaderBase->Args),node);
98 /* Skip to next part */
99 cmd = stpblk(cmd+temp);
102 BootLoaderBase->Flags |= MB_FLAGS_CMDLINE;
106 if (mb->flags & MB_FLAGS_GFX)
108 ULONG masks [] = { 0x01, 0x03, 0x07, 0x0f ,0x1f, 0x3f, 0x7f, 0xff };
110 BootLoaderBase->Vesa.FrameBuffer = (APTR)mb->vmi.phys_base;
111 BootLoaderBase->Vesa.FrameBufferSize = mb->vci.total_memory * 64; /* FrameBufferSize is in KBytes! */
112 BootLoaderBase->Vesa.XSize = mb->vmi.x_resolution;
113 BootLoaderBase->Vesa.YSize = mb->vmi.y_resolution;
114 BootLoaderBase->Vesa.BytesPerLine = mb->vmi.bytes_per_scanline;
115 BootLoaderBase->Vesa.BitsPerPixel = mb->vmi.bits_per_pixel;
116 BootLoaderBase->Vesa.ModeNumber = mb->vbe_mode;
117 BootLoaderBase->Vesa.Masks[VI_Red] = masks[mb->vmi.red_mask_size-1]<<mb->vmi.red_field_position;
118 BootLoaderBase->Vesa.Masks[VI_Blue] = masks[mb->vmi.blue_mask_size-1]<<mb->vmi.blue_field_position;
119 BootLoaderBase->Vesa.Masks[VI_Green] = masks[mb->vmi.green_mask_size-1]<<mb->vmi.green_field_position;
120 BootLoaderBase->Vesa.Masks[VI_Alpha] = masks[mb->vmi.reserved_mask_size-1]<<mb->vmi.reserved_field_position;
121 BootLoaderBase->Vesa.Shifts[VI_Red] = 32 - mb->vmi.red_field_position - mb->vmi.red_mask_size;
122 BootLoaderBase->Vesa.Shifts[VI_Blue] = 32 - mb->vmi.blue_field_position - mb->vmi.blue_mask_size;
123 BootLoaderBase->Vesa.Shifts[VI_Green] = 32 - mb->vmi.green_field_position - mb->vmi.green_mask_size;
124 BootLoaderBase->Vesa.Shifts[VI_Alpha] = 32 - mb->vmi.reserved_field_position - mb->vmi.reserved_mask_size;
125 BootLoaderBase->Vesa.PaletteWidth = mb->vbe_palette_width;
126 BootLoaderBase->Flags |= MB_FLAGS_GFX;
127 if (BootLoaderBase->Vesa.ModeNumber != 3)
129 D(bug("[BootLdr] Init: Vesa card capability flags: 0x%08lx\n", mb->vci.capabilities));
130 D(bug("[BootLdr] Init: Vesa mode %x type (%dx%dx%d)\n",
131 BootLoaderBase->Vesa.ModeNumber,
132 BootLoaderBase->Vesa.XSize,BootLoaderBase->Vesa.YSize,
133 BootLoaderBase->Vesa.BitsPerPixel));
134 D(bug("[BootLdr] Init: Vesa FB at 0x%08x size %d kB\n",
135 BootLoaderBase->Vesa.FrameBuffer,
136 BootLoaderBase->Vesa.FrameBufferSize));
137 D(bug("[BootLdr] Init: Vesa mode palette width: %d\n", BootLoaderBase->Vesa.PaletteWidth));
138 D(bug("[BootLdr] Init: Vesa mode direct color flags %02x\n", mb->vmi.direct_color_mode_info));
140 else
142 D(bug("[BootLdr] Init: Textmode graphics\n"));
146 if (mb->flags & MB_FLAGS_DRIVES)
148 struct mb_drive *curr;
149 struct DriveInfoNode *node;
151 for (curr = (struct mb_drive *) mb->drives_addr;
152 (unsigned long) curr < mb->drives_addr + mb->drives_len;
153 curr = (struct mb_drive *) ((unsigned long) curr + curr->size))
155 node = AllocMem(sizeof(struct DriveInfoNode),MEMF_ANY|MEMF_CLEAR);
156 node->Number = curr->number;
157 node->Mode = curr->mode;
158 node->Cylinders = curr->cyls;
159 node->Heads = curr->heads;
160 node->Sectors = curr->secs;
161 ADDTAIL(&(BootLoaderBase->DriveInfo),(struct Node *)node);
163 D(bug("[BootLdr] Init: Drive %02x, CHS (%d/%d/%d) mode %s\n",
164 curr->number,
165 curr->cyls,curr->heads,curr->secs,
166 curr->mode?"CHS":"LBA"));
168 BootLoaderBase->Flags |= MB_FLAGS_DRIVES;
171 return TRUE;
174 ADD2INITLIB(GM_UNIQUENAME(Init), 0)