3 #include <aros/kernel.h>
5 #include <bootconsole.h>
10 #include "bootstrap.h"
13 unsigned long mb1_parse(struct multiboot
*mb
, struct mb_mmap
**mmap_addr
, unsigned long *mmap_len
)
15 const char *cmdline
= NULL
;
16 struct mb_mmap
*mmap
= NULL
;
17 unsigned long len
= 0;
18 unsigned long usable
= (unsigned long)&_end
;
20 con_InitMultiboot(mb
);
22 D(kprintf("[Multiboot] Multiboot v1 structure @ %p\n", mb
));
25 * Now allocate our mirror buffer.
26 * The buffer is used only by graphical console.
30 if (mb
->flags
& MB_FLAGS_CMDLINE
)
32 cmdline
= (const char *)mb
->cmdline
;
33 D(kprintf("[Multiboot] Command line @ %p : '%s'\n", mb
->cmdline
, cmdline
));
35 usable
= STR_TOP_ADDR(usable
, cmdline
);
38 if ((mb
->flags
& MB_FLAGS_MMAP
))
40 mmap
= (struct mb_mmap
*)mb
->mmap_addr
;
41 len
= mb
->mmap_length
;
43 D(kprintf("[Multiboot] Memory map at 0x%p, length %u\n", mmap
, len
));
44 usable
= TOP_ADDR(usable
, (void *)mmap
+ len
);
47 if (mb
->flags
& MB_FLAGS_MEM
)
49 D(kprintf("[Multiboot] Low memory %u KB, upper memory %u KB\n", mb
->mem_lower
, mb
->mem_upper
));
54 * To simplify things down, memory map is mandatory for our kickstart.
55 * So we create an implicit one if the bootloader didn't supply it.
57 mmap
= mmap_make(&len
, mb
->mem_lower
<< 10, (unsigned long long)mb
->mem_upper
<< 10);
60 /* Kickstart wants size in bytes */
61 tag
->ti_Tag
= KRN_MEMLower
;
62 tag
->ti_Data
= mb
->mem_lower
<< 10;
65 tag
->ti_Tag
= KRN_MEMUpper
;
66 tag
->ti_Data
= (unsigned long long)mb
->mem_upper
<< 10;
70 if (mb
->flags
& MB_FLAGS_LDRNAME
)
72 tag
->ti_Tag
= KRN_BootLoader
;
73 tag
->ti_Data
= mb
->loader_name
;
76 usable
= STR_TOP_ADDR(usable
, (const char *)mb
->loader_name
);
80 panic("No memory information provided by the bootloader");
82 if (ParseCmdLine(cmdline
))
84 /* No VESA mode was set by command line arguments, supply what we already have */
85 if (mb
->flags
& MB_FLAGS_GFX
)
87 /* We prefer complete VBE data if present */
88 kprintf("[Multiboot] Got VESA display mode 0x%x from the bootstrap\n", mb
->vbe_mode
);
90 D(kprintf("[Multiboot] Mode info 0x%p, controller into 0x%p\n", mb
->vbe_mode_info
, mb
->vbe_control_info
));
91 D(kprintf("[Multiboot] VBE version 0x%04X\n", ((struct vbe_controller
*)mb
->vbe_control_info
)->version
));
92 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
));
93 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
));
94 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
));
97 * We are already running in VESA mode set by the bootloader.
98 * Pass on the mode information to AROS.
100 tag
->ti_Tag
= KRN_VBEModeInfo
;
101 tag
->ti_Data
= mb
->vbe_mode_info
;
104 tag
->ti_Tag
= KRN_VBEControllerInfo
;
105 tag
->ti_Data
= mb
->vbe_control_info
;
108 tag
->ti_Tag
= KRN_VBEMode
;
109 tag
->ti_Data
= mb
->vbe_mode
;
112 usable
= TOP_ADDR(usable
, mb
->vbe_mode_info
+ sizeof(struct vbe_mode
));
113 usable
= TOP_ADDR(usable
, mb
->vbe_control_info
+ sizeof(struct vbe_controller
));
115 else if (mb
->flags
& MB_FLAGS_FB
)
118 * We have a framebuffer but no VBE information.
119 * Looks like we are running on EFI machine with no VBE support (Mac).
120 * Convert framebuffer data to VBEModeInfo and hand it to AROS.
122 kprintf("[Multiboot] Got framebuffer display %dx%dx%d from the bootstrap\n", mb
->framebuffer_width
, mb
->framebuffer_height
, mb
->framebuffer_bpp
);
123 D(kprintf("[Multiboot] Address 0x%016llX, type %d, %d bytes per line\n", mb
->framebuffer_addr
, mb
->framebuffer_type
, mb
->framebuffer_pitch
));
126 * AROS VESA driver supports only RGB framebuffer because we are
127 * unlikely to have VGA palette registers for other cases.
128 * FIXME: we have some pointer to palette registers. We just need to
129 * pass it to the bootstrap and handle it there (how? Is it I/O port
130 * address or memory-mapped I/O address?)
132 if (mb
->framebuffer_type
== MB_FRAMEBUFFER_RGB
)
134 VBEModeInfo
.mode_attributes
= VM_SUPPORTED
|VM_COLOR
|VM_GRAPHICS
|VM_NO_VGA_HW
|VM_NO_VGA_MEM
|VM_LINEAR_FB
;
135 VBEModeInfo
.bytes_per_scanline
= mb
->framebuffer_pitch
;
136 VBEModeInfo
.x_resolution
= mb
->framebuffer_width
;
137 VBEModeInfo
.y_resolution
= mb
->framebuffer_height
;
138 VBEModeInfo
.bits_per_pixel
= mb
->framebuffer_bpp
;
139 VBEModeInfo
.memory_model
= VMEM_RGB
;
140 VBEModeInfo
.red_mask_size
= mb
->framebuffer_red_mask_size
;
141 VBEModeInfo
.red_field_position
= mb
->framebuffer_red_field_position
;
142 VBEModeInfo
.green_mask_size
= mb
->framebuffer_green_mask_size
;
143 VBEModeInfo
.green_field_position
= mb
->framebuffer_green_field_position
;
144 VBEModeInfo
.blue_mask_size
= mb
->framebuffer_blue_mask_size
;
145 VBEModeInfo
.blue_field_position
= mb
->framebuffer_blue_field_position
;
146 VBEModeInfo
.phys_base
= mb
->framebuffer_addr
;
147 VBEModeInfo
.linear_bytes_per_scanline
= mb
->framebuffer_pitch
;
148 VBEModeInfo
.linear_red_mask_size
= mb
->framebuffer_red_mask_size
;
149 VBEModeInfo
.linear_red_field_position
= mb
->framebuffer_red_field_position
;
150 VBEModeInfo
.linear_green_mask_size
= mb
->framebuffer_green_mask_size
;
151 VBEModeInfo
.linear_green_field_position
= mb
->framebuffer_green_field_position
;
152 VBEModeInfo
.linear_blue_mask_size
= mb
->framebuffer_blue_mask_size
;
153 VBEModeInfo
.linear_blue_field_position
= mb
->framebuffer_blue_field_position
;
155 tag
->ti_Tag
= KRN_VBEModeInfo
;
156 tag
->ti_Data
= KERNEL_OFFSET
| (unsigned long)&VBEModeInfo
;
165 /* Search for external modules loaded by GRUB */
166 /* Are there any modules at all? */
167 if (mb
->flags
&& MB_FLAGS_MODS
)
169 struct mb_module
*mod
= (struct mb_module
*)mb
->mods_addr
;
172 D(kprintf("[Multiboot] GRUB has loaded %d files\n", mb
->mods_count
));
174 /* Go through the list of modules loaded by GRUB */
175 for (i
=0; i
< mb
->mods_count
; i
++)
177 usable
= AddModule(mod
->mod_start
, mod
->mod_end
, usable
);
182 /* We return the lowest address suitable for loading kickstart into */