2019年7月18日 星期四

自製64位元作業系統11──尋找核心

我們繼續進行讀取核心的準備工作,今天的目標就是讀取核心(雖然我們根本還沒有核心)。要讀取一個Ext2檔案系統,首先一定要找到Superblock,並且透過裡面的資訊來定位其他必要的檔案位置。
在Ext2檔案系統中,Superblock從1024的位置開始,所以我們要先讀取這個東西。至於我們要讀取到哪裡呢?可以參考https://people.cs.nctu.edu.tw/~huangmc/works/web/Boot_x86/Boot_x86.html,裡面有最底下1MB記憶體的空閒區域(我們先暫時不要用到1MB以上的空間,因為以後要拿來放核心)。所以隨便找一個風水(?)好的位置,就可以放進去了。我挑選的位置是0x1000。
緊接著的是Block group descriptor table,我們就跟著superblock,放在0x1400的位置。
  movl $34, %ebx
  movl $4, %ecx
  movl $0x1000, %edi
  call readATA
再來我們要讀取核心的Inode,需要從Block group descriptor找到這個第零個Block group的Inode table位置。根目錄(也就是最上層的目錄,通俗一點叫做頂層資料夾),一定是第二個Inode,所以讀取這個Inode table的Block,再找到這個位置(每個Inode大小正常是128Bytes)。
# Read INODE Table to find root directory
  movl 0x1408, %ebx
  addl $16, %ebx
  shll %ebx
  movl $2, %ecx
  movl $0x1800, %edi
  call readATA
再來透過讀取根目錄的資訊,運用字串比對的方法,找尋kernel.elf這個檔案的Inode編號。
# block number zero
  movl $0x0, %ecx
  jmp .read_next_root_block

.searchKernel_Root_Block_Loop:
  pushl %ecx
  call searchFile
  popl %ecx
  cmp $0, %eax
  jne .found_kernel_inode
.read_next_root_block:
  pushl %ecx
  movl $32, %eax
  pushl %eax

  movl $1, %eax
  pushl %eax

  pushl %ecx

  movl $0x1880, %eax # Root Inode Position
  pushl %eax

  movl $0x1c00, %eax
  pushl %eax

  call readInodeBlock

  addl $20, %esp
  popl %ecx
  incl %ecx
  test %eax, %eax
  jnz .searchKernel_Root_Block_Loop
.kernel_not_found:
  movl $(0x7E00+.kernel_not_found_msg), %esi
  call print32
  hlt

.kernel_not_found_msg:
  .asciz "Kernel not found"
我們先來看看如何找到kernel.elf的檔案。這主要是由searchFile函式所處理。一開始我們先保護一些暫存器(但我們這裡都還沒有使用到任何呼叫慣例),然後把目錄中的所有檔案一個一個檢查和kernel.elf是否一樣,假如一樣,就把這個Inode目前我們存放的記憶體位置,利用EAX暫存器回傳
searchFile:
  pushl %ebx
  pushl %ecx
  pushl %edx
  pushl %esi
  pushl %edi
  movl $0x1C00, %ebx
  movl $0x0, %edx
  .loop_search_file:
    movl (%ebx, %edx, 1), %eax
    cmp $0, %eax
    je .next_search_file
    movzbl 6(%ebx, %edx, 1), %eax
    cmp $10, %eax         # kernel.elf 10 bytes
    jne .next_search_file
    leal 8(%ebx, %edx, 1), %edi
    leal KERN_FILENAME+0x7E00, %esi
    movl $10, %ecx
    repe cmpsb
    cmp $0, %ecx
    jne .next_search_file
    movl (%ebx, %edx, 1), %eax
    jmp .search_file_exit
  .next_search_file:
    movzwl 4(%ebx, %edx, 1), %eax
    addl %eax, %edx
    cmp $0x400, %edx
    jl .loop_search_file

  .search_file_end:
  movl $0, %eax

  .search_file_exit:
  popl %edi
  popl %esi
  popl %edx
  popl %ecx
  popl %ebx
  ret

KERN_FILENAME:
  .asciz "kernel.elf"
下一次我們就要利用找尋到的Inode編號讀取核心。



👉【幫我們一個忙!】👈

👋如果您喜歡這篇文章,請在下方按5個Like!
 ❤您的支持是我們最大的動力!

您只要登入帳號(Facebook、Google),在下方按5個Like,我們就會收到來自LikeCoin基金會的贊助。
您只需要支持我們,完全不會花到錢!