2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
8 #include <aros/kernel.h>
10 #include <bootconsole.h>
11 #include <elfloader.h>
15 #include "bootstrap.h"
18 unsigned long mb1_parse(struct multiboot
*mb
, struct mb_mmap
**mmap_addr
, unsigned long *mmap_len
)
20 const char *cmdline
= NULL
;
21 struct mb_mmap
*mmap
= NULL
;
22 unsigned long len
= 0;
23 unsigned long usable
= (unsigned long)&_end
;
25 con_InitMultiboot(mb
);
27 D(kprintf("[Multiboot] Multiboot v1 structure @ %p\n", mb
));
30 * Now allocate our mirror buffer.
31 * The buffer is used only by graphical console.
35 if (mb
->flags
& MB_FLAGS_CMDLINE
)
37 cmdline
= (const char *)mb
->cmdline
;
38 D(kprintf("[Multiboot] Command line @ %p : '%s'\n", mb
->cmdline
, cmdline
));
40 usable
= STR_TOP_ADDR(usable
, cmdline
);
43 if ((mb
->flags
& MB_FLAGS_MMAP
))
45 mmap
= (struct mb_mmap
*)mb
->mmap_addr
;
46 len
= mb
->mmap_length
;
48 D(kprintf("[Multiboot] Memory map at 0x%p, length %u\n", mmap
, len
));
49 usable
= TOP_ADDR(usable
, (void *)mmap
+ len
);
52 if (mb
->flags
& MB_FLAGS_MEM
)
54 D(kprintf("[Multiboot] Low memory %u KB, upper memory %u KB\n", mb
->mem_lower
, mb
->mem_upper
));
59 * To simplify things down, memory map is mandatory for our kickstart.
60 * So we create an implicit one if the bootloader didn't supply it.
62 mmap
= mmap_make(&len
, mb
->mem_lower
<< 10, (unsigned long long)mb
->mem_upper
<< 10);
65 /* Kickstart wants size in bytes */
66 tag
->ti_Tag
= KRN_MEMLower
;
67 tag
->ti_Data
= mb
->mem_lower
<< 10;
70 tag
->ti_Tag
= KRN_MEMUpper
;
71 tag
->ti_Data
= (unsigned long long)mb
->mem_upper
<< 10;
75 if (mb
->flags
& MB_FLAGS_LDRNAME
)
77 tag
->ti_Tag
= KRN_BootLoader
;
78 tag
->ti_Data
= mb
->loader_name
;
81 usable
= STR_TOP_ADDR(usable
, (const char *)mb
->loader_name
);
85 panic("No memory information provided by the bootloader");
87 if (ParseCmdLine(cmdline
))
89 /* No VESA mode was set by command line arguments, supply what we already have */
90 if (mb
->flags
& MB_FLAGS_GFX
)
92 /* We prefer complete VBE data if present */
93 kprintf("[Multiboot] Got VESA display mode 0x%x from the bootstrap\n", mb
->vbe_mode
);
95 D(kprintf("[Multiboot] Mode info 0x%p, controller into 0x%p\n", mb
->vbe_mode_info
, mb
->vbe_control_info
));
96 D(kprintf("[Multiboot] VBE version 0x%04X\n", ((struct vbe_controller
*)mb
->vbe_control_info
)->version
));
97 D(kprintf("[Multiboot] Resolution %d x %d\n", ((struct vbe_mode
*)mb
->vbe_mode_info
)->x_resolution
, ((struct vbe_mode
*)mb
->vbe_mode_info
)->y_resolution
));
98 D(kprintf("[Multiboot] Mode flags 0x%04X, framebuffer 0x%p\n", ((struct vbe_mode
*)mb
->vbe_mode_info
)->mode_attributes
, ((struct vbe_mode
*)mb
->vbe_mode_info
)->phys_base
));
99 D(kprintf("[Multiboot] Windows A 0x%04X B 0x%04X\n", ((struct vbe_mode
*)mb
->vbe_mode_info
)->win_a_segment
, ((struct vbe_mode
*)mb
->vbe_mode_info
)->win_b_segment
));
102 * We are already running in VESA mode set by the bootloader.
103 * Pass on the mode information to AROS.
105 tag
->ti_Tag
= KRN_VBEModeInfo
;
106 tag
->ti_Data
= mb
->vbe_mode_info
;
109 tag
->ti_Tag
= KRN_VBEControllerInfo
;
110 tag
->ti_Data
= mb
->vbe_control_info
;
113 tag
->ti_Tag
= KRN_VBEMode
;
114 tag
->ti_Data
= mb
->vbe_mode
;
117 usable
= TOP_ADDR(usable
, mb
->vbe_mode_info
+ sizeof(struct vbe_mode
));
118 usable
= TOP_ADDR(usable
, mb
->vbe_control_info
+ sizeof(struct vbe_controller
));
120 else if (mb
->flags
& MB_FLAGS_FB
)
123 * We have a framebuffer but no VBE information.
124 * Looks like we are running on EFI machine with no VBE support (Mac).
125 * Convert framebuffer data to VBEModeInfo and hand it to AROS.
127 kprintf("[Multiboot] Got framebuffer display %dx%dx%d from the bootstrap\n", mb
->framebuffer_width
, mb
->framebuffer_height
, mb
->framebuffer_bpp
);
128 D(kprintf("[Multiboot] Address 0x%016llX, type %d, %d bytes per line\n", mb
->framebuffer_addr
, mb
->framebuffer_type
, mb
->framebuffer_pitch
));
131 * AROS VESA driver supports only RGB framebuffer because we are
132 * unlikely to have VGA palette registers for other cases.
133 * FIXME: we have some pointer to palette registers. We just need to
134 * pass it to the bootstrap and handle it there (how? Is it I/O port
135 * address or memory-mapped I/O address?)
137 if (mb
->framebuffer_type
== MB_FRAMEBUFFER_RGB
)
139 VBEModeInfo
.mode_attributes
= VM_SUPPORTED
|VM_COLOR
|VM_GRAPHICS
|VM_NO_VGA_HW
|VM_NO_VGA_MEM
|VM_LINEAR_FB
;
140 VBEModeInfo
.bytes_per_scanline
= mb
->framebuffer_pitch
;
141 VBEModeInfo
.x_resolution
= mb
->framebuffer_width
;
142 VBEModeInfo
.y_resolution
= mb
->framebuffer_height
;
143 VBEModeInfo
.bits_per_pixel
= mb
->framebuffer_bpp
;
144 VBEModeInfo
.memory_model
= VMEM_RGB
;
145 VBEModeInfo
.red_mask_size
= mb
->framebuffer_red_mask_size
;
146 VBEModeInfo
.red_field_position
= mb
->framebuffer_red_field_position
;
147 VBEModeInfo
.green_mask_size
= mb
->framebuffer_green_mask_size
;
148 VBEModeInfo
.green_field_position
= mb
->framebuffer_green_field_position
;
149 VBEModeInfo
.blue_mask_size
= mb
->framebuffer_blue_mask_size
;
150 VBEModeInfo
.blue_field_position
= mb
->framebuffer_blue_field_position
;
151 VBEModeInfo
.phys_base
= mb
->framebuffer_addr
;
152 VBEModeInfo
.linear_bytes_per_scanline
= mb
->framebuffer_pitch
;
153 VBEModeInfo
.linear_red_mask_size
= mb
->framebuffer_red_mask_size
;
154 VBEModeInfo
.linear_red_field_position
= mb
->framebuffer_red_field_position
;
155 VBEModeInfo
.linear_green_mask_size
= mb
->framebuffer_green_mask_size
;
156 VBEModeInfo
.linear_green_field_position
= mb
->framebuffer_green_field_position
;
157 VBEModeInfo
.linear_blue_mask_size
= mb
->framebuffer_blue_mask_size
;
158 VBEModeInfo
.linear_blue_field_position
= mb
->framebuffer_blue_field_position
;
160 tag
->ti_Tag
= KRN_VBEModeInfo
;
161 tag
->ti_Data
= KERNEL_OFFSET
| (unsigned long)&VBEModeInfo
;
170 /* Search for external modules loaded by GRUB */
171 /* Are there any modules at all? */
172 if (mb
->flags
&& MB_FLAGS_MODS
)
174 struct mb_module
*mod
= (struct mb_module
*)mb
->mods_addr
;
177 D(kprintf("[Multiboot] GRUB has loaded %d files\n", mb
->mods_count
));
179 /* Go through the list of modules loaded by GRUB */
180 for (i
=0; i
< mb
->mods_count
; i
++)
182 usable
= AddModule(mod
->mod_start
, mod
->mod_end
, usable
);
187 /* We return the lowest address suitable for loading kickstart into */