<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      從零開始制作 MyOS(四)

      從零開始制作 MyOS(四)—— 跳轉到 C 語言編寫的小型內核

      目標

      在引導加載器準備好后,用 C 語言編寫一個小型內核并實現從引導加載器跳轉到內核執行。

      代碼

      引導程序文件

      org 0x7C00
      bits 16
      
      start:
          ; 初始化段寄存器
          xor ax, ax
          mov ds, ax
          mov es, ax
          mov ss, ax
          mov sp, 0x7C00
      
          ; 顯示啟動信息
          mov si, msg_loading
          call print_string
      
          ; 加載內核到 0x10000
          mov ax, 0x1000
          mov es, ax
          xor bx, bx
          
          mov ah, 0x02    ; 讀扇區
          mov al, 4       ; 4個扇區
          mov ch, 0       ; 柱面0
          mov cl, 2       ; 扇區2
          mov dh, 0       ; 磁頭0
          mov dl, 0x80    ; 驅動器
          int 0x13
          jc disk_error
      
          ; 切換到保護模式
          cli
          lgdt [gdt_descriptor]
          
          ; 啟用A20
          in al, 0x92
          or al, 2
          out 0x92, al
          
          mov eax, cr0
          or eax, 1
          mov cr0, eax
          
          jmp CODE_SEG:init_pm
      
      disk_error:
          mov si, msg_error
          call print_string
          jmp $
      
      print_string:
          lodsb
          test al, al
          jz .done
          mov ah, 0x0E
          int 0x10
          jmp print_string
      .done:
          ret
      
      bits 32
      init_pm:
          mov ax, DATA_SEG
          mov ds, ax
          mov es, ax
          mov ss, ax
          mov esp, 0x90000
          
          ; 跳轉到內核
          jmp 0x10000
      
      ; 數據區
      msg_loading db "Booting...", 0xD, 0xA, 0
      msg_error db "Disk error!", 0
      
      ; GDT
      gdt_start:
          dq 0
      gdt_code:
          dw 0xFFFF
          dw 0
          db 0
          db 10011010b
          db 11001111b
          db 0
      gdt_data:
          dw 0xFFFF
          dw 0
          db 0
          db 10010010b
          db 11001111b
          db 0
      gdt_end:
      
      gdt_descriptor:
          dw gdt_end - gdt_start - 1
          dd gdt_start
      
      CODE_SEG equ gdt_code - gdt_start
      DATA_SEG equ gdt_data - gdt_start
      
      times 510-($-$$) db 0
      dw 0xAA55
      
      

      內核入口文件

      section .text
      global _start
      
      _start:
          mov esp, 0x90000  ; 設置棧指針
          extern kernel_main
          call kernel_main   ; 調用C內核
          hlt
      

      小型內核文件

      void kernel_main(void) {
          char *vga = (char*)0xB8000;
          
          // 清屏
          for (int i = 0; i < 80 * 25 * 2; i += 2) {
              vga[i] = ' ';
              vga[i + 1] = 0x07;
          }
          
          // 顯示字符串
          char *msg = "Hello from C Kernel!";
          for (int i = 0; msg[i]; i++) {
              vga[i * 2] = msg[i];
              vga[i * 2 + 1] = 0x07;
          }
          
          while(1) asm("hlt");
      }
      

      鏈接器

      ENTRY(_start)
      
      SECTIONS
      {
          . = 0x10000;
          
          .text : { *(.text) }
          .data : { *(.data) }
          .bss : { *(.bss) }
      }
      

      Makefile

      CC = gcc
      LD = ld
      ASM = nasm
      
      CFLAGS = -m32 -ffreestanding -nostdlib -c
      ASFLAGS = -f elf32
      LDFLAGS = -m elf_i386 -T linker.ld -nostdlib
      
      all: os.img
      
      os.img: boot.bin kernel.bin
      	dd if=/dev/zero of=os.img bs=512 count=2880
      	dd if=boot.bin of=os.img conv=notrunc
      	dd if=kernel.bin of=os.img bs=512 seek=1 conv=notrunc
      
      boot.bin: boot.asm
      	$(ASM) -f bin boot.asm -o boot.bin
      
      kernel.bin: kernel.elf
      	objcopy -O binary kernel.elf kernel.bin
      
      kernel.elf: entry.o kernel.o
      	$(LD) $(LDFLAGS) -o kernel.elf entry.o kernel.o
      
      kernel.o: kernel.c
      	$(CC) $(CFLAGS) kernel.c -o kernel.o
      
      entry.o: entry.asm
      	$(ASM) $(ASFLAGS) entry.asm -o entry.o
      
      clean:
      	rm -f *.o *.bin *.elf os.img
      
      run: os.img
      	qemu-system-x86_64 -drive format=raw,file=os.img
      
      .PHONY: all clean run
      

      編譯運行

      # ubuntu 中,VGA 顯示
      make clean && make run
      
      

      運行結果

      當終端打印出來“Hello from C Kernel!”,就表示運行成功了

      跳轉 C 內核成功

      問題

      本節遇到最大的問題是內核跳轉不過來,目前只找到以下一些可能:

      磁盤問題

      1. 段寄存器設置順序錯誤

        • 先設置ES再操作磁盤
      2. 缺少錯誤重試機制?
        +

      3. 扇區數不足

      A20地址線啟用問題

      1. and al, 0xFE會錯誤清除bit 0(可能影響系統重啟)

      2. 缺少狀態檢查?:未驗證A20是否真正啟用成功

      保護模式跳轉問題

      1. 無效跳轉指令,jmp 0x10000未使用段選擇子,在保護模式下會崩潰
      2. 缺少段寄存器初始化?:未正確設置DS/ES/SS等數據段寄存器

      內核入口對齊問題

      1. 未聲明全局符號?:_start未在entry.asm中聲明為global
      2. ?棧未對齊?:x86要求棧指針按16字節對齊

      編譯鏈接問題

      1. 缺少內核地址指定?:鏈接腳本未強制指定內核加載地址為0x10000
      2. 未處理BSS段?:未清零未初始化數據段
      posted @ 2025-10-30 10:07  王清河  閱讀(6)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 汤阴县| 亚洲av日韩av永久无码电影| 免费观看成人毛片a片| 国产精品线在线精品国语| 丁香五月婷激情综合第九色| 蜜臀av在线观看| 日韩伦理片| 国产成人久久精品二区三| 亚洲一区二区中文av| 青青草原国产精品啪啪视频| 91老肥熟女九色老女人| 国产成人一区二区视频免费| 国产精品久久中文字幕| 中国性欧美videofree精品| 最近2019免费中文字幕8| 成人av午夜在线观看| 日本一区二区久久人妻高清| 成人无码午夜在线观看| 2021亚洲爆乳无码专区| 日韩人妻少妇一区二区三区| 国产成人精品免费视频app软件| 在线精品国产中文字幕| 日韩一区二区大尺度在线| 国产精品天干天干综合网| 日韩国产精品无码一区二区三区 | 精品一区二区成人精品| 新巴尔虎右旗| 麻豆国产成人AV在线播放| 亚洲第一福利网站在线| 国产99青青成人A在线| 国产亚洲无线码一区二区| 在线天堂www在线| 国产伦一区二区三区久久| 免费无码一区无码东京热| 久久精品无码免费不卡| 老司机精品影院一区二区三区| 亚洲一二区制服无码中字| 国产成人人综合亚洲欧美丁香花| 国产黄色三级三级看三级| 国产综合视频一区二区三区 | 国产成人AV男人的天堂|