snail_os 0.01 虽然没有完成,但是也要分享一下

33 篇文章 0 订阅
12 篇文章 0 订阅
本文档详细介绍了Bochs虚拟机的配置文件bochsrc.txt,包括内存设置、硬盘映射、启动设备选择等。同时,展示了x86汇编语言代码,用于初始化内存管理和显示输出。代码中包含内存页表的创建、8259中断控制器的初始化以及RTC中断处理程序。此外,还展示了如何读取BIOS信息并进行输出。
摘要由CSDN通过智能技术生成

###############################################################
# bochsrc.txt file for DLX Linux disk image.
###############################################################

# how much memory the emulated machine will have
megs: 1024

# filename of ROM images
romimage: file=./BIOS-bochs-latest
vgaromimage: file=./VGABIOS-lgpl-latest

# what disk images will be used 
floppya: 1_44=a.img, status=inserted
floppyb: 1_44=floppyb.img, status=inserted

# hard disk
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="c.img", cylinders=60, heads=16, spt=63

# choose the boot disk.
boot: c #floppy

# default config interface is textconfig.
#config_interface: textconfig
#config_interface: wx

#display_library: x
# other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga

# where do we send log messages?
# log: bochsout.txt

# disable the mouse, since DLX is text only
mouse: enabled=0

# set up IPS value and clock sync
cpu: ips=15000000
clock: sync=both

# enable key mapping, using US layout as default.
#
# NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows.
# However, the key mapping tables are used in the paste function, so 
# in the DLX Linux example I'm enabling keyboard_mapping so that paste 
# will work.  Cut&Paste is currently implemented on win32 and X windows only.

keyboard: keymap=./x11-pc-us.map
#keyboard: keymap=../keymaps/x11-pc-fr.map
#keyboard: keymap=../keymaps/x11-pc-de.map
#keyboard: keymap=../keymaps/x11-pc-es.map
; boot.asm

bits 16

start16:
	mov ax, 0x7c0
	mov ds, ax
	mov ss, ax
	mov sp, 0
	
	mov ax, 0xb800
	mov es, ax
	xor bx, bx
	mov byte [es:bx], 'R'
	inc bx
	mov byte [es:bx], 0xc
	inc bx

	
	mov al, 18
	mov dx, 0x1f2
	out dx, al

	mov al, 1
	mov dx, 0x1f3
	out dx, al
	mov al, 0
	mov dx, 0x1f4
	out dx, al
	mov al, 0
	mov dx, 0x1f5
	out dx, al
	mov al, 1110_0000b
	mov dx, 0x1f6
	out dx, al

	mov al, 0x20
	mov dx, 0x1f7
	out dx, al

	mov dx, 0x1f7
.1:
	in al, dx
	and al, 1000_1000b
	cmp al, 0000_1000b
	jne .1

	mov cx, 20 * 256
	mov bx, 0x200
	mov dx, 0x1f0
.2:
	in ax, dx
	mov [bx], ax
	inc bx
	inc bx
	loop .2



	mov ax, 0x7c0
	mov ds, ax
	mov ax, 0x50
	mov es, ax

	mov dword [0], 0
	xor ebx, ebx
	mov edx, 'PAMS'
	mov di, 0
.4:
	mov eax, 0xe820
	mov ecx, 20
	int 0x15
	jc .5
	add di, cx
	inc dword [0]
	cmp ebx, 0
	jnz .4
	jmp .6
.5:
	jmp $
.6:

	cli
	mov ax, 0x7c0
	mov ds, ax
	mov es, ax
	
	lgdt [gdtr]
	mov eax, cr0
	or eax, 0000_0000_0000_0000_0000_0000_0000_0001b
	mov cr0, eax
	
	mov ax, 1 * 8
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov ss, ax
	mov esp, 36 * 512
	
	mov ax, 3 * 8
	mov gs, ax
	
	jmp dword 2 * 8: 0
	

	
gdtr:
	dw gdt_end - gdt_begin - 1
	dd gdt_begin + 0x7c00
	
gdt_begin:
	dq 0x0000_0000_0000_0000 ; 0 * 8
	dq 0x00cf_9200_7e00_07ff ; 1 * 8
	dq 0x00cf_9a00_7e00_07ff ; 2 * 8
	dq 0x00cf_920b_8000_1000 ; 3 * 8
	dq 0x00cf_9200_0000_ffff ; 4 * 8
gdt_end:
	
times 512 - 2 - ($ - $$) db 0
dw 0xaa55
	

kauto.cmd

nasm -fbin -o boot.bin boot.asm
nasm -fbin -o loader.bin loader.asm
ld -Ttext 0xc0101000 -o kernel.pe kernel.o lib.o
objcopy -I pe-i386 -O elf32-i386 kernel.pe
move kernel.pe kernel.elf32

kbulid.cmd

dd if=boot.bin of=c.img seek=0 count=1
dd if=loader.bin of=c.img seek=1 count=18
dd if=kernel.elf32 of=c.img seek=19 count=2048
// kernel.c

typedef struct ards {
	int baseAddrLow;
	int baseAddrHigh;
	int lengthLow;
	int lengthHigh;
	short type;
}ards;

unsigned int* page_table_point;

unsigned int pos = 0;

struct crt_data {
	char data[3];
};

struct crt_data crt_data = {0, 0, 0};

typedef enum {
	false = 0, true = 1
}bool;

#define out(port, data) asm volatile ("out %w1, %b0;"::"a"(data), "d"(port))
#define in(port) ({\
	unsigned char _res;\
	asm volatile("in %b1, %w2":"=a"(_res):"0"(_res), "d"(port));\
	_res;\
})

#define bcd2bin(data) ((data) = (((data)&0xf) + (((data)>>4)*10)))
#define sti() asm volatile ("sti");
#define cli() asm volatile ("cli");

void general(void);
void page_error(void);
void init_page(void);
void rtc_interrupt(void);
void init_8259(void);
void init_rtc(void);
void put_char(char c);
void put_s(char* s);
char* kprintf(char* s, ...);
char* itoa(unsigned int i,unsigned  int n);
unsigned int strlen(char* s);
unsigned int div(unsigned int* i,unsigned  int n);
void cls(void);
void getArdsCount(void);
void put_s_pos(char* s, unsigned int pos, unsigned int colour);
void load_sector(int start_sector, int sector_number, int start_memory);
void create_descriptor(int descriptor_table_address, 
		int selector, int base_address, int limit, int attrib);
void create_gate(int descriptor_table_address,
		int number, int attrib, int selector, int offset);
void exception(void);		
void panic_snail(const char* filename, const char* func, int line, const char* exp);

#define assert_snail(exp) if(!(exp)) panic_snail(__FILE__, __func__, __LINE__, #exp); \
					else ;
					
unsigned int get_max(unsigned int* array, unsigned int length);


bool bit_match(unsigned int* v32, unsigned int p);
unsigned int map_search_block(unsigned int* v32, unsigned int map_l, 
	unsigned int block_l);
void set_0(unsigned int* v32, unsigned int p);
void set_1(unsigned int* v32, unsigned int p);

int mapOnePage(unsigned int virAddr, unsigned int phyAddr, unsigned int pageAttrib);

void kernel_entry(void) {
	cls();	
	init_page();
	int i;
	for(i = 0; i < 32; i++) {
		create_gate(0x1000 + 0xc0000000, i, 2 * 8, 0x8e00, (int)exception);		
	}
	
//	put_s(kprintf("Hello, World!\n"));
	
//	while(1);

	create_gate(0x1000 + 0xc0000000, 13, 2 * 8, 0x8e00, (int)general);
	create_gate(0x1000 + 0xc0000000, 14, 2 * 8, 0x8e00, (int)page_error);	
	create_gate(0x1000 + 0xc0000000, 0x28, 2 * 8, 0x8e00, (int)rtc_interrupt);	
	ards* pArds = (ards*)(0x500 + 0xc0000000);
	int array[64] ;
	int* parray = (void*)(0);
	for(i = 0; i < *((int*)(0x7c00 + 0xc0000000)); i++, pArds++) {
		put_s(kprintf("baseAddrLow = %x lengthLow = %x type = %d \n", 
		pArds->baseAddrLow, pArds->lengthLow, pArds->type));
		array[i] = pArds->lengthLow;
	}
	
//	put_s(kprintf("\n%dM\n", get_max(parray, *((int*)(0x7c00 + 0xc0000000))  ) /1024/1024));

	asm volatile ("mov word ptr [0x7c04 + 0xc0000000], 256 * 8 - 1;\
		mov dword ptr [0x7c06 + 0xc0000000], 0x1000 + 0xc0000000;\
		lidt [0x7c04 + 0xc0000000];\
	");
	
	init_8259();
	init_rtc();
	
	out(0x21, 0xfb);
	out(0xa1, 0xfe);

//	while(1) {}

	
	sti();

//	assert_snail( i > 256);

	unsigned int t[100];
	
	t[0] = 0xffff0000;
	
	put_s(kprintf("@@@ %d @@@", bit_match(t, 16)));
	set_1(t, 1);
	set_1(t, 2);
	set_1(t, 3);
	put_s(kprintf("\n %b \n", t[0]));
	put_s(kprintf("\n %b \n", t[1]));
	put_s(kprintf("\n %d \n", map_search_block(t, 100 * 32, 17)));	
	put_s(kprintf("\n %d \n", map_search_block(t, 100 * 32, 10)));	
	
	mapOnePage(0x100000, 0xc00000, 0x7);
	
	int data[3];	
	while(1) {
		data[0] = crt_data.data[0];
		data[1] = crt_data.data[1];
		data[2] = crt_data.data[2];	
		if(data[0] < 10) {
			put_s_pos("0", 0 * 80 * 2 + 140, 0xc);
			put_s_pos(kprintf("%d", bcd2bin(data[0])), 0 * 80 * 2 + 142, 0xc);				
		} else {
			put_s_pos(kprintf("%d", bcd2bin(data[0])), 0 * 80 * 2 + 140, 0xc);					
		}
		put_s_pos(":", 0 * 80 * 2 + 144, 0xc);
		if(data[1] < 10) {
			put_s_pos("0", 0 * 80 * 2 + 146, 0xc);
			put_s_pos(kprintf("%d", bcd2bin(data[1])), 0 * 80 * 2 + 148, 0xc);				
		} else {
			put_s_pos(kprintf("%d", bcd2bin(data[1])), 0 * 80 * 2 + 146, 0xc);					
		}
		put_s_pos(":", 0 * 80 * 2 + 150, 0xc);
		if(data[2] < 10) {
			put_s_pos("0", 0 * 80 * 2 + 152, 0xc);
			put_s_pos(kprintf("%d", bcd2bin(data[2])), 0 * 80 * 2 + 154, 0xc);				
		} else {
			put_s_pos(kprintf("%d", bcd2bin(data[2])), 0 * 80 * 2 + 152, 0xc);					
		}
		asm volatile ("hlt");
	}
}

void init_8259(void) {
	out(0x20, 0x11);
	out(0xa0, 0x11);
	out(0x21, 0x20);
	out(0xa1, 0x28);
	out(0x21, 0x4);
	out(0xa1, 0x2);
	out(0x21, 0x1);
	out(0xa1, 0x1);
	out(0x21, 0xff);
	out(0xa1, 0xff);
}


void put_char(char c) {
	if(pos >= 4000){
		pos = 0;
	}
	if(c == '\n') {
		pos = (pos / (2 * 80) + 1) * 2 * 80;
		return;
	}
	asm volatile ("mov ebx, %0;\
	mov byte ptr gs:[ebx], %b1; \
	inc ebx; \
	mov byte ptr gs:[ebx], 0xf; \
	inc ebx; \
	mov %0, ebx "::"m"(pos), "a"(c));
}

void put_s(char* s) {
	while(*s) {
		put_char(*s);
		s++;
	}
}

char* kprintf(char* s, ...) {
	static char buf[0x400];
	char buf1[0x40];
	char* pbuf = buf;
	void** args = (void**)&s;
	args++;
	char* p, *q = buf1;
	unsigned int i, l;
	while(*s) {
		if(*s == '%'){
			s++;
			switch(*s) {
			case '%':
				s++;
				break;
			case 's':
			case 'S':
				s++;
				p = (char*)*args++;
				while(*p) {
					*pbuf++ = *p++;
				}
				break;
			case 'c':
			case 'C':
				s++;
				i = (int)*args++;
				*pbuf++ = i;
				break;
			case 'b':
			case 'B':
				s++;
				i = (int)*args++;
				p = itoa(i, 2);
				q = buf1;
				l = 32 - strlen(p);
				for(i = 0;i < l; i++) {
					*q++ = '0';
				}
				while(*p) {
					*q++ = *p++;
				}
				*q = '\0';
				q = buf1;
				i = 0;
				while(*q){
					if((i != 0) && (i % 4 == 0)) {
						*pbuf++ = '_';
					}
					*pbuf++  = *q++;
					i++;
				}
				*pbuf++ = 'b';
				break;
			case 'd':
			case 'D':
				s++;
				i = (int)*args++;
				p = itoa(i, 10);
				while(*p){
					*pbuf++  = *p++;
				}
				break;
			case 'x':
			case 'X':
				s++;
				i = (int)*args++;
				p = itoa(i, 16);
				*pbuf++ = '0';
				*pbuf++ = 'x';
				l = 8 - strlen(p);
				q = buf1;
				for(i = 0;i < l; i++) {
					*q++ = '0';
				}
				while(*p) {
					*q++ = *p++;
				}
				*q = '\0';
				q = buf1;
				i = 0;
				while(*q){
					if((i != 0) && (i % 4 == 0)) {
						*pbuf++ = '_';
					}
					*pbuf++  = *q++;
					i++;
				}
				break;				
			default:
				break;
			}
		} else {
			*pbuf++ = *s++;
		}
	}
	*pbuf = '\0';
	return buf;
}

unsigned int div(unsigned int* i, unsigned int n) {
	unsigned int r = *i % n;
	*i /= n;
	return r;
}

unsigned int strlen(char* s) {
	unsigned int len = 0;
	while(*s) {
		len++;
		s++;
	}
	return len;
}

char* itoa(unsigned int i, unsigned int n) {
	char s[] = "0123456789abcdef";
	char buf0[0x20];
	char* pbuf = buf0;
	static char buf1[0x20];
	char* qbuf = buf1;
	int j;
	if(!i) {
		*qbuf++ = '0';
		*qbuf = '\0';
		return buf1;
	}
	while(i) {
		*pbuf++ = s[div(&i, n)];
	}
	*pbuf = '\0';
	for(j = strlen(buf0) - 1; j >= 0; j--) {
		*qbuf++ = *--pbuf;
	}
	*qbuf = '\0';
	return buf1;
}

void cls(void) {
	asm (".1: mov byte ptr gs:[ebx], ' '; \
	inc ebx;\
	mov byte ptr gs:[ebx], 0xf;\
	inc ebx;\
	loop .1 "\
	::"b"(0),"c"(2000));
//	while(1) {}
}

void getArdsCount(void) {
	asm volatile ("mov bx, 4 * 8; \
	mov ds, bx; \
	mov es, bx; \
	rep movsb; \
	mov eax, dword ptr[0x7c00]; \
	mov dword ptr[0x100000 + 0x400], eax; \
	mov bx, 1 * 8; \
	mov ds, bx;\
	mov es, bx" \
	::"c"(1024),"S"(0x7c00 + 512),"D"(0x100000) \
	);
}


void put_s_pos(char* s, unsigned int pos , unsigned int colour) {
	asm volatile ("\
		mov ah, cl;\
		w_loop: mov al, [%0];\
		or al, al;\
		jz exit;\
		mov gs:[%1], ax;\
		inc %1;\
		inc %1;\
		inc %0;\
		jmp w_loop;\
		exit: "\
	::"S"(s),"b"(pos),"c"(colour));
}

void exception(void) {
	put_s(kprintf("Exception...!"));
	while(1) {}
}

void init_rtc(void) {
	out(0x70, 0x8b);
	out(0x71, 0x12);
	out(0x70, 0xc);
	in(0x71);
}

void rtc_handler(void) {
	out(0x70, 4);
	crt_data.data[0] = in(0x71);
	out(0x70, 2);
	crt_data.data[1] = 	in(0x71);
	out(0x70, 0);
	crt_data.data[2] = 	in(0x71);
	out(0x70, 0xc);
	in(0x71);
}

void init_page(void) {
	int i;
	long* dir_table_base = (long*) (0x400000);
	long* page_table_base = (long*) (0x400000 + 0x1000);
	
/*	
	for(i = 0 ; i < 3; i++, dir_table_base++) {
		*dir_table_base = 0x400000 + 0x1000 + 0x7 + i * 0x1000;
	}	
	for(i = 0; i < 3 * 1024; i++, page_table_base++) {
		*page_table_base = 0x0 + 0x7 + i * 0x1000;
	}
*/		
	for(i = 0, dir_table_base += 0xc0000000 / 0x400000; i < 3; i++, dir_table_base++) {
		*dir_table_base = 0x400000 + 0x1000 + 0x100000 + 0x7 + i * 0x1000;		
	}
//	put_s(kprintf("  %x  ", page_table_base));
//	put_s(kprintf("  %x  ",--dir_table_base));
	page_table_base = (long*)(0x400000 + 0x1000 + 0x100000);
	for(i = 0; i < 3 * 1024; i++, page_table_base++) {
		*page_table_base = 0x0 + 0x7 + i * 0x1000;
	}

	dir_table_base = (long*) (0xc0400000);
	page_table_base = (long*) (0xc0400000 + 0x1000);
	for(i = 0 ; i < 3; i++, dir_table_base++) {
		*dir_table_base = 0x0;
	}

	for(i = 0; i < 3 * 1024; i++, page_table_base++) {
		*page_table_base = 0x0;
	}
	
	asm volatile ("\
		mov eax, 0x400000;\
		mov cr3, eax;\
		mov eax, cr0;\
		or eax, 0x80000000;\
		mov cr0, eax;\
		jmp 1f;\
		1:"\
	);
}

void general(void) {
	put_s(kprintf("General...!"));
	while(1) {}
}

void page_error(void) {
	put_s(kprintf("Page Error...!"));
	while(1) {}
}

void panic_snail(const char* filename, const char* func, int line, const char* exp) {
	cli();
	put_s(kprintf("System Error...!\n""FileName is [%s]\n", filename));	
	put_s(kprintf("Func is [%s]\n", func));
	put_s(kprintf("In [%d] Line\n", line));
	put_s(kprintf("Condition is [%s]\n", exp));
	while(1);
}

unsigned int get_max(unsigned int* array, unsigned int length) {
	assert_snail(array);
	int i;
	unsigned int t;
	for(i = 0, t = array[i]; i < length - 1; i++) {
		if(t < array[i + 1]) {
			t = array[i + 1];
		}
	}
	return t;
}

bool bit_match(unsigned int* v32, unsigned int p) {
	assert_snail(v32);
	return (v32[p / 32] & (1 << (p % 32)))?true:false;
}

unsigned int map_search_block(unsigned int* v32, unsigned int map_l, unsigned int block_l) {
	unsigned int i, c;
	for(i = 0; i < map_l; i++) {
		if(!(bit_match(v32, i))) {
			break;
		}
	}
	c = 0;
	while(i < map_l) {
		if(c == block_l) {
			break;
		} 
		if(!(bit_match(v32, i))) {
			c++;
		} else {
			c = 0;
		}
		i++;
	}
	return i - block_l;
}

void set_0(unsigned int* v32, unsigned int p) {
	if(bit_match(v32, p)) {
		v32[p / 32] &= ~(1 << (p % 32));
	}
}

void set_1(unsigned int* v32, unsigned int p) {
	if(!(bit_match(v32, p))) {
		v32[p / 32] |= 1 << (p % 32);
	}
}

int mapOnePage(unsigned int virAddr, unsigned int phyAddr, unsigned int pageAttrib) {
	unsigned int pageDirBase = 0xc0400000, pageTableBase = 0xc0400000 + 0x1000;
	*(unsigned int*)(pageDirBase + virAddr / 0x400000 * 4) = (0x400000 + 0x1000 + virAddr / 0x1000 * 4) + pageAttrib;
	*(unsigned int*)(pageTableBase + virAddr / 0x1000 * 4) = phyAddr + pageAttrib;
}


; lib.asm

global _create_gate, _load_sector, _create_descriptor

;	void load_sector(int start_sector, int sector_number, int start_memory)
;	mov dword [esp + 0 * 4], START_SECTOR
;	mov dword [esp + 1 * 4], SECTOR_NUMBER
;	mov dword [esp + 2 * 4], START_MEMORY
;	call load_sector
_load_sector:
	push ebp
	mov ebp, esp
	pusha

	mov esi, [ebp + 2 * 4]
	mov edi, [ebp + 3 * 4]
	mov ebx, [ebp + 4 * 4]

.3:
	mov al, 1
	mov dx, 0x1f2
	out dx, al
	
	mov eax, esi
	mov dx, 0x1f3
	out dx, al
	shr eax, 8
	mov dx, 0x1f4
	out dx, al
	shr eax, 8
	mov dx, 0x1f5
	out dx, al
	shr eax, 8
	and al, 0x0f
	or al, 1110_0000b
	mov dx, 0x1f6
	out dx, al
	
	mov al, 0x20
	mov dx, 0x1f7
	out dx, al
	
	mov dx, 0x1f7
.1:
	in al, dx
	and al, 1000_1000b
	cmp al, 0000_1000b
	jne .1

	mov ecx, 256
	mov dx, 0x1f0
.2:
	in ax, dx
	mov [ebx], ax
	inc ebx
	inc ebx
	loop .2

	inc esi
	dec edi
	cmp edi, 0
	jne .3

	popa
	leave
	ret

;	void create_descriptor(int descriptor_table_address, int selector, int base_address, int limit, int attrib)
;	mov dword [esp + 0 * 4], DESCRIPTOR_TABLE_ADDRESS
;	mov dword [esp + 1 * 4], SELECTOR
;	mov dword [esp + 2 * 4], BASE_ADDRESS
;	mov dword [esp + 3 * 4], LIMIT
;	mov dword [esp + 4 * 4], ATTRIB
;	call create_descriptor
_create_descriptor:
	push ebp
	mov ebp, esp
	pusha

	mov esi, [ebp + 2 * 4]
	mov edi, [ebp + 3 * 4]
	shl edi, 3
	add edi, esi
	mov ebx, [ebp + 4 * 4]
	mov [edi + 2], ebx
	shr ebx, 28
	mov [edi + 7], bl
	mov ebx, [ebp + 5 * 4]
	mov [edi + 0], bx
	shr ebx, 16
	mov [edi + 6], bl
	mov eax, [ebp + 6 * 4]
	mov [edi + 5], al
	and ah, 0xf0
	or [edi + 6], ah

	popa
	leave
	ret


;	void create_gate(int descriptor_table_address, int number, int attrib, int selector, int attrib)
;	mov dword [esp + 0 * 4], DESCRIPTOR_TABLE_ADDRESS
;	mov dword [esp + 1 * 4], NUMBER
;	mov dword [esp + 2 * 4], ATTRIB
;	mov dword [esp + 3 * 4],SELECTOR
;	mov dword [esp + 4 * 4], OFFSET
;	call create_gate
_create_gate:
	push ebp
	mov ebp, esp
	pusha

	mov ebx, [ebp + 2 * 4]
	mov ecx, [ebp + 3 * 4]
	shl ecx, 3
	add ebx, ecx
	mov ax, [ebp + 4 * 4]
	mov [ebx + 2], ax
	mov ax, [ebp + 5 * 4]
	mov [ebx + 4], ax
	mov eax, [ebp + 6 * 4]
	mov [ebx + 0], ax
	shr eax, 16
	mov [ebx + 6], ax

	popa
	leave
	ret


; void put_s_pos(char* s, int colour, int pos);

_put_s_pos:
	push ebp
	mov ebp, esp
	
	mov esi, [ebp + 2 * 4]
	mov ah, [ebp + 3 * 4]
	mov ebx, [ebp + 4 * 4]
	
.1:
	mov al, [esi]
	or al, al
	jz .2
	mov [gs:ebx], ax
	inc ebx
	inc ebx
	inc esi
	jmp .1
.2:

	leave
	ret
	
	
global _rtc_interrupt
extern _rtc_handler

_rtc_interrupt:
	pusha
	push ds
	push es
	push fs
	push gs
	
	call _rtc_handler
	
	mov al, 0x20
	out 0x20, al
	out 0xa0, al
	
	pop gs
	pop fs
	pop es
	pop ds
	popa
	iret
; loader.asm
bits 32
start32:

	mov ebx, 1 * 2 * 80 + 0 
	mov byte [gs:ebx], 'P'
	inc ebx
	mov byte [gs:ebx], 0xe
	inc ebx

	
;	void load_sector(int start_sector, int sector_number, int start_memory)
	mov dword [esp + 0 * 4], 19
	mov dword [esp + 1 * 4], 2048
	mov dword [esp + 2 * 4], 0x100000
	call load_sector


;	void create_descriptor(int descriptor_table_address, int selector, int base_address, int limit, int attrib)
	mov dword [esp + 0 * 4], 0x10000
	mov dword [esp + 1 * 4], 0
	mov dword [esp + 2 * 4], 0x0
	mov dword [esp + 3 * 4], 0x0
	mov dword [esp + 4 * 4], 0x0
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x10000
	mov dword [esp + 1 * 4], 1
	mov dword [esp + 2 * 4], 0x0
	mov dword [esp + 3 * 4], 0xfffff
	mov dword [esp + 4 * 4], 0xcf00 + 0x92
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x10000
	mov dword [esp + 1 * 4], 2
	mov dword [esp + 2 * 4], 0x0
	mov dword [esp + 3 * 4], 0xfffff
	mov dword [esp + 4 * 4], 0xcf00 + 0x9a
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x10000
	mov dword [esp + 1 * 4], 3
	mov dword [esp + 2 * 4], 0xb8000 + 0xc000_0000
	mov dword [esp + 3 * 4], 0xffffffff
	mov dword [esp + 4 * 4], 0xcf00 + 0x92
	call create_descriptor

	lgdt [gdtr]

	call setup_page



	mov ax, 1 * 8
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov ss, ax
	mov esp, 0xc000_0000 + 0x400000
	
	mov ax, 3 * 8
	mov gs, ax
	
	jmp dword 2 * 8 : 0xc0101000 
	
	jmp $
	
gdtr:
	dw 8192 * 8 - 1
	dd 0xc001_0000

;	void load_sector(int start_sector, int sector_number, int start_memory)
;	mov dword [esp + 0 * 4], START_SECTOR
;	mov dword [esp + 1 * 4], SECTOR_NUMBER
;	mov dword [esp + 2 * 4], START_MEMORY
;	call load_sector
load_sector:
	push ebp
	mov ebp, esp
	pusha

	push ds
	mov ax, 4 * 8
	mov ds, ax

	mov esi, [ebp + 2 * 4]
	mov edi, [ebp + 3 * 4]
	mov ebx, [ebp + 4 * 4]

.3:
	mov al, 1
	mov dx, 0x1f2
	out dx, al
	
	mov eax, esi
	mov dx, 0x1f3
	out dx, al
	shr eax, 8
	mov dx, 0x1f4
	out dx, al
	shr eax, 8
	mov dx, 0x1f5
	out dx, al
	shr eax, 8
	and al, 0x0f
	or al, 1110_0000b
	mov dx, 0x1f6
	out dx, al
	
	mov al, 0x20
	mov dx, 0x1f7
	out dx, al
	
	mov dx, 0x1f7
.1:
	in al, dx
	and al, 1000_1000b
	cmp al, 0000_1000b
	jne .1

	mov ecx, 256
	mov dx, 0x1f0
.2:
	in ax, dx
	mov [ebx], ax
	inc ebx
	inc ebx
	loop .2

	inc esi
	dec edi
	cmp edi, 0
	jne .3

	pop ds
	popa
	leave
	ret

;	void create_descriptor(int descriptor_table_address, int selector, int base_address, int limit, int attrib)
;	mov dword [esp + 0 * 4], DESCRIPTOR_TABLE_ADDRESS
;	mov dword [esp + 1 * 4], SELECTOR
;	mov dword [esp + 2 * 4], BASE_ADDRESS
;	mov dword [esp + 3 * 4], LIMIT
;	mov dword [esp + 4 * 4], ATTRIB
;	call create_descriptor
create_descriptor:
	push ebp
	mov ebp, esp
	pusha

	push ds
	mov ax, 4 * 8
	mov ds, ax
	mov esi, [ebp + 2 * 4]
	mov edi, [ebp + 3 * 4]
	shl edi, 3
	add edi, esi
	mov ebx, [ebp + 4 * 4]
	mov [edi + 2], ebx
	shr ebx, 24
	mov [edi + 7], bl
	mov ebx, [ebp + 5 * 4]
	mov [edi + 0], bx
	shr ebx, 16
	mov [edi + 6], bl
	mov eax, [ebp + 6 * 4]
	mov [edi + 5], al
	and ah, 0xf0
	or [edi + 6], ah

	pop ds	
	popa
	leave
	ret


;	void create_gate(int descriptor_table_address, int number, int offset, int selector, int attrib)
;	mov dword [esp + 0 * 4], DESCRIPTOR_TABLE_ADDRESS
;	mov dword [esp + 1 * 4], NUMBER
;	mov dword [esp + 2 * 4], OFFSET
;	mov dword [esp + 3 * 4],SELECTOR
;	mov dword [esp + 4 * 4], ATTRIB
;	call create_gate
create_gate:
	push ebp
	mov ebp, esp
	pusha

	push ds
	mov ax, 4 * 8
	mov ds, ax

	mov esi, [ebp + 2 * 4]
	mov edi, [ebp + 3 * 4]
	shl edi, 3
	add edi, esi
	mov ebx, [ebp + 4 * 4]
	mov [edi + 0], ebx
	mov [edi + 4], ebx
	mov ebx, [ebp + 5 * 4]
	mov [edi + 2], bx
	mov eax, [ebp + 6 * 4]
	mov [edi + 4], ax	

	pop ds
	popa
	leave
	ret

; void setup_page(void)
setup_page:
	push ebp
	mov ebp, esp
	pusha
	
	mov ecx, 3
	mov edi, 0x400000 - 0x7e00
	mov eax, 0x400000 + 0x1000 + 0x7
	.1: stosd
	add eax, 0x1000
	loop .1
	
	mov ecx, 3 * 1024
	mov edi, 0x400000 + 0x1000 - 0x7e00
	mov eax, 0x0 + 0x7
	.2: stosd
	add eax, 0x1000
	loop .2

	mov ecx, 3
	mov edi, 0x400000 + 0xc000_0000 / 0x400000 * 4 - 0x7e00
	mov eax, 0x400000 + 0x4000 + 0x7
	.3: stosd
	add eax, 0x1000
	loop .3
	
	mov ecx, 3 * 1024
	mov edi, 0x400000 + 0x4000 - 0x7e00
	mov eax, 0x0 + 0x7
	.4: stosd
	add eax, 0x1000	
	loop .4
	
	mov eax, 0x400000
	mov cr3, eax
	
	mov eax, cr0
	or eax, 0x8000_0000
	mov cr0, eax
	
	jmp .5
	.5:
	
	popa
	leave
	ret
	
#Makefile

all: c2o s2o asm2o
	kauto.cmd
build:
	make all
	kbuild.cmd
run: build
	run.cmd
dbg: build
	dbg.cmd

c2o: $(patsubst %.c, %.o, $(wildcard *.c))
%.o:%.c
	gcc -masm=intel -c -o $@ $^
s2o: $(patsubst %.s, %.o, $(wildcard *.s))
%.o:%.s
	gcc -masm=intel -c -o $@ $^
asm2o: $(patsubst %.asm, %.o, $(wildcard *.asm))
%.o:%.asm
	nasm -felf -o $@ $^
clean:
	del *.o *.bin *.pe *.elf32 *.lock

 run.cmd

bochs -q -f bochsrc.bxrc

 dbg.cmd

%dbg.cmd%
bochsdbg.exe -q -f bochsrc.bxrc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

weixin_39410618

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

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

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

打赏作者

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

抵扣说明:

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

余额充值