1 c執行環境的初始化

2021-07-22 08:31:01 字數 4557 閱讀 9966

源**目錄src/sandnix/kernel/hal/init/arch

這部分幹的活可以歸為以下幾點

.global     _start

.global gdt

.global kernel_header

.global tss_desc_table

.section .data

//gdt表

gdt:

segment_descriptor 0, 0, 0

descriptor_kernel_data:

segment_descriptor 0, 0xfffff, da_drw | da_dpl0 | da_32

descriptor_kernel_code:

segment_descriptor 0, 0xfffff, da_cr | da_dpl0 | da_32

descriptor_user_data:

segment_descriptor 0, 0xfffff, da_drw | da_dpl3 | da_32

descriptor_user_code:

segment_descriptor 0, 0xfffff, da_cr | da_dpl3 | da_32

tss_desc_table:

.rept max_cpu_num

segment_descriptor 0, 0x67, da_386tss | da_dpl0

.endr

gdt_end:

gdtr_value:

.word (gdt_end - gdt - 1)

gdt_addr:

.long gdt

.section .text

.align

8//描述核心映像資訊的結構體,編譯時由指令碼填充

kernel_header:

//magic

.long kernel_header_magic

//code_start

.long 0

//code_size

.long 0

//data_start

.long 0

//data_size

.long 0

//header_size

.long _kernel_header_end - kernel_header

//checksum

.long 0x100000000 - ((kernel_header_magic + (_kernel_header_end - kernel_header)) & 0xffffffff)

_kernel_header_end:

.long 0

/* step 1 : 檢查引導協議型別.咋檢查看multiboot2的文件 */

#if bootloader == multiboot2

//eax == magic.ebx = kernel parameters

_start:

cli//check bootloader

cmpl $0x36d76289, %eax

je _bootloader_checked

//if(eax != 0x36d76289)

_bootloader_checked:

//對的話就把引導資訊的位址壓棧

pushl %ebx

#endif

/* step 2 : 準備c的執行環境 */

//call/pop/sub組合計算偏移量,這招過去很多檔案型病毒也愛用

call _addr_1

_addr_1:

popl %eax

subl $_addr_1, %eax

//eax = offset

//write gdt address

movl $gdt, %edx

addl %eax, %edx

movl $gdt_addr, %ebx

addl %eax, %ebx

movl %edx, (%ebx)

//load gdt

movl $gdtr_value, %ebx

addl %eax, %ebx

lgdt (%ebx)

//load segments

movw $selector_u_data, %ax

movw %ax, %ds

movw %ax, %es

movw %ax, %fs

movw %ax, %gs

//開分頁,這個函式是mmu模組提供的,用c寫的,訪問個全域性變數都要計算偏移,相當的蛋疼

call start_paging

//跳到核心空間,順便載入cs

ljmpl $selector_k_code, $_kernel_mem

_kernel_mem:

//reload stack

//彈出引導資訊

popl %edi

movl $init_stack, %ebx

addl $default_stack_size, %ebx

movl %ebx, %ebp

movl %ebx, %esp

//將剛才彈出的引導資訊壓棧,這樣正好作為核心主函式的引數

push %edi

//reload gdt

//write gdt address

movl $gdt, gdt_addr

//load gdt

movl $gdtr_value, %eax

lgdt (%eax)

//fpu

fninit

movl $0x80010021, %eax

movl %eax, %cr0

/* step 3 : call c code. */

//呼叫主函式

call kinit

.global     _start

.global kernel_header

.section

.text

.align

8//跟上面一樣

kernel_header:

//magic

.long kernel_header_magic

//code_start

.long

0 //code_size

.long

0 //data_start

.long

0 //data_size

.long

0 //header_size

.long _kernel_header_end - kernel_header

//checksum

.long

0x100000000 - ((kernel_header_magic + (_kernel_header_end - kernel_header)) & 0xffffffff)

_kernel_header_end:

.long

0_start:

//保證處於svc模式並且遮蔽掉irq和fiq

ldr r5, =0x000000d3

msr spsr, r5

msr cpsr, r5

//計算偏移,原理和x86的一樣

_offchk_addr:

movr5, pc

subr5, r5, #8

ldr r6, =_offchk_addr

subr5, r5, r6 //r5 = offset

//載入核心棧

ldr sp, =init_stack

add sp, sp, r5

ldr r6,=default_stack_size

add sp, sp, r6

#if bootloader == uboot

//把引數壓棧

stmfd sp!,

#endif

//開分頁

bl start_paging

//重定位棧指標

sub sp, sp, r5

//把引數彈到r0

ldmfd sp!,

//呼叫主函式

ldr r1, =kinit

mov pc, r1

初始化 1 預設初始化 列表初始化

初始化的基本概念 事實 初始化和賦值是兩個完全不同的操作。初始化,是建立變數時賦予其乙個初始值。賦值,是把物件的當前值擦除,用乙個新值代替。列表初始化 p39 作為c 11新標準的一部分,用花括號 來初始化變數得到了全面應用。出於某些原因,這種初始化的方式叫做列表初始化。現在,無論是初始化物件還是某...

初始化 GDI 環境

初始化 gdi 環境我的開發環境為 vc.net 2003,下面我就來說一下在此開發環境中如何載入 gdi 開發環境,如果您的開發環境為 vc 6 請參考本文結尾部分。在標準的 mfc 開發環境中 mfc 是不支援 gdi 開發的,要想使用 gdi 需要我們手工對程式做一些修改。原理我就不想說了,感...

初始化GDI 環境

我的開發環境為 vc.net 2003,下面我就來說一下在此開發環境中如何載入 gdi 開發環境,如果您的開發環境為 vc 6 請參考本文結尾部分。在標準的 mfc 開發環境中 mfc 是不支援 gdi 開發的,要想使用 gdi 需要我們手工對程式做一些修改。原理我就不想說了,感興趣的朋友可以自己在...