2019年7月20日 星期六

自製64位元作業系統12──讀取核心

這次我們要接續上一篇文章,繼續讀取我們的核心。我們上次找到Inode的編號,找到對應的Block group,再跳到Inode table裡面,那個編號的檔案Inode。

.found_kernel_inode:
  decl %eax
  movl $0, %edx
  divl 0x1000 + 40
  shll $5, %eax
  movl 0x1408(%eax), %ebx
  addl $16, %ebx
  movl %edx, %eax
  xorl %edx, %edx
  movl $8, %ecx
  divl %ecx
  addl %eax, %ebx
  shll %ebx
  movl $2, %ecx
  movl $0x2000, %edi
  call readATA
讀取完以後,開始利用前不知道多少個文章中的讀取函式,來讀取核心的最前段到0x10000(找一個沒用過的地方亂塞東西:D)。
  shll $7, %edx

  pushl %edx
  movl $32, %eax
  pushl %eax

  movl $1, %eax
  pushl %eax

  movl $0, %eax
  pushl %eax

  leal 0x2000(%edx), %eax
  pushl %eax

  movl $0x10000, %eax
  pushl %eax
  call readInodeBlock

  addl $20, %esp
  popl %edx
因為我們的核心格式是ELF格式,我們就要試著讀取ELF格式中的各種資料,才能正確地把檔案讀取到記憶體中。我們可以參考:https://en.wikipedia.org/wiki/Executable_and_Linkable_Format裡面的資料,讓我們對ELF格式內部結構有更深的了解。
因為每一個有LOAD的Program section的Type編號都是1,所以我們只要把Type=1的所有section照著資料,一個一個讀入記憶體就好。
  movzwl 0x10038, %ecx
  movl 0x10020, %ebx          # Program header start position
  leal 0x10000(%ebx), %ebx
.load_elf_loop:
  pushl %ecx
  pushl %edx

  movl (%ebx), %eax
  cmp $1, %eax
  je .load_elf
  popl %edx
  jmp .add_elf_header
.load_elf:
  movl $32, %eax
  pushl %eax

  movl 0x20(%ebx), %eax
  test $0x3ff, %eax
  jz .load_less
  addl $0x400, %eax
  .load_less:
  shr $10, %eax
  pushl %eax

  movl 8(%ebx), %eax
  shr $10, %eax
  pushl %eax

  leal 0x2000(%edx), %eax
  pushl %eax

  movl 0x10(%ebx), %eax
  pushl %eax
  call readInodeBlock

  addl $20, %esp
  popl %edx
  movl 0x8(%ebx), %esi
  andl $1023, %esi
  
  test %esi, %esi
  
  jz .add_elf_header
  movl 0x8(%ebx), %esi
  movl 0x10(%ebx), %edi
  addl %edi, %esi
  movl 0x20(%ebx), %ecx
  rep movsb
  .add_elf_header:

  popl %ecx
  addl $0x38, %ebx
  loop .load_elf_loop

  movl 0x10018, %eax
  ret
我們最後的地方,把ELF裡面儲存的程式開始位置,放入EAX暫存器。現在,我們就可以把核心讀進來了。下一篇文章,我們要講述核心的格式。



👉【幫我們一個忙!】👈

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

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