📄 loader.s
字号:
/* Open A20 line. */ inb $0x92, %al orb $0b00000010, %al outb %al, $0x92 /* Enable protect mode, PE bit of CR0. */ movl %cr0, %eax orl $1, %eax movl %eax, %cr0 /* Mixed-Size Jump. */ ljmpl $SelectorCode32, $0 /* Thanks to earthengine@gmail, I got */ /* this mixed-size jump insn of gas. *//* 32-bit code segment for LDT */LABEL_CODEA:.code32 mov $(SelectorVideo), %ax mov %ax, %gs movb $0xC, %ah /* 0000: Black Back 1100: Red Front */ xor %esi, %esi xor %edi, %edi movl $(LDTMessage), %esi movl $((80 * 12 + 0) * 2), %edi cld /* Clear DF flag. *//* Display a string from %esi(string offset) to %edi(video segment). */CODEA.1: lodsb /* Load a byte from source */ test %al, %al jz CODEA.2 mov %ax, %gs:(%edi) add $2, %edi jmp CODEA.1CODEA.2: /* Stop here, infinate loop. */ jmp ..set CodeALen, (. - LABEL_CODEA)/* 32-bit code segment for GDT */LABEL_SEG_CODE32: mov $(SelectorData), %ax mov %ax, %ds /* Data segment selector */ mov $(SelectorData), %ax mov %ax, %es /* Data segment selector */ mov $(SelectorStack), %ax mov %ax, %ss /* Stack segment selector */ mov $(SelectorVideo), %ax mov %ax, %gs /* Video segment selector(dest) */ mov $(TopOfStack), %esp push $(ARDSTitle) /* Display addr range descriptor struct title */ call DispStr add $4, %esp call DispAddrMap /* Display system address map */ call SetupPaging /* Setup and enable paging */ push $(PMMessage) call DispStr add $4, %esp mov $(SelectorTSS), %ax /* Load TSS to TR register */ ltr %ax pushl $(SelectorStackR3) /* Fake call procedure. */ pushl $(TopOfStackR3) pushl $(SelectorCodeR3) pushl $0 lret /* return with no call */CODE32.3: mov $(SelectorLDT), %ax lldt %ax ljmp $(SelectorLDTCodeA), $0/* Get the length of 32-bit segment code. */.set SegCode32Len, . - LABEL_SEG_CODE32/* 32-bit code segment for call gate destination segment */LABEL_SEG_CODECG: mov $(SelectorVideo), %ax mov %ax, %gs movl $((80 * 12 + 0) * 2), %edi /* line 11, column 0 */ movb $0xC, %ah /* 0000: Black Back 1100: Red Front */ movb $'C', %al /* Print a 'C' */ mov %ax, %gs:(%edi) lret/* Get the length of 32-bit call gate destination segment code. */.set SegCodeCGLen, . - LABEL_SEG_CODECG/* 32-bit code segment for runing in ring 3. */LABEL_SEG_CODER3: mov $(SelectorVideo), %ax mov %ax, %gs movl $((80 * 12 + 1) * 2), %edi /* line 11, column 1 */ movb $0xC, %ah /* 0000: Black Back 1100: Red Front */ movb $'3', %al /* Print a '3' */ mov %ax, %gs:(%edi) lcall $(SelectorCGTest), $0 /* Call CODECG through call gate */ jmp . /* Get the length f 32-bit ring 3 segment code. */.set SegCodeR3Len, . - LABEL_SEG_CODER3SetupPaging:/* Directly map linear addresses to physical addresses for simplification */ /* Get useable PDE number from memory size. */ xor %edx, %edx mov (MemSize), %eax /* Memory Size */ mov $0x400000, %ebx /* Page table size(bytes), 1024*1024*4 */ div %ebx /* temp = MemSize/4M */ mov %eax, %ecx test %edx, %edx jz SP.no_remainder inc %ecxSP.no_remainder: push %ecx /* number of PDE = ceil(temp) */ /* Init page table directories, %ecx entries. */ mov $(SelectorPageDir), %ax mov %ax, %es xor %edi, %edi xor %eax, %eax /* Set PDE attributes(flags): P: 1, U/S: 1, R/W: 1. */ mov $(PageTblBase | PG_P | PG_USU | PG_RWW), %eaxSP.1: stosl /* Store %eax to %es:%edi consecutively. */ add $4096, %eax /* Page tables are in sequential format. */ loop SP.1 /* %ecx loops. */ /* Init page tables, %ecx*1024 pages. */ mov $(SelectorPageTbl), %ax mov %ax, %es pop %eax /* Pop pushed ecx(number of PDE) */ mov $1024, %ebx mul %ebx /* Loop counter, num of pages: 1024*%ecx. */ mov %eax, %ecx xor %edi, %edi /* Set PTE attributes(flags): P:1, U/S: 1, R/W: 1. */ mov $(PG_P | PG_USU | PG_RWW), %eaxSP.2: stosl /* Store %eax to %es:%edi consecutively. */ add $4096, %eax /* Pages are in sequential format. */ loop SP.2 /* %ecx loops. */ mov $(PageDirBase), %eax mov %eax, %cr3 /* Store base address of page table dir to %cr3. */ mov %cr0, %eax or $0x80000000, %eax mov %eax, %cr0 /* Enable paging bit in %cr0. */ ret/* Display system address map. */DispAddrMap: push %esi push %edi push %ecx mov $(AddrMapBuf), %esi /* int *p = AddrMapBuf; */ mov (AMECount), %ecx /* for (int i=0; i<AMECount; i++) { */DMS.loop: mov $5, %edx /* int j = 5; */ mov $(ARDStruct), %edi /* int *q = (int *)ARDStruct; */DMS.1: push (%esi) /* do { */ call DispInt /* printf("%xh", *p); */ pop %eax stosl /* *q++ = *p; */ add $4, %esi /* p++; */ dec %edx /* j--; */ cmp $0, %edx jnz DMS.1 /* } while(j != 0); */ call DispLF /* printf("\n"); */ cmpl $1, (Type) /* if (Type == AddressRangMemory){ */ jne DMS.2 mov (BaseAddrLow), %eax /* if(ARDStruct.BaseAddrLow */ add (LengthLow), %eax /* + ARDStruct.LengthLow */ cmp (MemSize), %eax /* > MemSize){ */ jb DMS.2 /* MemSize = BaseAddrLow + LengthLow; */ mov %eax, (MemSize) /* } */DMS.2: /* } */ loop DMS.loop /* } */ call DispLF /* printf("\n"); */ push $(RAMSizeMes) call DispStr /* printf("%s", RAMSizeMes); */ add $4, %esp pushl (MemSize) call DispInt /* printf("%x", MemSize); */ add $4, %esp call DispLF /* printf("\n"); */ pop %ecx pop %edi pop %esi ret#include "lib.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -