I am trying to develop a proof-of-concept os. Howsoever in the process one of the problems I encounter is the vesa video modes. It seems there is a lack of hardcoded video modes numbers after vesa told us to get them from vbe bios information and find the one that fits our needs. However I am unable to receive the video modes as I don't know how to use vbeFarPtr
from C kernel in 32 bit
Here is my kernel code:
I passed a VbeInfoBlock
as a parameter to the kernel from my second stage bootloader after receiving the information with int 0x10 ax=0x4f00
int kmain(struct VbeInfoBlock *vbeinfo)
{
init_idt();
SetPITSpeed(100);
init_DTCursor();
printf(vbeinfo->signature); // I can print VESA here means I have the vbeinfoblock
char* str = "";
itoa(vbeinfo->video_modes,str,16); // I want a hex dump so I convert it to hex
printf(str); // I get "VESA" for the signature followed by a string "1053" and nothing else while the list should be like this
// If for example video mode 0x0103, 0x0118 and 0x0115 are supported
// The list should be as 03 01 15 01 18 01 FF FF
// So I should atleast get some FF FF
// My output is "VESA 1053"
while(1);
}
The VbeInfoBlock is defined a follows if you dont know
struct VbeInfoBlock
{
char signature[4]; // must be "VESA" to indicate valid VBE support
uint16_t version; // VBE version; high byte is major version, low byte is minor version
uint32_t oem; // segment:offset pointer to OEM
uint32_t capabilities; // bitfield that describes card capabilities
uint32_t video_modes; // segment:offset pointer to list of supported video modes
uint16_t video_memory; // amount of video memory in 64KB blocks
uint16_t software_rev; // software revision
uint32_t vendor; // segment:offset to card vendor string
uint32_t product_name; // segment:offset to card model name
uint32_t product_rev; // segment:offset pointer to product revision
char reserved[222]; // reserved for future expansion
char oem_data[256]; // OEM BIOSes store their strings in this area
} __attribute__ ((packed));
I couldn't understand the problem. Are there any other way of doing it? Or is my way correct but my code is incorrect?
I think the problem is that video_modes part in VbeInfoBlock
is defined as a segment:offset pair. I don't know how to use it in 32 bit C code.
(You can request my second stage bootloader or my original bootloader but for this problem I think it is unnecessary)
EDIT:
The code I tried after Brendan's answer
uint32_t physical_address = (vbeinfo->video_modes_segment << 4) + vbeinfo->video_modes_offset;
uint16_t *videoListPointer = (uint16_t *)physical_address;
char chr = '\0';
while(*videoListPointer != 0xffff) {
itoa(*videoListPointer,chr,16);
printf(chr);
videoListPointer++;
}
and my gdt
gdt_start :
gdt_null : ; the mandatory null descriptor
dd 0x0 ; 'dd ' means define double word ( i.e. 4 bytes )
dd 0x0
gdt_code :
dw 0xffff ; Limit ( bits 0 -15)
dw 0x0 ; Base ( bits 0 -15)
db 0x0 ; Base ( bits 16 -23)
db 10011010b ; 1st flags , type flags
db 11001111b ; 2nd flags , Limit ( bits 16 -19)
db 0x0 ; Base ( bits 24 -31)
gdt_data :
dw 0xffff ; Limit ( bits 0 -15)
dw 0x0 ; Base ( bits 0 -15)
db 0x0 ; Base ( bits 16 -23)
db 10010010b ; 1st flags , type flags
db 11001111b ; 2nd flags , Limit ( bits 16 -19)
db 0x0 ; Base ( bits 24 -31)
gdt_end :
gdt_descriptor :
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
Edit 2:
Image
Edit 3:
Code I used:
int kmain(struct VbeInfoBlock *vbeinfo)
{
init_idt();
SetPITSpeed(100);
init_DTCursor();
uint32_t physical_address = (vbeinfo->video_modes_segment << 4) + vbeinfo->video_modes_offset;
uint16_t *videoListPointer = (uint16_t *)physical_address;
char chr[9];
while(*videoListPointer != 0xffff) {
//itoa(*videoListPointer, chr,16);
printf(*videoListPointer);
videoListPointer++;
}
while(1);
}
and screenshot of my output without itoa
Edit4:
gcc -v
C:\Users\Asus>gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=D:/MinGW/mingw32/bin/../libexec/gcc/i686-w64-mingw32/8.1.0/lto-wrapper.exe Target: i686-w64-mingw32 Configured with: ../../../src/gcc-8.1.0/configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-sjlj-exceptions --with-dwarf2 --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=i686 --with-tune=generic --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-pkgversion='i686-win32-dwarf-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/lib -L/c/mingw810/prerequisites/i686-zlib-static/lib -L/c/mingw810/prerequisites/i686-w64-mingw32-static/lib -Wl,--large-address-aware' Thread model: win32 gcc version 8.1.0 (i686-win32-dwarf-rev0, Built by MinGW-W64 project)
Edit5:
str
. Right now, it's just pointing to a location in the data section. Try usingchar str[9];
. You should probably also useprintf("%4s", vbeinfo->signature);
to print the signature. – S.S. Anne