操作系统第一课程实验内核代码解析

完成第一次操作系统实验,使用rust语言构造最小核并最终输出字符串hello world
下面是我们使用的内核代码的一部分,其余部分都是一些相关的设置,使用了rust语句逻辑的部分主要在_start函数中,代码如下:

static HELLO: &[u8] = b"Hello World!";

#[no_mangle]
pub extern "C" fn _start() -> ! {
    
    
    let vga_buffer = 0xb8000 as *mut u8;

    for (i, &byte) in HELLO.iter().enumerate() {
    
    
        unsafe {
    
    
            *vga_buffer.offset(i as isize * 2) = byte;
            *vga_buffer.offset(i as isize * 2 + 1) = 0xb;
        }
    }

    loop {
    
    }
}

解析部分

static HELLO: &[u8] = b"Hello World!"

这里的意思很简单就是声明一个静态的字符串字符串前面的b表示一个字节byte,&[u8]表示的是一个去切片,这里我的理解是将字符串切成一个字节为单位的片,方便后续的迭代

let vga_buffer = 0xb8000 as *mut u8;

这里使用了let关键字
let关键字的用法是用来绑定变量的这里u8前面使用mut表示这是一个可变变量,let的用法很多而这里表示的就是将显存的地址绑定到vga_buffer变量上

for (i, &byte) in HELLO.iter().enumerate() {
    
    
        unsafe {
    
    
            *vga_buffer.offset(i as isize * 2) = byte;
            *vga_buffer.offset(i as isize * 2 + 1) = 0xb;
        }
    }

for 循环部分是类似于python的形式,(i,&byte)会迭代HELLO.iter().enumerate()中的内容,其中i就表示其中元素的序号,byte表示其中的内容,这里就指HELLO字符串中的内容,然后接下来的unsafe就是表示接下来的操作因为涉及到裸指针可能会指向不该指的地方,但这里我们自己表示这个操作虽然会有风险但我们还是要运行,不过编译器照样会检查是否安全。

*vga_buffer.offset(i as isize * 2) = byte;
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;

最后是这两个语句,因为我们要写入数据的所谓的“显存”其实是VGA字符缓冲区(VGA text buffer):这是一段映射到VGA硬件的特殊内存片段,包含着显示在屏幕上的内容。通常情况下,它能够存储25行、80列共2000个字符单元(character cell);每个字符单元能够显示一个ASCII字符,也能设置这个字符的前景色,和背景色
所以说这里每一个字符单位都需要写入两个字节,一个表示要显示的内容,另一个则是显示的颜色,都是一个字节。
这里的offset(i as isize * 2)表示指针的偏移,as在rust中一般表示数据类型的转换,所以这里的意思是表示指针偏移2i位,因为每个字符单元有两个字节,所以这里的含义就是将第i个字符变量传入字符缓冲区的第2i个字节,将颜色信息存入字符缓冲区2*i+1,byte则是HELLO字符串中的迭代信息,即每一位字节,这里i则是每个迭代信息的序号即0.1.2…

Guess you like

Origin blog.csdn.net/qq_49327751/article/details/121323644