除了 stack 太小會被覆蓋之外, bss 也有可能, 由於沒有記憶體管理, 所以我隨意要了一塊區域來儲存軟碟片讀出的資料, 結果這位址剛好會覆蓋到 bss section, 導致我的全域變數 pbp 會被改到, 真的體會到沒事不要用全域變數 XD。
原來記憶體管理真的很重要, 本來以為沒有記憶體管理比較方便, 整塊記憶體位址隨我使用, 結果中招了。
kernel loader 又出狀況了
20121019 git commit: 593df1817cb2e9af341643ba10c2f891b718f6de
使用 gcc-4.7 的版本, 無法正常 load p_kernel.elf。
workaround: kernel loader 使用 gcc 4.4 的版本編譯。
p_kernel.elf 沒有這問題, 使用 gcc 4.7 一樣可以正常運作。
20121024 fixed:
git commit: 57a731474c6e28d2e1a07a926d1285e0ca7afda2
看來有兩個問題:
fat_buf 和 讀取 p_kernel.elf 的位址重疊。
p_kernel.elf 移動到 entry point 時, 被 corrupt 了。我把 entry point 改到 1 MB 之後就正常了。1MB 內就給真實模式用, 進入保護模式後就開心的用 1MB 之後的位址。
qemu/bochs VS 真實機器
在這些環境下, 總是有些不同, 每每總是要在真實機器上測試, 才能真正的通過考驗。所以在模擬器可以正確執行, 還不能安心, 得在真實環境再測試過才行。儘管如此, 有了 qemu, bochs 總是提供了不少助益, 讓我有些除錯的方法。而在 A 機器跑得正常的模擬器環境, 到 B 機器的模擬器環境竟然有問題, 這也很常見, 總之要靠模擬器驗證程式的正確性不是很可靠。
在不同的電腦環境下, 在 qemu/bochs 有不同表現
git version: 3b4455c3b688a4d59029a540918d306c2bf4eb71有的可以執行, 有的環境會發生 #GP, 應該還是程式碼哪裡有問題吧!
結果是 stack 的問題, 我加大 kernel stack from 2048 -> 4096 就沒這問題了。
init_bss_asm 放錯地方
init_bss_asm 會把 bss 清成 0, 但我搞了烏龍, 在 c function 裡頭將 gdt 變數設定好, 準備好保護模式的 code, 在測試 process 的程式碼時, 卻總是在某個地方出錯。百思不得其解, 出動 bochs 的內建 debugger, 發現 gdt 怎麼變成 0 了, 奇怪, 我都把值印出來看過了, 怎麼會有問題?
原來我在 c function 之後執行了 init_bss_asm, 自然把 .bss section 清為 0, 而 gdt 正好放在 .bss sesction, 就這樣, 又搞烏龍。要是放在 .data 也許就沒問題了, 但是我的 bss 初始化程式碼, 也可能就更找不到出錯的地方。早點發現還是比較好的。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。