Call CloseDevice() before DeleteIORequest(), and don't call
[AROS.git] / rom / bootloader / bootloader_init.c
blob2d08b2b8ec7375fecc136e6d32782b2f45dcb9a1
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Bootloader information initialisation.
6 */
8 #define DEBUG 0
10 #include <aros/debug.h>
11 #include <aros/kernel.h>
12 #include <aros/multiboot.h>
13 #include <aros/symbolsets.h>
14 #include <aros/bootloader.h>
15 #include <exec/types.h>
16 #include <exec/memory.h>
17 #include <exec/resident.h>
18 #include <utility/utility.h>
19 #include <utility/tagitem.h>
20 #include <proto/exec.h>
21 #include <proto/bootloader.h>
22 #include <proto/kernel.h>
23 #include <proto/utility.h>
25 #include <ctype.h>
26 #include <string.h>
28 #include "bootloader_intern.h"
30 #include LC_LIBDEFS_FILE
32 static void GetCmdLine(char *Kernel_Args, struct BootLoaderBase *BootLoaderBase)
34 STRPTR buff;
35 ULONG len;
37 /* Sanity check against broken bootstraps */
38 if (!Kernel_Args)
39 return;
41 D(bug("[BootLdr] Kernel arguments: %s\n", Kernel_Args));
43 /* First make a copy of the command line */
44 len = strlen(Kernel_Args) + 1;
45 buff = AllocMem(len, MEMF_ANY);
46 if (buff)
48 CopyMem(Kernel_Args, buff, len);
50 while (1)
52 struct Node *node;
54 /* remove any leading spaces */
55 buff = stpblk(buff);
57 /* Hit end of line (trailing spaces) ? Exit if so. */
58 if (!*buff)
59 break;
61 /* Allocate node and insert into list */
62 node = AllocMem(sizeof(struct Node),MEMF_ANY);
63 if (!node)
64 break;
66 node->ln_Name = buff;
67 AddTail(&(BootLoaderBase->Args), node);
69 /* We now have the command line */
70 BootLoaderBase->Flags |= BL_FLAGS_CMDLINE;
72 /* Skip up to a next space or EOL */
73 while (*buff != '\0' && !isspace(*buff))
74 buff++;
76 /* End of line ? If yes, we are done. */
77 if (!*buff)
79 D(bug("[BootLdr] Init: Last argument %s\n", node->ln_Name));
80 break;
83 /* Split the line and repeat */
84 *buff++ = 0;
85 D(bug("[BootLdr] Init: Argument %s\n", node->ln_Name));
90 static const ULONG masks [] = {0x01, 0x03, 0x07, 0x0f ,0x1f, 0x3f, 0x7f, 0xff};
92 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR BootLoaderBase)
94 struct TagItem *tag, *bootinfo;
95 APTR KernelBase;
96 struct Library *UtilityBase;
97 struct vbe_mode *vmi = NULL;
98 struct vbe_controller *vci = NULL;
99 UWORD vmode = 0x00FF; /* Dummy mode number by default */
100 UBYTE palette = 0; /* By default we don't know palette width */
102 D(bug("[BootLdr] Init\n"));
104 UtilityBase = TaggedOpenLibrary(TAGGEDOPEN_UTILITY);
105 if (!UtilityBase)
106 return FALSE;
108 NEWLIST(&(BootLoaderBase->Args));
109 NEWLIST(&(BootLoaderBase->DriveInfo));
111 KernelBase = OpenResource("kernel.resource");
112 bootinfo = (struct TagItem *)KrnGetBootInfo();
114 while ((tag = NextTagItem(&bootinfo)))
116 switch (tag->ti_Tag)
118 case KRN_BootLoader:
119 BootLoaderBase->LdrName = (STRPTR)tag->ti_Data;
120 break;
122 case KRN_CmdLine:
123 GetCmdLine((char *)tag->ti_Data, BootLoaderBase);
124 break;
126 case KRN_VBEModeInfo:
127 vmi = (struct vbe_mode *)tag->ti_Data;
128 break;
130 case KRN_VBEControllerInfo:
131 vci = (struct vbe_controller *)tag->ti_Data;
132 break;
134 case KRN_VBEMode:
135 vmode = tag->ti_Data;
136 break;
138 case KRN_VBEPaletteWidth:
139 palette = tag->ti_Data;
140 break;
144 /* Get VESA mode information */
145 D(bug("[BootLdr] VESA mode info 0x%p, controller info 0x%p\n", vmi, vci));
147 /* We support only graphical framebuffers here. */
148 if (vmi && (vmi->mode_attributes & VM_GRAPHICS))
150 BootLoaderBase->Vesa = AllocMem(sizeof(struct VesaInfo), MEMF_CLEAR);
152 if (BootLoaderBase->Vesa)
154 /* If we don't have VBEControllerInfo, this is VBE v2 mode structure */
155 unsigned short version = 0x0200;
157 if (vci)
159 D(bug("[BootLdr] Init: Vesa card capability flags: 0x%08X\n", vci->capabilities));
161 version = vci->version;
162 /* FrameBufferSize is in KBytes! */
163 BootLoaderBase->Vesa->FrameBufferSize = vci->total_memory << 6;
166 BootLoaderBase->Vesa->XSize = vmi->x_resolution;
167 BootLoaderBase->Vesa->YSize = vmi->y_resolution;
168 BootLoaderBase->Vesa->BitsPerPixel = vmi->bits_per_pixel;
169 BootLoaderBase->Vesa->ModeNumber = vmode;
170 BootLoaderBase->Vesa->PaletteWidth = palette;
172 /* Framebuffer pointer is only valid for VBE v2 and better */
173 if (version >= 0x0200)
174 BootLoaderBase->Vesa->FrameBuffer = (APTR)(IPTR)vmi->phys_base;
176 if (version >= 0x0300)
178 /* VBE v3 structures specify linear framebuffer parameters in separate fields */
179 BootLoaderBase->Vesa->BytesPerLine = vmi->linear_bytes_per_scanline;
180 BootLoaderBase->Vesa->Masks [VI_Red] = masks[vmi->linear_red_mask_size-1]<<vmi->linear_red_field_position;
181 BootLoaderBase->Vesa->Masks [VI_Blue] = masks[vmi->linear_blue_mask_size-1]<<vmi->linear_blue_field_position;
182 BootLoaderBase->Vesa->Masks [VI_Green] = masks[vmi->linear_green_mask_size-1]<<vmi->linear_green_field_position;
183 BootLoaderBase->Vesa->Masks [VI_Alpha] = masks[vmi->linear_reserved_mask_size-1]<<vmi->linear_reserved_field_position;
184 BootLoaderBase->Vesa->Shifts[VI_Red] = 32 - vmi->linear_red_field_position - vmi->linear_red_mask_size;
185 BootLoaderBase->Vesa->Shifts[VI_Blue] = 32 - vmi->linear_blue_field_position - vmi->linear_blue_mask_size;
186 BootLoaderBase->Vesa->Shifts[VI_Green] = 32 - vmi->linear_green_field_position - vmi->linear_green_mask_size;
187 BootLoaderBase->Vesa->Shifts[VI_Alpha] = 32 - vmi->linear_reserved_field_position - vmi->linear_reserved_mask_size;
189 else
191 BootLoaderBase->Vesa->BytesPerLine = vmi->bytes_per_scanline;
192 BootLoaderBase->Vesa->Masks [VI_Red] = masks[vmi->red_mask_size-1]<<vmi->red_field_position;
193 BootLoaderBase->Vesa->Masks [VI_Blue] = masks[vmi->blue_mask_size-1]<<vmi->blue_field_position;
194 BootLoaderBase->Vesa->Masks [VI_Green] = masks[vmi->green_mask_size-1]<<vmi->green_field_position;
195 BootLoaderBase->Vesa->Masks [VI_Alpha] = masks[vmi->reserved_mask_size-1]<<vmi->reserved_field_position;
196 BootLoaderBase->Vesa->Shifts[VI_Red] = 32 - vmi->red_field_position - vmi->red_mask_size;
197 BootLoaderBase->Vesa->Shifts[VI_Blue] = 32 - vmi->blue_field_position - vmi->blue_mask_size;
198 BootLoaderBase->Vesa->Shifts[VI_Green] = 32 - vmi->green_field_position - vmi->green_mask_size;
199 BootLoaderBase->Vesa->Shifts[VI_Alpha] = 32 - vmi->reserved_field_position - vmi->reserved_mask_size;
202 D(bug("[BootLdr] Init: Vesa mode %x type (%dx%dx%d)\n", BootLoaderBase->Vesa->ModeNumber,
203 BootLoaderBase->Vesa->XSize, BootLoaderBase->Vesa->YSize, BootLoaderBase->Vesa->BitsPerPixel));
204 D(bug("[BootLdr] Init: Vesa FB at 0x%p size %d kB\n", BootLoaderBase->Vesa->FrameBuffer,
205 BootLoaderBase->Vesa->FrameBufferSize));
206 D(bug("[BootLdr] Init: Vesa mode palette width: %d\n", BootLoaderBase->Vesa->PaletteWidth));
207 D(bug("[BootLdr] Init: Vesa mode direct color flags %02X\n", vmi->direct_color_mode_info));
211 CloseLibrary(UtilityBase);
213 return TRUE;
216 ADD2INITLIB(GM_UNIQUENAME(Init), 0)