顯示具有 osdev 標籤的文章。 顯示所有文章
顯示具有 osdev 標籤的文章。 顯示所有文章

2019年1月27日 星期日

OrangeOS's 作業系統實現範例出現微軟防毒Defender的誤偵測





年關將近,最近繼續在整理舊書,偶然間翻到了一本放了很久的舊書 OrangeOS's 一個作業系統的實現。

在Windows 10 系統中,想試試它的範例,發現 a.img 檔案複製不過來,覺得十分奇怪。

突然跳出病毒移除警告,微軟的防毒軟體偵到 Trojan: DOS/Killmbr。


出現的路徑剛好是範例1的Hello World boot.asm 所對應的檔案 a.img

程式碼

原本的測試範例沒有Makefile, 筆者寫了一個測試用的Makefile 以方便在Ubuntu 16.04.4 重覆編譯

編譯測試檔案
/Dev/orangeos/chapter1/a$ make
qemu-img create -f raw a.img 1440k
Formatting 'a.img', fmt=raw size=1474560
mkfs.msdos -s 1 a.img
mkfs.fat 3.0.28 (2015-05-16)
nasm boot.asm -f bin -o boot.bin
dd if=boot.bin of=./a.img bs=512 count=1
1+0 records in
1+0 records out
512 bytes copied, 0.000185582 s, 2.8 MB/s


被偵測到有問題的boot.asm 範例


 org 07c00h
 mov ax, cs
 mov ds, ax
 mov es, ax
 call DispStr
 jmp $
DispStr:
 mov ax, BootMessage
 mov bp, ax
 mov cx, 16
 mov ax, 01301h
 mov bx, 000ch
 mov dl, 0
 int 10h
 ret
BootMessage:  db "Hello, OS world!"
times  510-($-$$) db 0
dw  0xaa55


通Defender 偵測的 boot.asm 範例

測試 ghaiklor 的 Simple boot sector with Hello World 範例編譯沒有問題
source: https://gist.github.com/ghaiklor/89e243a3463569480d01188c9e55e077





執行編譯OK的Hello World 

Windows 10 pro with qemu / make tools installed by choco


小結

比較程式的差異,通Defender 偵測的 boot.asm 範例,是比較好的寫法,有做處理停止中斷及結束。
看到偵測有病毒檔案訊息,先不用緊張,確認問題點,調整一下寫法,就可避開 Defender 誤偵測,繼續快樂的作業系統程式開發與研究囉!

2013年10月17日 星期四

F9 Microkernel 導讀活動 Part 1




今天JULUOS.ORG小聚 -- F9 Microkernel (a.k.a F9) 導讀活動,筆者將最近在拜讀 jserv 發起 F9 專案程式的筆記資料做個整理分享給大家。

為什麼我會想來讀F9 的程式碼呢?
首先,本人偏愛 BSD  License。

接著,之前有稍微看一下F9的程式,覺得寫得滿優雅的,程式看來順眼。記得曾看過關於優雅程式寫作的文章(我忘記那篇出處了>.<)中寫到:一個 .C 檔,最好保持在 300 行以內;一個C函式落在25~30行,目前看到的F9 code 有符合。見賢思齊,之前我的程式碼並沒有完全依循,之後也要再接再勵。

因為場地的關係,活動時間只有一個多小時;講了一些提要的重點,加上 F9 程式進入點的小部分,就沒時間了。之後找時間換個場地,再來辦導讀活動 Part 2。

最後,奉上今日的簡報檔,如有誤謬,請不吝指正。




2012年12月27日 星期四

我們可能使用更高階的語言來寫OS嗎?


今天我看在 JuluOSDev 論壇上看到 

Descent 問道:寫 os 真的只有組合語言, c/c++ 可以完成嗎?別的語言無法用來寫 os 嗎?
(本文同步回覆於論壇)

以下是我參考一些文章翻譯及一點自已小心得總和而來。

其實是也不是,對所有語言來說最終會轉換machine code (大部分會產生中間的assembly)。
換個精確一點的問法:「我們可能使用更高階的語言來寫OS嗎?」

答案不是絕對的,因人而異。

排列比較答案後,大部分想使用高階語言來寫OS,是想簡化學習的曲線,避掉一些瑣碎細節,來享受快速開發的好處。

但憑心而論,學習沒有捷徑,天道酬勤;
還是需要大量的作業系統設計的基礎(如網路通信協定、記憶體管理、執行緒、驅動程式等等),
畢竟不會使用舊的方法的問題所在;無法創造新的路出來。

從技術的觀點來看,電腦其實並不知道你使用的是C#,還是JAVA;

首先你第一個要的是一個 bootloader, 
如果略過bootloader 的部分,你可以用任何語言來寫OS,

假設所使用的語言可以編譯出機器語言(而不是byte code,但有人可能反駁說硬體有JVM chip,可能也是成立的,視環境而定)。

另一方面,從效能的觀點,OS常需要精實而高效率的,
這部分高階語言無法為你做的,很有可能你會需要自行開適合的編譯器或其他的子系統來輔助,因為在和硬體溝通的部分若沒有低階語言存取能力,事情可能變得更複雜一些。

最後,就我個人而言,也夢想有一天,自已能用 python 或 nodejs 等語言來寫出OS來。

以下是大略列出(但不限),其他語言可用來寫OS:


* Forth -- http://www.forth.org/svfig/osf.html
ref: http://en.wikipedia.org/wiki/Forth_(programming_language)

* Lisp -- Genera is a commercial operating system
ref: http://en.wikipedia.org/wiki/Genera_(operating_system)

* JAVA: JNode
ref: http://www.jnode.org/
ref: http://www.jopdesign.com/ (Java Optimized Processor)

* C#: Singularity
ref: http://research.microsoft.com/en-us/projects/singularity/

* Ada: MaRTE OS
ref: MaRTE OS: An Ada Kernel for Real-Time Embedded ... - CiteSeerX
ref: http://marte.unican.es/


參考資料:
*stackoverflow - 627095/can a whole operating system be written without using even one line of c c code

*High level Languages and IO Access in Computer Interfacing﹣ osdever.net/tutorials/pdf/high_level_io.pdf

* System Programming in a High Level Language - Andrew D Birrell ﹣ http://birrell.org/andrew/papers/thesis.pdf

* wikipedia Operating system

* stackoverflow - 3317329/what language is used to write operating systems windows
* quora.com/What programming language are operating systems written in


以上寫了一堆,希望有所幫助。

2012年7月25日 星期三

F4OS與STM32F407的那些事兒?


源起,最近看到STM32F407這塊板子CPU 168MHz,性價比很高,手滑買了下來。


這塊板子上有個高手(Michael Pratt)正在認真地開發上面的作業系統,專案名為F4OS,源碼開放在GitHub。歷經三個多月,目前成品可直接在USART1跑一個只有一個uname 指令的shell。

在嵌入式無螢幕的裝置上,開發OS,最難的地方便是在沒有任何輸出之前的階段,把Terminal Console弄出來。

首先,Michael 開發是最先利用板子上的LED的明暗速度來進行偵錯。

筆者大約在6月份時,第一次用F4OS便是將LED 的明暗做調整,
接著用ARM的GDB來觀察暫存器值的變化,這真是黑暗前期。

直到最近,當看到Terminal輸出的畫面的一刻,真是令人十分感動。

USB2TTL

筆者使用的是  FT232 USB-Serial 的裝置
使用lsb 命令結果

~$ lsusb
Bus 002 Device 022: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Bus 002 Device 021: ID 0483:3748 SGS Thomson Microelectronics
Bus 002 Device 002: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

STM32F407 + F4OS輸出畫面


執行uname -a 的輸出結果:

$ uname -a
F40S rev 143 Wed Jul 25 22:36:20 CST 2012

USB2TTL 與 STM32407 的連接

使用杜邦端子線來連接USB2TTL及STM32,之前一直卡在這裡;故特別對接法做個記錄。

STM32 Pin   ----    USB2TTL
PB6 (TX)  <------------> RX
PB7 (RX)  <------------> TX
GND  <-----------------> GND
(註:GND 線不接也可正常運作)

小結

有了Terminal 輸出的功能之後,開始進行其他實驗就十分的方便。
以上記錄目前的學習進度。


2012年5月21日 星期一

實作第一個BenOS 系統呼叫 puts

最近很久沒有更新BenOS的訊息,最近專注在研讀MIT-OSE 課程。

本次仿造 MIT-OSE JOS 中的系統呼叫,
筆者為自己小OS加新功能,算是對最近學習的一個驗證。

實作程式碼在 https://github.com/benwei/bos (develop branch)。

讓我們先來看JOS的系統呼叫的概念圖:
 可參考Lab3 JOS 實作程式碼在branch lab3 https://github.com/benwei/MIT-JOS

Lab3 JOS syscall calling sequence

執行步驟:
  1. lib/libmain.c:17 呼叫 sys_getenvid()
  2. lib/syscall.c:61 呼叫 syscall(SYS_getenvid)
  3. lib/syscall.c:23 呼叫48號中斷 帶入系統呼叫SYS_getenvid(2) 號
  4. 發生中斷 kern/trapentry.S:98, 將返回值0及 系統呼叫SYS_getenvid(2) 號放入堆疊,
  5. 跳至 kern/trapentry.S:312 _alltraps中,將相關的暫存器放入堆疊,接著執行332行trap(%esp), %esp == struct Trapframe *tf
  6. 為避免重覆執行中斷, kern/trap.c:200, eflags & FL_IF == 0 必須為真,204行檢查只否由使用者空間進入(tf->tf_cs & 3) == 3, 將tf 複製到核心空間保存;執行220行trap_dispatch()
  7. 執行trap.c:172 核心的syscall() 在 kern/syscall.c
  8. 跳至kern/syscall.c:87 執行 sys_getenvid(), 取得 curenv->env_id
  9. 返回trapdispatch, 執行kern/env.c:520 env_run 中 env_pop_tf()
  10. 呼叫kern/env.c:502 重新設置返回值及相關暫存器
  11. 於kern/env.c:507 執行iret 結束系統呼叫中斷
  12. 回到使用者空間,lib/syscall.c:34 檢查回傳值等等,完成一個呼叫流程
(注意:在lib/syscall.c:23及 TRAPHANDLER_NOEC&_alltrap 放入堆疊的數量與env_pop_tf 取回堆疊的數值必須一致,否則系統將發生不可預的行為。)

BenOS 實作


本次只先實作部分 kernel thread 間的系統呼叫,尚無ring3 至ring 0之間的權限切換。

詳見 user/libsyscall.c:10 系統呼叫:int TRAP_SYSCALL(68) , 其中 BSYS_PUTS(8)

1 #include "user/syscall.h"
2 #include "stdio.h"
3
4 /*
5  * num: BSYS_PUTS, a1 is string for display, a2 is undefined.
6  */
7 unsigned int syscall(int num, unsigned int a1, unsigned int a2)
8 {
9         unsigned int ret = 0;
10          __asm __volatile(
11                 "int %1\n"
12                 :"=a" (ret)
13                 :"i" (TRAP_SYSCALL),
14                  "a" (num),
15                  "d" (a1),
16                  "c" (a2)
17                 :"cc", "memory");
18         printf("syscall with ret=%d\n", ret);
19         return ret;
20 }
21
22 void uputs(const char *msg)
23 {
24         syscall(BSYS_PUTS, (unsigned int)msg, 202);
25 }

在kernel/osfunc.s:126 使用nasm 語法寫成,IDT 中斷呼叫256個函式庫。

其中osfunc.s:400 為減少堆疊使用,僅使用三個參數。
(註:將JOS 中的env_pop_tf 改寫成409~413,較易於理解)

400 _all_trap_handler:
401         push eax
402         push edx
403         push ecx
404
405         push esp
406         call trap_handler
407         add  esp, 4
408
409         pop ecx
410         pop edx
411         add esp, 4 ; no pop eax for return code
412         add esp, 8
413         iretd

kernel/trap.c
70 int trap_handler(struct trapframe *tf)
71 {
72         switch(tf->trapno) {
73         case TRAP_SYSCALL:
74                 print_tf(tf);
75
76                 return kern_syscall(tf->regs.eax,
77                              tf->regs.edx,
78                              tf->regs.ecx);
79                 break;
80         default:
81                 print_tf(tf);
82                 panic("panic: system halt\n");
83         }
84         return 0;
85 }

kernel/ksyscall.c
6 int kern_syscall(uint32_t num, uint32_t a1, uint32_t a2)
7 {
8         int ret = 0;
9         if (num == BSYS_PUTS) {
10                 do {
11                 struct task *t = get_now_task();
12                 printf("task_id(%d) syscall(BSYS_PUTS,a2=%d),a1: %s\n", t->pid, a2, a1);
13                 ret = strlen(a1);
14                 } while(0);
15         }
16         return ret;
17 }

執行結果:

開機完成至bos$ 下,執行run 來執行task 2 (events: hello_main)

0521_BOS


小結


本次的系統呼叫的基本框架,以最精簡的部分,實作出來。

筆者正在嘗試加入ring3 至 ring0 時,
在windows的qemu 0.13版,執行run 命令,qemu系統自動重新啟動bos;
但在MAC OS X 中使用qemu 0.12.5 執行同樣測試時,
qemu 會顯示正確存取權限失敗,
因為bos在ring3 中直接呼叫ring0函式。之後,會對使用者權限切換部分繼續實作。

有任何問題建議,歡迎至 http://www.juluos.org or http://julu.staros.mobi  中的Juluosdev google groups 參與討論。

2011年10月14日 星期五

在Mac OS X初次使用Arduino實驗板

今天在HackingThursday 聚會,朋友借了一塊Arduino Mega 2560實驗板,現場測試。本文便是將開發設定相關心得做個紀錄。
當然可參考原文的說明手冊
首先至http://arduino.cc/en/Main/Software此下載Mac OS X安裝檔http://arduino.googlecode.com/files/arduino-0022.dmg
arduino_install1
開啟dmg檔案後,便會出現上列,將Arduino 圖示,拖曳到Applications(應用程式目錄),再安裝USB 序列埠驅動程式,如下,依指示安裝。
  arduino_Install_FTD_Driver
先使用USB連接線,連接Mac及2560實驗板,會出現偵測到新網路介面,按cancel 取消即可,不需進行此項設定。
IMG_1442Arduino Mega 2560 Modem in usb detected
再來到Applications 目錄中,找到並執行Arduino整合開發應用程式。
Arduino_in_Applications_dir
Arduino 整合開發環境是以Java開發而成,加上AVR gcc/g++ …的跨平台編譯器及相關設定所組成。
在Arduino設定,注意事項中,先由選單,選擇[Tools] –> [Board] –> [Arduino Mega 2560] (請依網友們的開發板型號,挑選)
arduino_select_hardware
緊接著設定USB 序列埠,先由選單,選擇[Tools] –>[Serial Port]->[/dev/tty.usbmodemfd121] (請依網友們的開發板型號,挑選)
 Arduino_select_the_serial_port
好戲上場,在Arduino中,已準備許多範例程式可供參考,選取視窗上方按鈕[Open]->[1.Basics]->[Blink],
 Arduino_selected_1.Basics_Blink.sample
即出現下方畫面,中央為範例程式碼。最後執行[Upload]鈕(右方數來第二按鈕),立刻編譯並上傳到開發板。(在傳送過程式中,TX燈會閃爍,完成後,即啟動閃爍程式,令13腳位LED每隔一秒閃爍一次。
arduino_Blink_LED_Uploading
若無其他3.3V LED可連13及GND腳位時,可參考下圖,USB Port右方,紅色燈號亦作用與在13pin插LED相同。
 IMG_1445 IMG_1448
結論
Arduino設計非常易於使用,並且有相當多的相容擴充元件可供使用,很適合不太熟悉程式設計及硬體的人來使用。

2011年10月1日 星期六

ARM Linux 開發環境設定指南

debian-arm-booting 
最近在工作上,需要用到ARM相關平台,所以花時間研究 ARM CPU 架構的開發環境,
其中硬體商(目前開發板:Friendly ARM Tiny6410)提供的部分程式必須在Windows 上才可執行。
故筆者想能不能在windows 及ubuntu-linux 中,也可各有一個模擬arm 的開發平台,可直接編譯程式而不需要使用cross-compiler(簡言之,如在windows平台上,使用ARM虛擬機器編譯arm執行檔)。
經過搜尋網上資料後,發現有一套件debian armel可供使用,且很貼心的提供可利用qemu arm來直接載入使用,大大減少重新編譯的時間。

設定步驟


安裝QEMU
下載debian-armel
檔案所在位置:http://people.debian.org/~aurel32/qemu/armel/
 a3853606c5762d41bb245aaeb8823996  debian_lenny_armel_desktop.qcow2
  dce9f0d2855d57b79b63bcf3a9ecd51d  debian_lenny_armel_standard.qcow2
  a6d0dde54fb27254e2b8d94736889462  initrd.img-2.6.26-2-versatile
  1969e2a0ffc571ccf6024dc7c842d4dd  vmlinuz-2.6.26-2-versatile
  c5f9039b463e07852055071ac118320a  debian_squeeze_armel_desktop.qcow2
  b7807306c4c79aaa9a423119f4633ffb  debian_squeeze_armel_standard.qcow2
  f73e83b8e48bd422457dafeb8afe7fc6  initrd.img-2.6.32-5-versatile
  8b33324f99d13dc71d6ad060db2fd60a  vmlinuz-2.6.32-5-versatile

筆者所使用的檔案組合如下表:
下載檔案說明
initrd.img-2.6.32-5-versatile初始化並啟動附加檔案
vmlinuz-2.6.32-5-versatile系統啟動用linux 核心
debian_squeeze_armel_standard.qcowdebian squeeze 標準系統映像檔(可寫入更新資料)


執行debian arm linux
開機完成後,預設登入帳號及密碼皆為root。
debian-arm-login

執行腳本檔
此腳本用來執行debian-armel,及相關必要參數。
run.sh
#!/bin/sh
export PATH="$PATH:/usr/local/qemu/bin"
PLATFORM="`uname -s | cut -d'_' -f1`"
QEMUEXE="qemu-system-arm"
if [ "$PLATFORM" = "CYGWIN" ] ; then
    QEMUEXE=${QEMUEXE}.exe
fi
img=debian_squeeze_armel_standard.qcow2
$QEMUEXE -M versatilepb  -kernel vmlinuz-versatile -initrd initrd.gz -m 256 -hda $img -append 'root=/dev/sda1' -redir tcp:2200::22

使用腳本檔案前用先將,下列檔案更名:

  • initrd.img-2.6.32-5-versatile  改為 initrd.gz
  • vmlinuz-2.6.32-5-versatile 改為 vmlinuz-versatile

進入到run.sh 所在目錄,並執行下列腳本檔

sh run.sh

註一:當在使用apt-get install gcc g++ 時,發生找不到檔案的情形。
解決方法: apt-get update –fix-missing
註二:因為qemu 網路架構原設計,需使用-redir 參數用來將Guest OS(debian-arm) 的ssh 22 port 轉到本機2200port。(記得debian-arm中,執行 apt-get install openssh-server來安裝ssh server)

結論
當筆者完成所有步驟後,等於擁有一台虛擬ARM機器,且為一包含完整開發軟體的LINUX系統。
若網友們所寫的程式無特別額外ARM硬體需求,則可直接在上面開發偵錯,可減少arm程式複製到arm 板子上的時間。

2011年9月5日 星期一

啟用e100 (i82559er)網路卡在自製Bos

bos_i82559er_enabled 續上篇自製BenOS支援lspci 命令,參考MIT OSE Lab6: Network Driver 及其中各項文件,且參照相關Linux網路驅動程式設計,目前已整合實作82559er網路卡驅動至BOS v0.21中。
新增及修改下列檔案:
pcireg.h PCI相關參數標頭檔,引用自NetBSD,源自MIT OSE LAB
pci.c 移植Lab6 kern/pci.c
net_e100.h 參考Lab6相關實作資料
net_e100.c 參考Lab6相關實作資料
teset/Makefile   已修改以i82559er為參數,啟動qemu :
qemu -fda "../bos.img" -net user -net nic,model=i82559er
執行後結果,如文頭畫面。

啟用e100
其中pci.c,如何啟用e100 82559er 簡略原始碼如下:
pci_func_enable(pci_pdata_t f) {
        pci_conf_write(f, PCI_COMMAND_STATUS_REG,
                       PCI_COMMAND_IO_ENABLE |
                       PCI_COMMAND_MEM_ENABLE |
                       PCI_COMMAND_MASTER_ENABLE);
        for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
             bar += bar_width)
        {
                uint32_t oldv = pci_conf_read(f, bar);
                bar_width = 4;
                pci_conf_write(f, bar, 0xffffffff);
                uint32_t rv = pci_conf_read(f, bar);
                if (rv == 0)   continue;
                int regnum = PCI_MAPREG_NUM(bar);
                if (PCI_MAPREG_TYPE(rv) == PCI_MAPREG_TYPE_MEM) {
                        if (PCI_MAPREG_MEM_TYPE(rv) == PCI_MAPREG_MEM_TYPE_64BIT)
                                bar_width = 8;
                        size = PCI_MAPREG_MEM_SIZE(rv);
                        base = PCI_MAPREG_MEM_ADDR(oldv);
                } else {
                        size = PCI_MAPREG_IO_SIZE(rv);
                        base = PCI_MAPREG_IO_ADDR(oldv);
                }
       pci_conf_write(f, bar, oldv);
       f->addr_base[regnum] = base;
       f->addr_size[regnum] = size; }

net_e100.c
啟用後,這時便用使用到 io region 1: 0xc040,長度為64位元組,參考Intel 82559,來進行下列操作。
需要將e100 做軟體重置(可參e100_reset函式),因使用DMA Rings,
所以接著要掛上傳送的緩衝區Control Block List(CBL)及接收用的緩衝區Receive Frame Area(RFA),可參考cbl_init()及rfa_init()。



net 命令
在起動Bos v0.21後,輸入net 指令,可看到下列結果:
bos$ net
PCI function 00:18.0 (8086:1209) enabled
mem region 0: 4096 bytes at 0xf2020000
io region 1: 64 bytes at 0xc040
cbl avail = 9, wait = 1, slot = 0x420000, irq=11
rfa avail = 10, wait = 0, slot = 0x420050
其中黃色標記三項資訊,在對網路卡設備進行操作時,會使用到。


結語
原使用e100設備序號,並不生效;後來研究OSE資料後,發現必須在qemu參數中設定,之後再使用設備序號1209來啟用e100(i82559er),如此才能正確執行在qemu環境。
MIT OSE Lab6十分具有挑戰性,筆者經幾天的努力才把這網路卡驅動部分實作完成;但大約只完成Lab6的三分之二,其餘部分,待9/6社群活動後,再來討論後面部分旳細節。本次程式碼可由此下載。

2011年8月29日 星期一

自製BenOS支援lspci 命令

image
在實現網路支援之前,必須先能使用PCI Bus來找到網路卡相關資訊,
參考OSDev.org的"Where I can find Programming Info on PCI?”一文後,
筆者已在Bos實現了lspci 命令,參考"Configuration Mechanism #1”完成,下列程式,
其實一開始,最先遇到問題部分是如何讀取PCI?
原文使用sysOutLong() 和sysInLong(), 對照MIT OSE Lab相關資料,實作如下:
static __inline uint32_t inl(int port)
{
        uint32_t data;
        __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
        return data;
}
static __inline void outl(int port, uint32_t data)
{
        __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
}
筆者也試了一下NASM的寫法如下:
        global _inl, _outl
;uint32_t _intl(int port)
_inl:
        mov  edx, [esp+4]
        mov  eax, 0
        in eax, dx
        ret
;void _outl(int port, uint32_t data)
_outl:
        mov  edx, [esp+4]  ; io port
        mov  eax, [esp+8]  ; data
        out  dx, eax
        ret
之後,實作pci_conf_readl與pci_conf_readw,先試作讀取的部分:
完整程式碼請參照kernel/pci.c和kernel/osfunc.s,從GitHub 上bos下載。

結論

在程式實作過程中,只要依照PCI所定義的資料表,將所需要的資料取出,存到一個PCI資訊的陣列中。
當有需要時,再從PCI 資訊陣列中取出相對應的記錄一一列出便可得到文章開頭的螢幕畫面。
其中一筆如下:
vendor:0x8086, devid:0x100E, class:0200(Network Controller), rev=3
0x100E指得便是e100的Intel網路卡。而它便是筆者正在研究議題的網路卡資訊來源之一, 提供網路實作使用。

(註一:軟語錄:"提高程式設計功力的方法無它,便是不斷地實作與追踪偵錯。")
(註二:此次9/6活動,筆者將分享最近在研究網路實作的心得,歡迎來切磋指教。)

2011年8月25日 星期四

在Cygwin中設定並使用Qemu

mintty_cygwin_qemu
在看完前三篇編繹BOS文章之後,眼尖的讀者,應該有發現在Linux和MAC OS X平台都是使用qemu 來執行;可是一到Windows 怎麼變成VMWare Player呢!其實筆者曾試著編繹cygwin版的qemu, 卻有太多問題要解決,為求效率;使用其他虛擬機軟體來代替。
這篇算是補完"自製開發BenOS支援Windows+Cygwin"一文。

1. 下載所需qemu工具

在使用谷歌大神後,Qemu.org的友站連結中的非官方版已預先編繹好的程式,找到qemu 0.13版,由此下載 。(感謝他的分享,筆者少花數小時生命。)


2. 安裝Qemu
在下載完qemu-0.13.0-windows.zip後,將它解壓縮到cygwin安裝目錄中。
就筆者環境來說,路徑為C:\cygwin\usr\local\qemu
3. 開啟cygwin命令視窗
加入下列指令到 /etc/bash.bashrc
export PATH=/usr/local/qemu:$PATH
4. 重新開啟cygwin命令視窗
下載最新版bos,執行下列指令,便可看到如上所示執行畫面:
make run
本次在程式碼的編繹腳本修改所使用命令為qemu,主因是此版本qemu-system-x86_64.exe無法正常運作,但qemu卻是正常工作。
@@ -9,7 +9,7 @@ endif
all: run
run:
-ifeq ($(KNAME),CYGWIN)
+ifeq ($(KNAME),$(KNAME_CYGWIN))
        qemu -fda "$(IMG_NAME)"
else
        qemu-system-x86_64 -boot a -M $(MACHINE) -fda "$(IMG_NAME)"
結語

筆者歸納了最近使編繹流程跨平台的經驗,列出幾點供大家參考:
  1. 先到網上花5分鐘找看看,有無編繹好的開發用軟體;
  2. 如果沒有,看看有無編繹經驗分享,
  3. 也無經驗分享,最後才是自己編繹一版。
保持分享的美德,把編繹好的工具,公布出來。如此一來,基於眾人成果,大家互相會受益於時間成本的大大縮短。
當然這也筆者撰文的原因之一。

註:此次報名網址已建置好,請由此報名9/6星系主題活動。

更新0825

Dennis 有提出:
我覺得應該找qemu for win32, 用vc++或mingw compile。因為cygwin有些posix api模擬,並沒有做得很好,用native win32 api比較順。而且我很久以前有試過這個 http://www.h7.dion.ne.jp/~qemu-win/ ,它應該可以work。

ben 想:
不過這個qemu-win網址編繹的版本0.9.0有點老而且已停止更新,其實我文章中所用Qemu 可能同一人所維護,只是文中使用連結是較新的版本。若要最新版本,需要的人就要自行編繹了。


2011年8月23日 星期二

在Mac OS X上編繹BenOS並使用Qemu執行

bos_run_at_osx

續上篇自製開發BenOS支援Windows+Cygwin後,發現Mac上的使用者(當然筆者也是其中之一,不才也是半個蘋果迷)也想能直接編繹(另一個原因是,不想再開另一個Linux 虛擬機,太耗資源及電力,環保一下吧),於是乎有了這篇文章。

編繹環境設定

筆者的Mac 是Snow Leopard 10.6.8

1. 安裝Xcode

到http://developer.apple.com/下載並安裝Xcode (筆者用的是4.0.2)

2. 安裝HomeBrew

請參考把常用的UNIX 環境重建到MAC OS X (1) 一文。

3. 使用brew 安裝 nasm 和qemu

sudo brew install nasm qemu git

4.安裝cross gcc

測試使用Xcode 的gcc,並發現不能做完整靜態連結。也不能輸出ELF檔案。

正想把最後殺手鐧拿來,自己編繹gcc時,心血來潮google 一下,

發現下列的站台,有專門編繹給Mac OS X,二話不說,馬上拿來用,節省不少時間。

可從此處下載http://crossgcc.rts-software.org/doku.php

dmg 安裝至目錄

gcc-4.5.2-for-linux32.dmg (65.2 MB)

/usr/local/gcc-4.5.2-for-linux32/
gcc-4.5.2-for-linux64.dmg (71.7 MB) /usr/local/gcc-4.5.2-for-linux64/

筆者安裝是64位元版,但在編繹時需要加上-m32, 因為目前bos 尚未相容64位元模式。

5. 安裝mtools

在編繹過程,只有一個小問題,便是找不到iconv,極可能是script 的bug,加上-liconv,即可通過編繹。

另外為求保險,去除不必要的變數,故加上-arch i386,產生mtools i386 版。

env CFLAGS="-arch i386" LDFLAGS="-arch i386 -liconv" ./configure
make
sudo make install

結語

如此一來,便可在OSX上編繹及執行,可參考開頭畫面。

再則,感謝google 大神,讓我能省去編繹 toolchain時間。相對windows 來說,Mac OS X 對Unix-like開發者,較為友善。

然後,到本文筆者便寫完三個主要平台的OS開發環境Linux、Windows、OSX上設定。

希望對大家有所幫助,少走一彎路。

最後,筆者因為以前工作屬工友級,所以需要什麼,就學什麼。

想請問大家最常使用什麼平台和工具來進行程式開發呢?

說不定有更好的組合提高您的生產力;一人技窮,二人技長;快提出來大家討論,集思廣益吧。

註一:下次的大聚會9/6,有重量級的OS長老駕到,可來吸收一甲子功力,請大家踴躍參加。

註二:此次9/6活動已加入TOSSUG行程(請參閱http://www.tossug.org/2011)

2011年8月21日 星期日

自製開發BenOS支援Windows+Cygwin


vmplayer_bos_run
繼上篇"自製作業系統原始碼公佈"後,發現讀者們使用Windows系統比例高達7成。
筆者便在想,讓自製的小系統也能直接在Windows 裡編繹並使用其虛擬機器執行。
1. 安裝Cygwin
(但Cygwin 所附的bash login console 介面,限制頗多,不太方便,所以下載mintty來使用 (它以putty程式碼修改而來)。
在安裝過程中,請記得選取並安裝gcc 和nasm套件,用來編繹主程式及組合語言部分。
2. 安裝mtools
在Bos v0.2後,使用了mcopy。可參考 英文原文或此文下載安裝。
3. 安裝 git + pagent.exe
因為要使用github,而其中需要使用上傳檔案的key,
所以利用pagent.exe 將key提供給git 使用。(試過使用ssh,但不能正常工作)
目前筆者在使用github 前,使用下列命令將key載入,
bash file: load_pagent_with_key
/cygdrive/c/yourpath/pageant.exe "c:\\youpath\\your_key_generate_by_puttygen.ppk" &
接著pagent.exe 會跳出輸入密碼的視窗,輸入後便載入完成。
記得使用完github,要將下列PAgent 圖示,按滑鼠右鍵,選Exit結束程式。




4. 下載 BOS v0.2 原始碼
使用git 前,請確認GIT_SSH環境變數:
$ export | grep GIT
declare -x GIT_SSH="C:\\yourpath\\plink.exe"
註:可在Windos 系統內容->進階->環境變數->系統變數 中修改GIT_SSH。
請下載最近原始碼
$ git clone git@github.com:benwei/bos.git
Initialized empty Git repository in C:/src/
github/bos/.git/
remote: Counting objects: 65, done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 65 (delta 5), reused 63 (delta 3) KiB/s
Receiving objects: 100% (65/65), 32.73 KiB | 31 KiB/s, done.
Resolving deltas: 100% (5/5), done.
5. 編繹Bos
$ make
… ignored
nasm -f elf32 kernel/main.s -o kernel/main.o -Iinclude/ # -l kernel/main.lst
nasm -f elf32 kernel/osfunc.s -o kernel/osfunc.o -Iinclude/ # -l kernel/osfunc
.lst
ld -nostdlib -static -e _start --no-undefined -X -T ld-script.lds -Map MYOS.map
-o myos.elf kernel/init.o kernel/kthread.o lib/describtbl.o lib/fifo.o lib/file.
o lib/floppy.o lib/interrupt.o lib/keyboard.o lib/memory.o lib/mtask.o lib/timer
.o blibc/screen.o blibc/stdio.o blibc/string.o apps/bshell.o kernel/main.o kerne
l/osfunc.o
ld: cannot perform PE operations on non PE output file 'myos.elf'.
make: *** [myos.elf] Error 1
在編繹過程發現原本由CYGWIN所安裝的gcc 只支援PE 格式,所編繹出來的obj file 格式為 Windows coff @.@。
但main.s同時包含16位元與32位元程式碼用以進入32位元保護模式, 所以會產生下列錯誤。
$ make CYGWIN=1
nasm -f win32 kernel/main.s -o kernel/main.o -Iinclude/ # -l kernel/main.lst
begdt.inc:24: error: COFF format does not support non-32-bit relocations
kernel/main.s:75: error: COFF format does not support non-32-bit relocations
kernel/main.s:89: error: COFF format does not support non-32-bit relocations
make: *** [kernel/main.o] Error 1
目前編繹obj檔案格式參照
$ file bos/kernel/init.o
bos/kernel/init.o: MS Windows COFF Intel 80386 object file
$ file bos/kernel/main.o
bos/kernel/main.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
目前解決方法有二:
1. 改寫main.s 將進保護模式部分移到開機程式中,使其能順利使用 nasm –f win32 編繹。
2. 使用cross compiler, 參考OSDev.og文章GCC Cross Compiler
筆者選擇使用方法二,主因是BOS可能會支援ARM或其他平台。看了此篇Cross-Compiler Successful Builds。
使用binutils-2.20 + gcc-4.4.3 的組合,編繹了一版ToolChain,由此下載。
cygwin_toolchain4_bos0821.tgz (md5sum: e06bdccb2c44c4cc65097399e8722d95)
$ cd /
$ tar zxvf <your download path>/cygwin_toolchain4_bos0821.tgz
已修改使用新的Toolchain, 下列為編繹成功範例。
$ make
nasm -o bootldr.elf boot/bootldr.s -I include
nasm -f elf32 kernel/main.s -o kernel/main.o -Iinclude/ # -l kernel/main.lst
nasm -f elf32 kernel/osfunc.s -o kernel/osfunc.o -Iinclude/ # -l kernel/osfun
.lst
building [kernel/init.c] -> [kernel/init.o]
building [kernel/kthread.c] -> [kernel/kthread.o]
building [lib/describtbl.c] -> [lib/describtbl.o]
building [lib/fifo.c] -> [lib/fifo.o]
building [lib/file.c] -> [lib/file.o]
building [lib/floppy.c] -> [lib/floppy.o]
building [lib/interrupt.c] -> [lib/interrupt.o]
building [lib/keyboard.c] -> [lib/keyboard.o]
building [lib/memory.c] -> [lib/memory.o]
building [lib/mtask.c] -> [lib/mtask.o]
building [lib/timer.c] -> [lib/timer.o]
building [blibc/screen.c] -> [blibc/screen.o]
building [blibc/stdio.c] -> [blibc/stdio.o]
building [blibc/string.c] -> [blibc/string.o]
building [apps/bshell.c] -> [apps/bshell.o]
/usr/local/cross/bin/i586-elf-ld -nostdlib -static -e _start -s -Ttext 500 -Map
MYOS.map -o myos.elf kernel/main.o kernel/osfunc.o kernel/init.o kernel/kthrea
.o lib/describtbl.o lib/fifo.o lib/file.o lib/floppy.o lib/interrupt.o lib/keyb
ard.o lib/memory.o lib/mtask.o lib/timer.o blibc/screen.o blibc/stdio.o blibc/s
ring.o apps/bshell.o
echo "convert myos.elf MYOS.BIN"
convert myos.elf MYOS.BIN
/usr/local/cross/bin/i586-elf-objcopy -I elf32-i386 -O binary -R .pdr -R .note
R .note.gnu.build-id -R .comment -S myos.elf MYOS.BIN
$ make package
dd if=./bootldr.elf of=bos.img seek=0 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000172887 s, 3.0 MB/s
dd if=/dev/zero of="bos.img" seek=1 count=2879
2879+0 records in
2879+0 records out
1474048 bytes (1.5 MB) copied, 0.011148 s, 132 MB/s
mcopy -i "bos.img" "MYOS.BIN" ::
mdir -i "bos.img"
Volume in drive : has no label
Volume Serial Number is A0A1-A2A3
Directory for ::/
MYOS BIN 19576 2011-08-21 21:07
1 file 19 576 bytes
1 437 696 bytes free
在windows 上使用VMware Player來執行, 請建立一新的虛擬機器,
在使用磁片檔部分填入所產生的bos.img 的檔案路徑及名稱,如下所示,
vmplayer_bos
接著執行,便可看到本文開頭的執行畫面。
讀者們若對編繹及執行BOS系統在windows+cygwin上有任何問題?
另外筆者最近寫了許多新文章,這裡有個小問題,請問一下讀者們,有什麼想看的技術主題?
歡迎留言交流。
註:此次9/6活動已加入TOSSUG行程(請參閱http://www.tossug.org/2011)

2011年8月17日 星期三

自製作業系統 BenOS 原始碼公佈

bosv0dot2
最近把自製作業系統原始碼整理一下並修正部分問題,另附寫說明文件後,於今晚,發佈Ben OS v0.2,有興趣的朋友可從GitHub下載原始碼。
程式碼目前已在下列平台編繹並使用Qemu測試:
  • Ubuntu 10.04, 10.10, 11.04
  • Fedora 12
程式目錄說明
apps 應用程式,目前只有一個 bshell
blibc BOS用到的自製的C函式庫
boot 啟動程式
include 標頭檔案
kernel 系統核心相關
lib 核心相關函式庫
scripts 系統開發腳本檔
test 執行測試用
tools 預留工具程式
如何編繹請參閱?
Readme.md
Ubuntu + Qemu在VMWare Fusion Mac問題?
bosv0dot2-howtoquit
當Qemu執行時,跳離的快速鍵將會失效,造成無法正常使用Xwindow,可使用CTRL+ALT+2回到qemu monitor console,再輸入 "quit" + Enter 鍵離開Qemu 視窗。
BOS v0.2 編繹已不需要管理權限?
原來使用mount 磁片檔方式需要管理權限,現已修改為使用 mcopy (mtools)。(感謝社群成員Dennis 提供建議)
註:下次社群活動09/06/2011,詳請參閱社群首頁。
更新0821

2011年5月31日 星期二

自製OS作業系統所需基本知識?

繼上篇,參考 wiki.osdev.org的OS開發之始一文,加入本人的心得寫了在OS開發中所需要的基礎。
(圖:引用自Wikipedia)


就實際上來說,寫OS向來被認為是一件十分困難且複雜的事。初學程式設計者,並不適合一開就自製OS。


以下是您必須瞭解的知識:

  • 電腦科學基礎: 你需深入且熟悉16進位和二進位符號之間邏輯運算,以及其他必要知識如:
    • 資料結構,相關的演算法的建立、 操作、搜尋和排序, 程式概念等等。

  • 語言與字彙: 你需能夠略懂讀和寫英文技術文章. 絕大部分從網站找到OS技術文章都以英文寫成。一般而言,中文譯書大約落後英文書二年左右。

  • 語言與字彙: 大部分OS的功能範例在osdev.org是均以程式語言C或C++寫成。假使你選用其他語言像是FreeBASIC或Pascal;但 C 語言是程式設計通用語, 故而你應能以所使用之程式語言來轉換。

  • 組合語言Assembly: 應對組合語言有所瞭解。它是一種與硬體緊密相關的程式設計低階語言。組譯語言是機器語言便於記憶和理解的符號形式。 至少你必須閱讀關於這語言的教程, 並寫過用戶空間(user-space)的應用程式碼以便你能熟悉它。就算你使用更高階語言,你還必須瞭解它,例如bootloader, input/output 程式均少不了它的存在。當然你可將你所慣用的組言語言部分寫成函式,如此一來,便可使用C語言來呼叫(可參考Linux kernel )

  • 程式設計經驗: 你不僅需要知道相關程式語言,且需要瞭解並熟悉版本控制,如何偵錯等等。 簡言之,你必須在你開始寫OS之前,先成功地寫完一些user-space程式。

  • 開發環境:
    • 使用Linux來開發: 你將注意你需要許多 Unix工具。 Linux kernel 是一個常用學習的不錯參考範例,用以瞭解系統如何運作及其設計。 命令提示的工具(如bash 或 ksh等等) 是最低需求,並安裝Toolchain。

    • 使用Window來開發: Cygwin 提供一個簡易的方法來安裝unix開發環境, mingw 為一個精簡的GNU開發環境。


  • 工具集(Toolchain): 你必須瞭解如何使用編譯器(compiler: GCC)、組譯器(assembler: GNU as, NASM, MASM), 連結器(linker: GNU ld)及相關編譯工具(如make)。

  • 可執行的檔案格式: 核心空間(Kernel space)程式設計有許多額外的要求,以提供必要功能來給未知的應用程式開發所使用。故需要解析可執行的二進位檔案 (若你的OS需要載入並執行應用程式),請熟悉可執行檔格式 Executable File Types(其內部結構和如何連結產生)。

  • 自製OS 平台(Platform): 你必須學習相關CPU的說明手冊來寫你的OS所支援的平台. 手冊將包含必要的資訊來設計你的核心 。如x86 (Intel IA-32程式開發英文手冊)

以上心得,僅為拋磚引玉。

2011年5月25日 星期三

精簡版作業系統實戰: 自製OS用Qemu執行

源起一直以來想自己寫一個OS,練練功,去年到今年斷斷續續花了一至兩個月時間,寫了 我自己的陽春作業系統,最近正在整理程式碼做個記錄;證明有達成自己的目標。以下是從我的Xubuntu 10.10 執行benos 使用QEMU的畫面截圖。

qemu-system-x86_64 -boot a -M pc-0.11 -fda /home/ben/osdev/../main.img


畫面左上為Ben OS 執行結果。

目前實作了下列功能:

  1. 簡易的記憶體管理

  2. Timer中斷處理

  3. 鍵盤I/O, 佇列

  4. 多個執行緒的多工切換

  5. 簡單的命令模式 (ps, uname, free, clear, type mem)

  6. 精簡 libc 函式庫
在寫自己小OS過程中,最痛苦的莫過於不知道為什麼OS又沒畫面了。開發期間,學習了不少以前觀念有些模糊的部分,例如:如何進入保護模式、程式執行期權限模式、記憶管理、多工處理等等。
之後可能的研究議題如下:
  • 如何編繹及改寫BenOS支援網路開機方式(PXE)?

  • 如何支援檔案系統從S-ATA 硬碟?
如果想寫自己的OS,如何開始呢?
首先在完全沒有基礎情況,起步是最難的。
其實坊間有多本自製OS的書,以下是本人看過書:
- 偏重Linux 0.01 相關觀念介紹
- 較不適合初學者
- 偏重圖形介面實作,且用到許多自制工具或其他工具
- 較適合進階網友
- 比較全面詳細介紹觀念細節
- 較適合初學者
作業系統開發實戰手冊:以開發一個視窗多工作業系統為例(2011.5)
- 圖形介面實作
- 提供多平台的開發
- 使用大量表格來對照行號,進行解說。
再來最常遇到就是卡關,卡在某一環節良久,無法解決。這時如果有人可以討論,相信情況會大為改善。
在wiki at osdev.org裡有英文文章,如英文尚可考慮精讀,有很多初學者的參考文章。
另外在Jserv's CURT v1 ARM 精簡作業系統一文中,Jserv 留言說有熱心網友將CURT v1移植到i386平台,可供大家參考練習。以上一點淺見,希望對您有所幫助。

更新2011-07-22:
建立共筆用的站台:Julu 作業系統開發協作平台,有興趣的人可留言(改到社群論壇,詳參閱協作平台),歡迎一同編修內容。

更新2011-08-17:

更新2011-12-14
BOS 使用新的bootloader(By Dennis) 以及初步整合VFS(By Wayling) 

2011年4月20日 星期三

讀"Orange's 一個作業系統的實現"的心得

前一陣子花時間看這本書,
這本算是滿適合新手入門的書,
很多觀念說明很清楚,不過要讀本書;還是需要一些基礎:
1.略懂組合語言
使用NASM,作為一些低階操作。
2.C 語言 (絕大部分程式使用。)
3.略懂環境Shell,Gnu Make
Windows 批次檔
Linux: Bash or Csh 等等

從環境設定,到Boot 流程、多執行序、記憶體、檔案系統的實作等等,
許多重要的OS元素均有詳細的介紹。

這本書環境設部分,很貼心的介紹了Linux 及windows 開發環境的設定。
對於不習慣使用Linux的讀者提供另一種選擇。

本人習慣使用Linux 環境,所以電腦環境如下:
OS: XUbuntu 10.10 , 桌面:Xfce
Tool: gcc 4.4.5, GNU Make 3.81, Bash 4.1.5, qemu 0.12.5
Editor: vim + ctags + cscope

一邊看書,一邊利用範例修改編繹,讓自己更容易瞭解,來龍去脈。
其實研究OS的原理,可讓自己更知道系統如何運作,加強自己的功力喔!!!
有空不妨看看!!!

2010年1月27日 星期三

Jserv's CURT v1 ARM 精簡作業系統

以下是我設定作業環境來編繹CURT v1的心得 (rework 2011-04-14)


 A.編繹程式

1. 下載工具
 a. 原 Toolchain for CURT v1


 b. gcc 4.4.1 for  by cyt93cs 



2. 安裝工具 (from sourceryg)
$ md5sum sourceryg++-4.4-93-arm-none-linux-gnueabi.bin
e9b81d6288c29f992f4af3d7c1cbddda sourceryg++-4.4-93-arm-none-linux-gnueabi.bin
$ ./sourceryg++-4.4-93-arm-none-linux-gnueabi.bin
The installer has detected that your system uses the dash shell
as /bin/sh. This shell is not supported by the installer.

You can work around this problem by changing /bin/sh to be a
symbolic link to a supported shell such as bash.

For example, on Ubuntu systems, execute this shell command:
% sudo dpkg-reconfigure -plow dash

Install as /bin/sh? No

3. 接著回到X-window 啟動Sourcery整合作業環境
輸入從codesourcery所申請的試用 license

B. 環境設定

1. 重設一下shell 的執行環境
sudo dpkg-reconfigure -plow dash

2. 安裝qemu-arm-static, qemu-kvm-extras
使用ubuntu 內建的 Synaptic 安裝檔案管理員來進行安裝

 
3. 設定toolchain 所在位置
PATH="/opt/CodeSourcery/sourcery_G++/bin:${PATH}"
export PATH
可由此下載原始碼 (http://blog.linux.org.tw/~jserv/archives/002082.html)
感謝 Jserv 的資訊 http://code.google.com/p/curt-v1-rework/ 主要進一些修改several patches were landed.

C. 編繹 CURT v1
1. 解壓縮程式碼 curt-src-v1.tar.bz2

2. 修正程式碼 device/serial.c第39行 有toolchain 相容問題如下:
if (!xxx && 0x00000040)
correct it to
if ((!xxx) && 0x00000040)

3.編繹
$ cd CuRT_v1/app/shell
$ make
~/CuRT_v1/app/shell$ ./prepare-flash
16384+0 records in
16384+0 records out
16777216 bytes (17 MB) copied, 0.0454887 s, 369 MB/s
16+1 records in
16+1 records out
16980 bytes (17 kB) copied, 4.0371e-05 s, 421 MB/s

D. 執行

~/CuRT_v1/app/shell$ ./run-on-connex
 
 
 
備註:記得要在X-Window 下開啟終端機,才能正確執行qemu-system-arm.

 
參考資料

http://sites.google.com/site/embedded2009/introduction-to-curt-v1
http://blog.linux.org.tw/~jserv/archives/002082.html
http://code.google.com/p/curt-v1-rework/

更新2011-09-18:
 - 其他同好網友文章:CuRT porting到x86成功

更新2012-04-01 相關文章連結
 - http://ccckmit.wikidot.com/os:curtos