From 4f12af3748d7304912118bbdabe21f33b0903ebe Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jan 2010 18:52:11 +0100 Subject: [PATCH] Define framebuffer video independently of VBE video --- doc/boot.S | 16 ++++++-- doc/kernel.c | 81 +++++++++++++++++++++++++++++++++++++ doc/multiboot.h | 40 ++++++++++++++++++- doc/multiboot.texi | 99 ++++++++++++++++++++++------------------------ 4 files changed, 180 insertions(+), 56 deletions(-) diff --git a/doc/boot.S b/doc/boot.S index edf9268e2..d7e128fc4 100644 --- a/doc/boot.S +++ b/doc/boot.S @@ -30,9 +30,9 @@ /* The flags for the Multiboot header. */ #ifdef __ELF__ -# define MULTIBOOT_HEADER_FLAGS 0x00000003 +# define MULTIBOOT_HEADER_FLAGS 0x00000007 #else -# define MULTIBOOT_HEADER_FLAGS 0x00010003 +# define MULTIBOOT_HEADER_FLAGS 0x00010007 #endif .text @@ -64,7 +64,17 @@ multiboot_header: .long _end /* entry_addr */ .long multiboot_entry -#endif /* ! __ELF__ */ +#else /* ! __ELF__ */ + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 +#endif /* __ELF__ */ + .long 0 + .long 1024 + .long 768 + .long 32 multiboot_entry: /* Initialize the stack pointer. */ diff --git a/doc/kernel.c b/doc/kernel.c index 2aceff028..598046264 100644 --- a/doc/kernel.c +++ b/doc/kernel.c @@ -150,6 +150,87 @@ cmain (unsigned long magic, unsigned long addr) mmap->len & 0xffffffff, (unsigned) mmap->type); } + + /* Draw diagonal blue line. */ + if (CHECK_FLAG (mbi->flags, 12)) + { + multiboot_uint32_t color; + unsigned i; + void *fb = (void *) (unsigned long) mbi->framebuffer_addr; + + switch (mbi->framebuffer_type) + { + case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED: + { + unsigned best_distance, distance; + struct multiboot_color *palette; + + palette = (struct multiboot_color *) mbi->framebuffer_palette_addr; + + color = 0; + best_distance = 4*256*256; + + for (i = 0; i < mbi->framebuffer_palette_num_colors; i++) + { + distance = (0xff - palette[i].blue) * (0xff - palette[i].blue) + + palette[i].red * palette[i].red + + palette[i].green * palette[i].green; + if (distance < best_distance) + { + color = i; + best_distance = distance; + } + } + } + break; + + case MULTIBOOT_FRAMEBUFFER_TYPE_RGB: + color = ((1 << mbi->framebuffer_blue_mask_size) - 1) + << mbi->framebuffer_blue_field_position; + break; + + default: + color = 0xffffffff; + break; + } + for (i = 0; i < mbi->framebuffer_width + && i < mbi->framebuffer_height; i++) + { + switch (mbi->framebuffer_bpp) + { + case 8: + { + multiboot_uint8_t *pixel = fb + mbi->framebuffer_pitch * i + i; + *pixel = color; + } + break; + case 15: + case 16: + { + multiboot_uint16_t *pixel + = fb + mbi->framebuffer_pitch * i + 2 * i; + *pixel = color; + } + break; + case 24: + { + multiboot_uint32_t *pixel + = fb + mbi->framebuffer_pitch * i + 3 * i; + *pixel = (color & 0xffffff) | (*pixel & 0xff000000); + } + break; + + case 32: + { + multiboot_uint32_t *pixel + = fb + mbi->framebuffer_pitch * i + 4 * i; + *pixel = color; + } + break; + } + } + } + } /* Clear the screen and initialize VIDEO, XPOS and YPOS. */ diff --git a/doc/multiboot.h b/doc/multiboot.h index 587f50832..e48d45b84 100644 --- a/doc/multiboot.h +++ b/doc/multiboot.h @@ -32,7 +32,7 @@ #define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 /* The bits in the required part of flags field we don't support. */ -#define MULTIBOOT_UNSUPPORTED 0x0000fffc +#define MULTIBOOT_UNSUPPORTED 0x0000fff8 /* Alignment of multiboot modules. */ #define MULTIBOOT_MOD_ALIGN 0x00001000 @@ -88,10 +88,12 @@ #define MULTIBOOT_INFO_APM_TABLE 0x00000400 /* Is there video information? */ -#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 #ifndef ASM_FILE +typedef unsigned char multiboot_uint8_t; typedef unsigned short multiboot_uint16_t; typedef unsigned int multiboot_uint32_t; typedef unsigned long long multiboot_uint64_t; @@ -190,9 +192,43 @@ struct multiboot_info multiboot_uint16_t vbe_interface_seg; multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; }; typedef struct multiboot_info multiboot_info_t; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 + struct multiboot_mmap_entry { multiboot_uint32_t size; diff --git a/doc/multiboot.texi b/doc/multiboot.texi index e4bf66e4b..64059dd56 100644 --- a/doc/multiboot.texi +++ b/doc/multiboot.texi @@ -638,6 +638,15 @@ follows: 84 | vbe_interface_off | 86 | vbe_interface_len | +-------------------+ +88 | framebuffer_addr | (present if flags[12] is set) +96 | framebuffer_pitch | +100 | framebuffer_width | +104 | framebuffer_height| +108 | framebuffer_bpp | +109 | framebuffer_type | +110-115 | color_info | + +-------------------+ + @end group @end example @@ -914,63 +923,15 @@ bytes, and the others are 2 bytes. See @uref{http://www.microsoft.com/hwdev/busbios/amp_12.htm, Advanced Power Management (APM) BIOS Interface Specification}, for more information. -If bit 11 in the @samp{flags} is set, the graphics table is available. +If bit 11 in the @samp{flags} is set, the @sc{vbe} table is available. The fields @samp{vbe_control_info} and @samp{vbe_mode_info} contain the physical addresses of @sc{vbe} control information returned by the @sc{vbe} Function 00h and @sc{vbe} mode information returned by the -@sc{vbe} Function 01h, respectively. In case of non-@sc{vbe} video driver -@samp{vbe_control_info} contains zero and @samp{vbe_mode_info} points to the -following 256-byte structure: - -@example -@group - +----------------------+ -0 | flags | -2 | zeros | -16 | pitch | -18 | width | -20 | height | -22 | zeros | -25 | bits per pixel | -26 | zeros | -27 | memory model | -28 | zeros | -31 | red mask size | -32 | red field position | -33 | green mask size | -34 | green field position | -35 | blue mask size | -36 | blue field position | -37 | alpha mask size | -38 | alpha field position | -39 | zero | -40 | framebuffer address | -44 | zero | -50 | pitch | -52 | zero | -54 | red mask size | -55 | red field position | -56 | green mask size | -57 | green field position | -58 | blue mask size | -59 | blue field position | -60 | alpha mask size | -61 | alpha field position | -62 | zeros | - +----------------------+ -@end group -@end example - -All fields have the same meaning as the corresponding VBE mode info -structure except fields marked as zeros which are zero-filled. - -If video is a linear framebuffer boot loader has to ensure that -displayed region starts at offset @samp{0} of linear framebuffer. +@sc{vbe} Function 01h, respectively. The field @samp{vbe_mode} indicates current video mode in the format -specified in @sc{vbe} 3.0. In case of non-@sc{vbe} video driver -@samp{vbe_mode} contains 0xffff. +specified in @sc{vbe} 3.0. The rest fields @samp{vbe_interface_seg}, @samp{vbe_interface_off}, and @samp{vbe_interface_len} contain the table of a protected mode interface @@ -984,6 +945,42 @@ The fields for the graphics table are designed for @sc{vbe}, but Multiboot boot loaders may simulate @sc{vbe} on non-@sc{vbe} modes, as if they were @sc{vbe} modes. +If bit 12 in the @samp{flags} is set, the @sc{Framebuffer} table is available. + +The field @samp{framebuffer_addr} contains framebuffer physical address. This field is 64-bit wide but bootloader @dfn{should} set it under 4GiB if possible for compatibility with payloads which aren't aware of PAE or amd64. The field @samp{framebuffer_pitch} contains pitch in bytes. The fields @samp{framebuffer_width}, @samp{framebuffer_height} contain framebuffer dimensions in pixels. The field @samp{framebuffer_bpp} contains number of bits per pixel. If @samp{framebuffer_type} is set to 0 it means indexed color. In this case color_info is defined as following: +@example +@group + +----------------------------------+ +110 | framebuffer_palette_addr | +114 | framebuffer_palette_num_colors | + +----------------------------------+ +@end group +@end example +@samp{framebuffer_palette_addr} contains address of array of @samp{framebuffer_palette_num_colors} following structures: +@example +@group + +-------------+ +0 | red_value | +1 | green_value | +2 | blue_value | + +-------------+ +@end group +@end example +If @samp{framebuffer_type} is set to 1 it direct RGB color. Then color_type is defined as following: + +@example +@group + +----------------------------------+ +110 | framebuffer_red_field_position | +111 | framebuffer_red_mask_size | +112 | framebuffer_green_field_position | +113 | framebuffer_green_mask_size | +114 | framebuffer_blue_field_position | +115 | framebuffer_blue_mask_size | + +----------------------------------+ +@end group +@end example +All further values of @samp{framebuffer_type} are reserved for future expansion @node Examples @chapter Examples -- 2.47.2