⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 head.s

📁 从网上下载的一个自己编写的简单的操作系统源代码,对底层了解很有好处的
💻 S
字号:
;***********************************************************;; 32 bit 内核环境: gdt ,idt ; pg_dir pgtable; tss;; Segment Descripters:;      TSS;      LDT  不使用;      Code ;      Data;     ;*************************************************************global Start_OSglobal _gdt, _kpg_dirglobal _kpg_table,_pgt0,_pgt1extern _mainSECTION	.text  ; if no this , the ld can't find entry Start_OSStart_OS:        ;mov	ax,cs		; right, forgot this at first. didn't work :-)	;mov	ds,ax           ; 代码段描述符是不容许写的!!!!!!        ;call setup_paging       ;尽快开启分页        	;设置页目录,8M,2 entry	mov dword[_kpg_dir],_pgt0+7   ;页表采用绝对定位	mov dword[_kpg_dir+4],_pgt1+7	;3G+0- 3G+8M        mov dword[_kpg_dir+768*4],_pgt0+7	mov dword[_kpg_dir+4+768*4],_pgt1+7        ;设置两个页表, 恒同映射	mov edi,_pgt0     ;+4092	mov eax,0x007     ;/*  8Mb - 4096 + 7 (r/w user,p) */     fill_pte:	        mov [edi],eax     	add eax,0x1000       ;页面号加1(物理页面号)	add edi,4        cmp eax,0x800007 ;0x7ff007        jl  fill_pte        ;准备开启分页,设置cr3为页目录地址	mov eax,_kpg_dir	;/* pg_dir  */	mov cr3,eax		;/* cr3 - page directory start */        ;开启分页	mov eax,cr0	or  eax,0x80000000	mov cr0,eax		;/* set paging (PG) bit */        jmp page_flush          ;这一句让内核在3G以上开始运行        page_flush:        ;mov edx, 0x310a330a	;mov eax, 0xc00b8000	;mov [eax],edx        ;fush_after_paging_on:jmp fush_after_paging_on        		lgdt	[gdt_descr]		; reload gdt with kernel gdt                jmp pmode_flush        pmode_flush:                         push dword 0        popf        jmp 8:pmode_cs_flush       ; cs<--8,code segment        pmode_cs_flush:                mov     ax,0x10                 ; ds<--15, data segment                    mov     ds,ax        ;die:jmp die        mov     es,ax        mov     ss,ax        ;mov     fs,ax        ;mov     gs,ax                mov     esp,_k_top ;4k 内核栈        mov     eax,0                              mov eax,0        call _main        ;不可能运行到这里        never_here:        jmp never_hereglobal __flush        __flush:        mov eax,cr3	mov cr3,eax		;/* cr3 - page directory start */        ret;*********************全局变量**********************************         ;;section .dataalign 2   dw 0;伪gdt段的描述符,用于装载全局描述表寄存器GDTR;  Limit dw 0;  Liner_Base dd 0gdt_descr:            dw 256*8-1		; so does gdt (not that that's any	   dd _gdt		; magic number, but it works for me :^) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;全局描述符表;像linux 一样,我们不准备使用x86的分段机制;我们用4G的描述符绕过这个机制, 绝大多数cpu;只支持分页就是我们最好的理由;    LIMITL     DW      0 ;段界限低16位;    BASEL      DW      0 ;基地址低16位;    BASEM      DB      0 ;基地址中间8位;    ATTRIB     DB      0 ;段属性 P DPL(2) S TYPE(4);    LIMITH     DB      0 ;G D/B 0 AVL ,段界限的高4位16-19bits;    BASEH      DB      0 ;基地址的高8位section .data_gdt:	        dw	0,0,0,0		; CPU 不使用第一个段描述符        ;见IA-32 Volume 3,  3.5.1. Segment Descriptor Tables        ;kernel code	dw	0xFFFF	; 4G - limit=2047 (2048*4096=8Mb)	dw	0x0000	; base address=0	db	0x00	; base address=0	db      0x9A    ; code read//exec || 1 00(dpl)//1(code/data) 1010	db	0xCF	;  1100,粒度4k,32bit默认操作数,1111(4G),         db      0x00    ; base         ;kernel data        dw	0xFFFF	; 4G - limit=2047 (2048*4096=8Mb)	dw	0x0000	; base address=0	db	0x00	; base address=0	db      0x92    ; data read/write || 1 00(dpl)/1(code/data) 1010	db	0xCF	;  1100,粒度4k,32bit默认操作数,1111(4G),         db      0x00    ; base         ;user code                ;user data 	times 252*8 db 0 ;/* space for LDT's and TSS's etc */;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Paging          page dir;     cr3----> |----------|          page table;              |----------|\_______\ |--------|     |->|------|;              |----------|/       / |--------| ----|  |物理页|    ;              |----------|           .....         |  |------|;                ....                               |;              |----------|\_______\ |--------|     |  ;              |----------|/       / |--------|-----|;              |----------|          |--------|-------->|-----|;                .......               ......           |     |;                                                       |-----|;上面的图示演示一种特殊的页映射;page dir :4G空间, 1024 项,每个entry 有4m空间,占用4k;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;页目录表表项格式  ;31-----12 11--9  8  7   6  5   4    3   2    1    0  ;物理页码   AVL   G  PS  0  A  PCD  PWT  U/S  R/W  P ;;---最高20位(位12—位31)包含物理地址空间页的页码,也就是物理地址的高20位。;---低12位包含页的属性,属性中内容为0的位保留位必须设置为0。;---AVL字段供软件使用。;---G(Pentium Pro)置1代表是一个全局页. 我们置0.;---PS Page Size. ;0代表4k页,page dir entry 指向一个页表. 1代表4M页,page dir entry 指向页.;---A=1表示已访问过对应的物理页. 处理器永不清除A位,在访问时置A位.;通过周期性地检测及清除A位,操作系统就可确定哪些页在最近一段时间未被访问过;---PCD page-level cache disable. 为0时对应的页表或页可以被cache. ;i/o 内存一般情况下不容许cache.;---PWT page write-through. 如果置1, 写通cache策略使能, 否则使用write-back.;---U/S位指示该表项所指定的页是否是用户级页。;若U/S=1,表项所指定的页是用户级页,可由任何特权级下执行的程序访问;;如果U/S=0,表项所指定的页是系统级页,只能由系统特权级下执行的程序访问;---R/W位指示该表项所指定的页是否可读、写或执行。;若R/W=1,对表项所指定的页可进行读、写或执行;;若R/W=0,对表项所指定的页可读或执行,但不能对该指定的页写入。;但是,R/W位对页的写保护只在处理器处于用户特权级时发挥作用;;当处理器处于系统特权级时,R/W位被忽略,即总可以读、写或执行。 ;---P位表示该表项是否已经建立映射.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -