这一次想用C++来写一个操作系统,不过看起来没那么容易。

本文详细介绍了snailOS操作系统的引导加载过程及内核初始化代码。使用Multiboot2规范与GRUB引导加载器进行系统引导,通过汇编语言设置CPU寄存器并跳转到内核入口点。C++实现的内核部分负责初始化视频缓冲区,绘制图形界面,包括填充颜色和创建动态方格图案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#boot.s
MULTIBOOT2_HEADER_MAGIC = 0xe85250d6
GRUB_MULTIBOOT_ARCHITECTURE_I386 = 0x0
MULTIBOOT_HEADER_TAG_ADDRESS = 0x2
MULTIBOOT_HEADER_TAG_OPTIONAL = 0x1
MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS = 0x3
MULTIBOOT_HEADER_TAG_END = 0x0
MULTIBOOT_HEADER_TAG_FRAMEBUFFER = 0x5

.globl _start
.extern _mymain

_start:
	jmp multiboot_entry
.align 8

multiboot_header:
	.int MULTIBOOT2_HEADER_MAGIC
	.int GRUB_MULTIBOOT_ARCHITECTURE_I386
	.int multiboot_header_end - multiboot_header
	.int -(MULTIBOOT2_HEADER_MAGIC + GRUB_MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))

.align 8
	
address_tag_start:
	.short MULTIBOOT_HEADER_TAG_ADDRESS
	.short MULTIBOOT_HEADER_TAG_OPTIONAL
	.int address_tag_end - address_tag_start
	.int multiboot_header
	.int _start
	.int 0x0
	.int 0x0
address_tag_end:

.align 8

entry_address_tag_start:
	.short MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS
	.short MULTIBOOT_HEADER_TAG_OPTIONAL
	.int entry_address_tag_end - entry_address_tag_start
	.int multiboot_entry
entry_address_tag_end:

.align 8

framebuffer_tag_start:
	.short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
	.short MULTIBOOT_HEADER_TAG_OPTIONAL
	.int framebuffer_tag_end - framebuffer_tag_start
	.int 1024
	.int 768
	.int 32
framebuffer_tag_end:

.align 8

undefined_tag:
	.short MULTIBOOT_HEADER_TAG_END
	.short 0
	.int 8
	
multiboot_header_end:
.align 8
multiboot_entry:
	movl $stack, %esp
	pushl $0
	popf
	
	pushl %ebx
	pushl %eax
	
	call _mymain
	
1:
	hlt
	jmp 1b

.align 0x1000
.fill 0x1000, 1, 0
stack:
//kernel.cpp
extern "C" {
	namespace snailOS {
		class Paint{
		public:
//			Paint(int* fb){
//				this->fb = fb;
//			}
			static void fillbox(int* fb, int xsize, int color, int x0, int y0, int x1, int y1) {
				int x, y;
				for (y = 0; y <= y1 - y0; y++) {
					for (x = 0; x <= x1 - x0; x++) {
						fb[x0 + x + (y0 + y) * xsize] = color;
					}
				}
			}
		private:
		};

	}

	int* const myfb = (int*) 0xe0000000;

	void fillbox(int xsize, int color, int x0, int y0, int x1, int y1) {
		int x, y;
		for (y = 0; y <= y1 - y0; y++) {
			for (x = 0; x <= x1 - x0; x++) {
				myfb[x0 + x + (y0 + y) * xsize] = color;
			}
		}
	}

	int mymain(int eax, int ebx) {
	/*
		char* videoaddr = (char*)0xb8000;
		*videoaddr = 'H';
		*(videoaddr + 1) = 0x9;
		*(videoaddr + 2) = 'e';
		*(videoaddr + 3) = 0x9;
		*(videoaddr + 4) = 'l';
		*(videoaddr + 5) = 0x9;
		*(videoaddr + 6) = 'l';
		*(videoaddr + 7) = 0x9;
		*(videoaddr + 8) = 'o';
		*(videoaddr + 9) = 0x9;
	*/
//		fillbox(1024, 0x1e90ff, 0, 0, 1024 - 1, 768 - 1);
//		fillbox(1024, 0x0, 201, 201, 300, 300);
//		fillbox(1024, 0xffffff, 301, 301, 400, 400);
		using namespace snailOS;
//		Paint p((int*)0xe0000000);
//		p.fillbox(1024, 0x1e90ff, 0, 0, 1024 - 1, 768 - 1);
		Paint::fillbox((int*)0xe0000000, 1024, 0x1e90ff, 0, 0, 1024 - 1, 768 - 1);
		for(int i = 0; i < 32; i++){
			Paint::fillbox((int*)0xe0000000, 1024, 0xffffffff, i * 20, i * 20, i * 20 + 20 - 1, i * 20 + 20 - 1);
		}
		
		while(1) {
			asm("hlt"::);
		}
	}

}
#Makefile
AS = as
C = g++
CF = -c
LD = ld
LDF = -Ttext 0x100000
OBJ = boot.o kernel.o

default: $(OBJ)
	make boot.o
	make kernel.o

boot.o: boot.s
	$(AS) -o $@ $<
	
kernel.o: kernel.cpp
	$(C) $(CF) -o $@ $<
	
kernel:	$(OBJ)
	$(LD) $(LDF) -o kernel $(OBJ)
	objcopy -I pe-i386 -O elf32-i386 kernel
	mount.cmd
  
run: kernel
	make default
	start virtualbox --startvm "C:\Users\Administrator\VirtualBox VMs\snailOS\snailOS.vbox" 

clean:
	del *.o
	del kernel

	
	

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_39410618

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值