I have been trying to mess around in x86 real mode to sort of get a feel for things and try some things out. However, I have been having issues getting a pointer to the VGA Shared Memory Buffer to work properly. When I cast 0xB8000 to a u8 mutable pointer, any changes I make seem to be ignored regardless of whether I'm using core::ptr::write_volatile or the volatile crate. It works fine when I manually find the memory address via printing out 6 characters and finding the repeats, but not when I input it by hand. This is despite several tests showing the both point to the same location. So, I'm decently sure it's a compiler optimization issue, but I"m not sure how to make it stop.
#Issues accessing the VGA Buffer in x86 real mode
7 messages · Page 1 of 1 (latest)
const VRAM: u32 = 0xB8000;
#[link_section = ".startup"]
#[no_mangle]
fn stage_2() {
//print out characters to look for
print_char(b'D');
print_char(b'D');
print_char(b'D');
print_char(b'D');
print_char(b'D');
print_char(b'D');
//find repeated addresses
let mut in_row = 0;
let mut start_addr = 0;
for i in 0..0x000BFFFF {
let val = unsafe { *((i*2) as *const u8)};
if val == b'D' {
in_row += 1;
if in_row == 1 {
start_addr = i*2;
} else if in_row == 6 {
//print address found
print_number(start_addr);
break;
}
} else {
in_row = 0;
}
}
//print VRAM address programmed in
print_number(VRAM);
unsafe {
//check if you can change the runtime found address
core::ptr::write_volatile((start_addr+2) as *mut u8, b'j');
}
unsafe {
//check if you can change it based on vram
core::ptr::write_volatile(VRAM as *mut u8, b'h');
}
//check if they are equal to eachother on several levels
if VRAM == start_addr {
print_number(10);
} else {
print_number(20);
}
if VRAM as *mut u8 == start_addr as *mut u8 {
print_number(10);
} else {
print_number(20);
}
let a = unsafe { *(VRAM as *mut u8)};
let b = unsafe { *(start_addr as *mut u8)};
if a == b {
print_number(10);
} else {
print_number(20);
}
}```
Is the expected behaviour to output the text hDjDDDD? (as in prepend the h to the existing buffer and push everything along?)
I don't know anything about this mode, but start_addr + 2 seems to be referring to the second character in the string (D gets transformed to j)
start_addr there (or VRAM) would be before the first character, so it depends on if this can handle that case
Does it work if you update the existing first character by using (I assume)
unsafe {
//check if you can change it based on vram
core::ptr::write_volatile((VRAM + 1) as *mut u8, b'h');
}
in the VGA buffer, each character is 2 bytes, the first byte being the ASCII character and the second being color information. The intended behavior is for the first character to become h from the VRAM write and the second character to become j from the start_addr write. However, only the start_addr (the pointer made at runtime) seems to work.
So the expected behavior is hjDDDD
representation of char:
#[repr(C)]
struct ScreenCharacter {
ascii_character: u8,
color_code: u8,
}```