跳轉到內容

AROS/開發者/文件

50% developed
來自Wikibooks,開放世界中的開放書籍
AROS Wikibook的導航欄
AROS使用者
AROS使用者文件
AROS使用者常見問題
AROS使用者應用程式
AROS使用者DOS Shell
AROS/使用者/AmigaLegacy
AROS開發文件
AROS開發者文件
從AmigaOS/SDL移植軟體
Zune初學者指南
Zune .MUI類
SDL初學者指南
AROS開發者構建系統
特定平臺
AROS x86完整系統HCL
AROS x86音訊/影片支援
AROS x86網路支援
AROS Intel AMD x86安裝
AROS儲存支援IDE SATA等
AROS Poseidon USB支援
x86-64支援
摩托羅拉68k Amiga支援
Linux和FreeBSD支援
Windows Mingw和MacOSX支援
Android支援
Arm Raspberry Pi支援
PPC Power Architecture
其他
AROS公共許可證

AROS的技術概述

[編輯 | 編輯原始碼]

谷歌翻譯 德語法語義大利語西班牙語印地語中文俄語波蘭語葡萄牙語

AROS,[1]與AmigaOS (TM)類似,是一種訊息傳遞搶佔式多工作業系統

它使用可重入共享庫來節省記憶體空間。

AROS基於一個執行庫核心(Exec)和另外兩個庫

  • Exec(“核心”,在現代意義上它不是核心),
  • Intuition(圖形和GUI,整合到系統中)以及
  • AmigaDOS(磁碟作業系統,Metacomco的Tripos經過修改以與Exec配合使用)。

AmigaDOS和Intuition的設計理念大不相同,前者採用類似C的API,而後者為程式設計師建立了一個面向物件、訊息傳遞感知的環境。系統基礎是AmigaOS中唯一絕對地址(位於0x00000004),這與AROS有所不同,因為AROS SysBase是自動提供的(沒有$4),但其他所有內容都是動態載入的。該作業系統以其與硬體的緊密聯絡而聞名,從而提供了高效能,同時還具有支援可重新定點陣圖形(Cybergraphics)和可重新定位音訊子系統(AHI)的靈活性。

顯示庫與系統關係的圖表需要


請記住,AROS是一個研究作業系統,雖然歡迎對AROS基礎程式碼做出任何貢獻,但對於任何核心更改,請先聯絡開發人員列表。為AROS編寫應用程式沒有此要求。

雖然AROS的外觀和感覺幾乎功能完整,但它仍然缺少Amiga API中少量函式,以及一些核心功能的實現。還有一些使用者應用程式,雖然不是AmigaOS 3.1環境的嚴格組成部分,但也需要編寫。


此執行緒提供設定資訊、文件以及您是否對核心作業系統更改和/或編寫/移植軟體應用程式感興趣

  • 您可以在AROS下直接編譯,AROS可以在真實硬體、虛擬硬體上執行
  • 在Linux/Windows下的託管模式下,從該主機作業系統交叉編譯

用於當前開發版本ABIv1的儲存庫,用於當前穩定PC版本ABIv0(帶有反向移植的ABIv1功能)的儲存庫位於AROS One和基於Icaros x86的發行版中使用的儲存庫

任何錯誤/問題都可以新增

我們在這裡有一個Slack,Discord在Discord@AmigaDev,AROSExec Discord伺服器也可用



AROS軟體開發

[編輯 | 編輯原始碼]

程式語言

[編輯 | 編輯原始碼]

除了主要支援C/C++程式碼的“開發人員環境”之外,AROS還提供了其他程式語言

指令碼

DOS,包含在所有
LUA,包含在所有或Hollywood
REXX Regina(AROS的ARexx),包含在所有
Python [資訊],包含在Icaros中
Ruby 資訊/下載

Basic

Amos Pro 相容 命令(所有不完整)
X-Amos
SDLBasic (下載)
Alvyn (下載)
Basic4SDL (下載)
Project Deimos,
Blitz Basic AROS上沒有
Amiblitz 在JanusUAE Amiga(TM)模擬器上
Amiga Basic
[ ACEBasic]

其他

AmigaE Portable E
FreePascal FPC Aros-Exec 執行緒下載,FreePascal for AROS 有自己的華夏公益教科書
LLVM,


在哪裡獲取 C/C++ 環境

[編輯 | 編輯原始碼]

如果你想為 AROS 開發,通常情況下,執行 Linux 託管的 AROS 開發環境更容易,特別是對於 C++ 來說,交叉編譯程式碼。現在大多數開發人員都是這樣做的。g++ 用於編譯 owb web 瀏覽器以及其他一些 AROS 軟體。如果你希望有一套豐富的為作業系統功能集定義的 C++ 庫或類,你可能會失望。

AROS 本地編譯是可能的,但是你更有可能遇到開發環境中的一些奇怪的錯誤,因為它很少被其他開發者測試和修復。

是否有可用的 sftp 軟體或透過 ssh 的 scp?沒有。沒有。如果至少可以處理安全部分,那會更容易,移植 amissl


來自其他作業系統的交叉編譯器

[編輯 | 編輯原始碼]

預編譯版本的 AROS ABIv0 Linux 託管版本可以在 這裡找到


而且,就像一直以來的情況一樣,你可以使用 contrib 歸檔檔案來“獲取”包含 /native/ AROS gcc 編譯器和工具的開發目錄。該編譯器用於構建 AROS 本身,但可以透過提供帶有指示目錄的 --sysroot 來在 AROS 構建過程之外使用,以交叉編譯 AROS。


你想構建 AROS。沒問題。

以下是 64 位的說明:https://github.com/deadw00d/AROS/blob/master/INSTALL.md

以下是 32 位的說明:https://github.com/deadw00d/AROS/blob/alt-abiv0/INSTALL.md


32 位 Linux 託管 AROS 和為 Linux 編譯 AROS 應用程式,它可以在 64 位 Linux 發行版上無問題地執行,所有當前可用的軟體也將在其上執行


請在繼續下一步之前安裝這些軟體包。以下是基於 Debian 的發行版的參考列表。參考構建系統是 Ubuntu 18.04/20.04 amd64。

subversion git-core gcc g++ make gawk bison flex bzip2 netpbm autoconf automake libx11-dev libxext-dev libc6-dev liblzo2-dev libxxf86vm-dev libpng-dev gcc-multilib libsdl1.2-dev byacc python-mako libxcursor-dev cmake zsh mingw64

在使用者的 home 目錄或使用者具有寫入許可權的其他目錄下執行所有這些操作。

具體來說,在“Linux-i386”部分,請務必首先構建交叉編譯器(toolchain-alt-abiv0-i386),然後才構建 AROS 本身(alt-abiv0-linux-i386)。


克隆和構建

$ mkdir myrepo
$ cd myrepo
$ git clone https://github.com/deadw00d/AROS.git AROS
$ cd AROS
$ git checkout alt-abiv0
$ cd ..
$ cp ./AROS/scripts/rebuild.sh .
$ ./rebuild.sh

現在到下面的構建選擇 - Linux-i386

選擇 toolchain-alt-abiv0-i386 - 選擇 alt-abiv0-linux-i386 (DEBUG)

透過以下方式啟動 AROS

$ cd alt-abiv0-linux-i386/bin/linux-i386/AROS
$ ./Arch/linux/AROSBootstrap


Pc-i386 選擇 toolchain-alt-abiv0-i386(如果尚未構建) - 選擇 alt-abiv0-pc-i386

ISO 映象位於 alt-abiv0-pc-i386/distfiles 中


現在我們有了 Linux 託管的構建,我們可以恢復本地構建(選項 2)。執行 ./rebuild.sh 並選擇選項 2。等待它完成,然後

$ cd alt-abiv0-pc-i386
$ make

現在

$ make bootiso


現在,你的編譯器位於 toolchain-alt-abiv0-i386 目錄中,名為 i386-aros-gcc。包含檔案位於 alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/include 中,庫位於 alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development.lib 中。

這就是如何將其傳遞給編譯器

/home/xxx/toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot /home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development -L/home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/lib

../toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot bin/linux-i386/AROS/Development local/helloworld/helloworld.c -o local/helloworld/helloworld


Slack 開發論壇


另一個 Linux 選項是使用Linux 的交叉編譯器

另一種方法是使用 Debian 等發行版並下載 gimmearos.sh 指令碼(在 aros-archives 上)透過下載必要的軟體包來設定開發環境……gimmearos 指令碼是朝這個方向邁出的良好第一步,構建交叉編譯器和託管的 AROS 環境,但 gimmearos.sh 可能已過時或與任何給定的 Linux 發行版不完全相容。

為此,你必須自己編譯 AROS。下載 AROS 原始碼歸檔檔案,而不是 contrib。透過進入主目錄編譯 AROS

./configure
make

(更多關於編譯 AROS 的資訊)。結果將是一個沒有開發工具的基本 AROS 系統。

要在 Linux 上編譯 C++,請鍵入“make gnu-contrib-crosstools”,在 ./bin/linux-i386/tools/ 中建立交叉編譯器,命名為 i386-aros-gcc 等。

注意:目前,要使交叉編譯器可用,請將 tools/ 中的“collect-aros”複製到 tools/i386-aros/bin/ 中。目前,如果從 Linux 命令列使用交叉編譯器,則只有在它位於那裡時才會找到它。

如果你想編譯本地編譯器(開發環境),請鍵入“make contrib-gnu-gcc”,在 AROS 的 System:Development/bin 目錄中建立本地編譯器。

當輸出需要被剝離時 --strip-unneeded --remove-section .comment

Obj-C 後端應該開箱即用。

開啟 contrib/gnu/gcc/mmakefile.src 並搜尋包含“--enable-languages”的行,並將“objc”新增到其後的語言列表中。

   --enable-languages=c,c++,objc

最好將其設為 —enable-languages=c,c++,objc,obj-c++

一旦你嘗試使用異常,ObjC++ 就會崩潰,但這可能會在未來的 GCC 版本中發生變化,而且它在那裡不會造成任何傷害。



你需要交叉編譯器還是真正的編譯器?在第一種情況下,你只需下載適當的 gcc 歸檔檔案,應用補丁並繼續進行正常的 gcc 構建即可。在真正的交叉編譯器的情況下,下載 contrib 原始碼時,還需要下載普通原始碼,將 contrib 原始碼放置到名為 contrib 的目錄中,需要安裝 autoconf+automake+perl+python,呼叫 ./configure,進入子目錄並鍵入 make。

重新構建 GCC,其中 host == build == target == i386-pc-aros。所以只需獲取普通原始碼並應用補丁,而無需擔心構建系統?


預配置的 VM 環境 vmware 虛擬機器,用於開發 AROS 和 AROS 軟體



64 位

首先你需要一個 Linux 系統,建議使用 Ubuntu,並安裝 cmake 和 x86_64-aros 交叉編譯器。為了獲得交叉編譯器,你需要在該機器上本地構建 AROS(linux-x86_64 或 pc-x86_64,我建議使用 linux-x86_64)。AROS 的構建說明可以在此處找到:http://aros.sourceforge.net/documentation/developers/compiling.php

一旦你擁有了交叉編譯器並使其可用,我們就可以繼續了。

如何 建立 AROS 開發環境,如果你想自己動手


一個開始使用 Icaros 64 的中心頁面 https://vmwaros.blogspot.com/p/64-bit.html


32 位

一個適用於多種作業系統的不錯選擇是 AxRuntime 允許開發人員將其基於 Amiga API 的應用程式編譯為 Linux 二進位制檔案,能夠利用 Linux 上可用的現代開發工具,例如 IDE、偵錯程式、分析器等


AROS 的本地編譯器

[編輯 | 編輯原始碼]

即,C 的 gcc 或 C++ 的 g++ 與 開發環境一起提供,該環境已設定並作為任何當前 AROS 發行版(如 AROS One、Icaros或 nightly 版本)的一部分,但不包括 Icaros Lite

目前,開發環境由以下軟體元件組成:GNU GCC 4.x GNU BinUtils、GNU Fileutils 4.x、GNU Textutils 等。

在單分割槽系統和啟動 ISO 上,AROS 開發環境安裝在“SYS:Development/”下。具有多個分割槽的系統(例如 Work: 分割槽)傾向於將其安裝到那裡,但是可以將其手動安裝到任何位置。請記住,如果移動,你需要更正 Development 包的“安裝位置”env 變數以指向新的根位置 - 在 SYS:S/startup-sequence 中檢視。

Assign Development: SYS:Development 
Assign C: Development:bin ADD 


在 aros 構建說明中。你需要將 contrib 和/或 ports 檢出到你的 AROS 原始碼目錄中,作為子目錄。然後,假設你正在外部構建目錄中構建,就像你應該做的那樣,你只需配置並“make contrib”例如或任何你可能想要構建的子模組。



C 和 C++ 初學者教程

[編輯 | 編輯原始碼]

由於 AROS 是 基於 C 的 API 與 AmigaOS 3.x 相容,因此大多數關於在 Amiga 上進行 C 程式設計的資訊也適用於 AROS。請注意,周圍還有很多 AOS 1.3(不太有用)和 AmigaOS AOS 2.x 的資訊。

缺少花括號 - 請嘗試 SHIFT + ALT + 7 或 0。


編寫 AROS 應用程式所需內容的簡要概述

  1. 使用 Intuition 用於基本的螢幕/視窗
  2. 透過 8 位 圖形在視窗內使用圖形,然後到 15-16-24 位 cybergraphx
  3. 載入和儲存工作到 dos 磁碟驅動器
  4. 使用 ZUNE GUI 環境


編寫本地遊戲需要這些額外資訊

  1. 使用 AHI 音訊硬體獨立 API
  2. 使用USB操縱桿/遊戲手柄,透過LowLevel庫與Poseidon USB棧互動


稍後可能新增的其他功能

  1. 為程式新增額外的Locale語言翻譯
  2. 為應用程式新增AREXX/Regina
  3. 複製貼上操作:使用AROS的剪貼簿並使用開啟/寫入/讀取/關閉操作
  4. 從應用程式執行Amiga(TM) DOS命令
  5. 使用圖示(.info檔案)和圖示工具型別(堆疊、版本和程式啟動選項)

Rob Peck的書籍"Amiga程式設計師指南"是對Amiga程式設計的良好入門介紹,儘管有點過時。Amiga ROM核心手冊:庫(第三版)和AmigaDOS手冊(第三版)是最常用的書籍,其他RKM,包括風格指南,也有其用途。AmigaMail和Devcon筆記(可在Amiga開發者光碟上再次獲得)提供了許多參考示例。

如果使用Arexx,那麼Commodore出版的Eric Giguere撰寫的"Amiga程式設計師的ARexx指南"以及"Arexx食譜"都很有用。



  • 原始碼可以在這裡這裡以及這裡找到。AROS原始碼本身包含大量示例程式碼。從AROS網站下載**contrib原始碼**存檔,並研究AROS應用程式的原始碼,例如Tests抽屜(資料夾/目錄)中的測試程式。檢視一些較小的AROS程式的程式碼可能是一個更好、更及時的指南。AROS SVN中隱藏著相當多的優秀示例。

上傳構建時,請在歸檔檔名中寫入架構(如i386-aros、x86_64-aros等),並且建議在“需求”欄位中寫入ABI(ABIv0或ABI-WIP或ABIv1)


編譯C/C++程式碼

[編輯 | 編輯原始碼]

雖然我們有IDE整合開發環境(Murks),但它缺少偵錯程式。其他人則結合使用文字編輯器和Shell來編輯程式碼。不過,大多數人使用在Linux上執行的AROS,以利用更好的GCC工具(如GDB)和各種IDE。

開啟Shell - 它是Wanderer(桌面)左上角的一個選單選項。或者在包含原始碼的目錄中使用右Win鍵和w(或F12和w)。輸入

sh 

將Amiga Shell切換到Unix Shell。然後可以輸入ls(Unix中相當於Amiga的dir)。更多命令請檢視這裡

對於單個檔案程式-name.c或program-name.cpp

gcc -o program-name program-name.c  

或者

g++ -o program-name program-name.cpp

或者

g++ -o test -Wall -g main.cc texturelib.cpp xmodelib.cc -lsdl -lgl

要關閉Shell,請點選左上角關閉(兩次)。第一次返回AROS Shell,然後再次點選最終關閉。使用cksfv作為測試。

一些原始碼需要新增Amiga API庫,例如dos,可以在編譯時使用以下標誌:

gcc -o julia.exe julia.c -ldos

例如,對於DOS使用-ldos,如果正在編譯mui程式碼,則為-lmui或intuition -lintuition。其他缺少的符號是由於連結庫對於連結標準C庫中不存在的函式是必要的。例如,一些原始碼需要新增

-lz or -lm or -lpng or -larosc etc.

在Unix命令列模式下使用此命令在多個.c檔案中搜索“search-item”(對於C++為*.cpp等)。

grep -l 'search-item' *.c

如果程式不可執行,請嘗試使用引數fno-common


更多資訊:Aros/Developer/移植軟體


如何使應用程式具有AROS 64位特定支援程式碼

[編輯 | 編輯原始碼]

可移植程式碼

AROS64已經使用64位定址,只是目前沒有為超過4GB的物理記憶體設定MMU。將軟體移植到AROS64時,“大多數”情況下是將用於儲存指標的ULONG轉換為IPTR,等等。另一個特性是確保堆疊上的專案大小正確,為此可以使用STACKED屬性。

  • 使用文字編輯器或某些工具將原始碼中的所有“ULONG”替換為“IPTR”,將“LONG”替換為“SIPTR”。

編譯用於AROS的mui內容,需要設定-std=gnu99,通常使用-std=c99。MUI應用程式很可能只需要HOOKPROTOxxx SDI宏。它們與AROS相容,只需要按照正確的順序給出屬性(鉤子、物件屬性)。


編碼規範

[編輯 | 編輯原始碼]

由於AROS核心原始碼是共享的開發者體驗,因此存在關於結構和風格的規則。在建立自己的應用程式和編寫程式碼時,結構和風格應該是您自己的,也就是說,您應該享受您所做的事情,並以您可以理解的方式去做。

static void 1st_function()
{
    program
    exit(0);    
}

int main(void)
{
    1st_function();
    2nd_function();
    3rd_function();
    return 0;
}
struct Screen * openscreen(void);
struct Window *openwindow(struct Screen *screen, const char *title, LONG x, LONG y, LONG w, LONG h);

VOID 1st_function();
VOID 2nd_function();

int main(int argc, char **argv)
{
    program
    return 0;
} /* main */

VOID 1st_function()
{

}

VOID 2nd_function()
{

}

通用風格

[編輯 | 編輯原始碼]

這段程式碼被很多人使用,因此在提交原始碼時,您應該牢記一些事項

  • 保持簡單
  • 保持原始碼整潔
  • 始終了解您在做什麼,如果不瞭解,請標記並描述需要做什麼...
  • 清晰簡潔地解釋您在做什麼
  • 記住,您只編寫一次程式碼,但它會被很多人多次閱讀

AROS使用原始碼中的一些註釋來生成文件。因此,需要保持一定的格式,以便工具可以找到其資訊。其他註釋會被忽略,但它們應該解釋您在編寫程式碼時的想法。如果您真的想不出解釋,那麼不要像這樣再次編寫程式碼

/* This adds 1 to t */
t ++;

我們認為是這樣的

/* Go on with next element */
t ++;

格式化

[編輯 | 編輯原始碼]

這隻有在您要處理AROS核心程式碼或contrib時才**重要**,而對於可能駐留在外部(例如AROS Archives或其他網站上)的應用程式則不重要。

{
    /* a */
    struct RastPort * rp;
    int               a;

    /* b */
    rp = NULL;
    a  = 1;

    /* c */
    if (a == 1)
        printf ("Init worked\n");

    /* d */
    if
    (
        !(rp = Get_a_pointer_to_the_RastPort
            (
                some
                , long
                , arguments
            )
        )
    ||
        a <= 0
    )
    {
        printf ("Something failed\n");
        return FAIL;
    }

    /* e */
    a = printf ("My RastPort is %p, a=%d\n"
        , rp
        , a
    );

    return OK;
}

看起來很醜,是嗎?:-) 好吧,以下是規則

If several lines contain similar code, put similar things below each other (see a and b);
Put spaces between operands and operators
Put braces {}, brackets [] and parentheses () below each other (d) if there is much code between. 
Brackets and parentheses may be in one line if the code between is small (c)
Indent by 4 Spaces. Two indent levels may be abbreviated by one tab.

在提交之前,請規範縮排 - 如果混合使用了製表符和空格 - 請始終使用空格,1個製表符=4個空格。

這樣做的原因是

  1. 雖然一些編輯器可以使用任意大小的製表符,但告訴另一個編輯器編寫程式碼時使用了哪個製表符大小有點複雜。
  2. AROS中的大多數程式碼都是這樣編寫的,您的程式碼也應該與其他程式碼保持一致。
  3. 您可以使用任何印表機列印此程式碼,而無需使用特殊工具來“修復”製表符。
  4. 大多數編輯器都有智慧製表符,可以精確地做到這一點。如果您的編輯器沒有,請提交錯誤報告。

如果您的函式有多個引數(d,e),您應該將括號放在單獨的行上,並將每個引數放在一行上(d),或者將第一個引數放在開括號後面(e),並將每個後續引數放在單獨的行上,並在前面加上逗號。閉括號位於單獨的行上,並與表示式的開頭對齊(即a,而不是開括號或printf())。

使用單個空行分隔邏輯塊。大型註釋應該在前後各有一個空行,小型註釋應該放在它們解釋的程式碼之前,前面只有一個空行。

如果您在AROS核心原始碼中看到任何製表符,建議您“取消製表符並單獨提交”,無論是在進行功能更改之前還是之後。進行兩次提交而不是一次。這使得其他人更容易看到真正的更改,而不是不得不瀏覽多行不相關的差異。

消除全域性變數

[編輯 | 編輯原始碼]

即將變數傳遞給函式(區域性範圍)或類,從而更容易跟蹤和除錯程式碼。

任何時候,如果您發現需要在“許多不同的地方”使用特定的東西,那麼很有可能所有這些地方在概念上都是相關的,因此您可以建立一個類、一個名稱空間、一個函式或其他一些更高級別的組織單元來表示這種關係。這使得程式更容易理解。

不良設計

  • 所有變數都是全域性的。
  • 沒有獨立的函式,只有作用於全域性變數的子程式。
  • 每個子程式至少有500行,甚至達到幾千行
  • 每個子程式執行多個任務
  • 首選複製貼上而不是編寫方法,並且在程式碼中間進行細微的更改

良好設計

  • 將程式結構化為函式(C或基本) - 自上而下的過程化方法
  • 放入類(freepascal或C++) - 物件是固定的,並且使用方法來訪問物件

 class String_List
 {
 private:
 list<string> m_List;  // member
 public:
 void read_strings() { /* read strings into m_List */ }
 void print_strings() { /* write contents of m_List to stdout */ }
 void sort_strings() { /* sort contents of m_List */ }
 void sort_strings_reverse() { /* reverse-sort contents of m_List */ }
 void unique_strings() { /* remove duplicate strings */ }
 };

 int main()
 {
 String_List myList;  // local
 myList.read_strings();
 myList.sort_strings();
 myList.print_strings();
 myList.sort_strings_reverse();
 myList.print_strings();
 myList.unique_strings();
 myList.print_strings();
 return 0;
 }

這樣,為了除錯目的,用新的列表替換列表變得非常容易,或者當您想要不同的結果時,在不替換列表的情況下替換方法。您只需要替換區域性變數的內容。

So create the structure that matches your data (linked lists, trees, arrays, etc) and what to do with them (sorting, searching, etc)
.h usually contain #define #include typedef enum struct extern screen and window definitions (data structures)
.c should contains functions and algorithms

可以這樣理解,選單標題充當 .c 檔案,子選單標題充當函式。

當您開始一個專案時,您會在包含檔案中放置一些宣告。隨著專案的進行,您會在包含檔案中放置越來越多的宣告,其中一些宣告引用或包含以前的宣告。在您意識到之前,您手上就會出現一團亂麻。大部分原始檔都瞭解資料結構,並直接引用結構中的元素。在一個許多資料結構直接引用其他資料結構的環境中進行更改,充其量只會讓人頭疼。考慮一下當您更改資料結構時會發生什麼。

使用良好的變數名來幫助澄清程式碼,並且僅在需要解釋為什麼採用某種程式設計方法時才進行註釋。

您正在重構遺留程式碼,您看到了一個全域性變數,您想擺脫它。您該怎麼做呢?

具體該怎麼做取決於全域性變數的使用方式。第一步是在整個程式碼中查詢全域性變數的所有使用情況,並瞭解變數的意義以及它與程式其餘部分的關係。特別注意變數的“生命週期”(何時初始化、何時首次使用、何時最後使用、如何清理)。然後,您可能會將全域性變數設為類的成員變數(對於面向物件的語言),或者編寫一些 get/set 函式。轉換為單例模式很常見,但您可能會發現,將資料元素設為現有單例的成員或例項變數更有意義。

  1. 建立一個基本的讀取方法,作為類或全域性函式。用訪問方法替換所有讀取操作,但將變數定義為全域性變數。
  2. 檢查對方法的每個寫入操作,並一次提取一個操作函式。除非原始程式碼中兩個操作的編碼完全相同,否則請分別提取每個寫入訪問操作。
  3. 將變數的作用域從全域性更改為區域性。
  4. 分析類似的操作函式,以確定是否可以合併任何函式,即函式結果沒有功能上的差異,只是實現細節上的差異。
  5. 檢查對讀取方法的呼叫,並檢視是否應該應用更復雜的功能。遵循寫入操作的方法,除非實現相同,否則建立單獨的訪問函式。
  6. 分析訪問函式是否存在重複。

隨著“按值傳遞”返回變數被遺忘,“按引用傳遞”通常被用作替代。引用是指向變數的指標,因此在返回時會記住該值。

替代方案

  • 隱藏的全域性變數
  • 單例模式
  • 資料庫或元組空間
  • 上下文物件
  • 依賴注入
  • 有狀態過程

AROS/AmigaOS API 和文件

[編輯 | 編輯原始碼]
Library:
   - Private data structure
   - Many public access methods

Device:
   - Private data structure
   - Two (BeginIO/AbortIO) access methods

Resource:
   - Public data structure
   - *NO* access methods

而且,由於與 Amiga OS 相容,因此所有這些都有例外情況。


系統庫

[編輯 | 編輯原始碼]

可以使用 AROS 庫指南 作為各個命令的指南,並且在應用程式程式設計中使用舊的開發文件。

生成的 Aros AutoDocs HTML 閱讀 或下載 docs-html.bz2 從這裡

Amiga/Aros 風格的庫與 Windows 和 Linux 庫非常不同。典型的 .so/dll 庫對於大多數類似 Amiga 的作業系統來說是陌生的。



AROS 子系統

[編輯 | 編輯原始碼]
  1. Zune MUI 相容 GUI
  2. AROS 應用程式包
  3. AHI 音訊驅動程式 - 用法/開發
  4. AROSTCP Sana2 網路介面驅動程式 - 用法/開發
  5. gfx.hidd/cybergraphics 影片驅動程式 - 用法/開發
  6. IO 裝置驅動程式 - 用法/開發
  7. USB 裝置驅動程式 - 用法/開發
  8. PCI 裝置驅動程式 - 用法/開發
  9. SDL
  10. Gallium 3D openGL 又名 Mesa - 用法/開發 Swfitless
  11. 透過 MUI-GTK 實現的一小部分 GTK2。
  12. Cairo 2D 引擎 - 用法/開發
  13. Scalos 桌面 API 和外掛模組


HIDD 用於裝置/外設底層硬體支援驅動程式。HIDD 系統被分成一個具有嚴格繼承層次結構的類集合。HIDD 類為單個裝置或在極少數情況下為一組裝置實現裝置驅動程式,並提供用於其他程式和裝置訪問的介面。

為了保持跨各種硬體的介面的可移植性,此介面通常不會提供對底層硬體的原始介面。相反,它將提供一個描述許多不同硬體實現的通用介面。這允許最大程度地重用介面和程式碼。

不過,HIDD API 比較重量級。您需要開啟一個 HIDD 庫,開啟 oop.library,例項化一個物件(即使沒有物件);並且與普通的庫呼叫相比,物件呼叫成本更高。


基本上,您的任務是為您的硬體實現 hidd.ata.bus 的子類。只需為 Amiga 晶片組實現 XXXATA__Hidd_ATABus__xxxxxx 方法,以及 interface_xxx.c 檔案的相應版本。probe.c 中幾乎所有內容都可以忽略 - 只需編寫一個相關的 Amiga 裝置的替換掃描,並將您需要的所有資訊儲存在匯流排資料中?只有“SUPPORT_LEGACY”塊可能相關。

您不需要依賴 PCI API。PCI 只是在 PC 等上發現硬體的一種方式。<hidd/pci.h> 包含(在某些深度)<interface/HW.h>,它定義了 IID_HW。這來自'generic' HIDD 類,位於

rom/hidds/hidd/hiddclass.conf

沒有將 HIDD 和 HW 分開,因為它們總是成對使用。這與 hidd/pci.h 為 PCI、PCIDriver 和 PCIDevice 提供定義相同。PCI 實際上是 PCIHW,只是出於向後相容性的原因,名稱沒有更改。HW 是 HIDD 例項插入的“集線器”。

除非 ata.device 首先檢測到正確的命令列引數,否則 ATA HIDD aoHidd_ATABus_Use32Bit 值將完全被忽略。是的。不幸的是,我無法在程式碼或 svn 歷史記錄中找到任何帶有解釋的註釋。查看了 Linux 原始碼,那裡 32 位 PIO 也是控制器驅動程式的屬性。其中一些啟用它,一些不啟用。

實際上,將預設值切換為 ON 應該是安全的。ata.device 在此方面是故障安全的,因為在 IDENTIFY 命令期間,它會驗證高 16 位,如果它們在所有 128 個長字中都顯示為零,則 32 位模式將關閉。但是,儘管如此,我知道硬體可能有多麼棘手,所以我決定不更改原始行為。如果您認為在某些情況下這是錯誤的,則可以新增一個額外的屬性,例如 aHidd_ATABus_Default32Bit。如果設定為 YES,則表示預設情況下可以使用 32 位 PIO。


Amiga 使用 裝置其他硬體 通訊。AROS 已將這些硬體裝置替換為 hidd 等效項,但出於向後相容性考慮,仍保留了一些裝置。

如果本地庫/裝置/處理程式等的版本高於 ROM 中的版本,則應該覆蓋 ROM 中的版本。

以下是 exec 預設命令列表

CMD_CLEAR 清除裝置的緩衝區
CMD_READ 播放控制
CMD_STOP 停止裝置的活動
CMD_FLUSH 清空命令佇列
CMD_RESET 重置裝置
CMD_WRITE 播放控制
CMD_INVALID 建立錯誤
CMD_UPDATE 獲取更新的裝置
CMD_START 將重新啟動裝置

雖然AmigaOS中大多數其他“你與其通訊的事物”都是共享通用基礎介面的裝置[2]OS 1.3 裝置驅動程式


處理器

[編輯 | 編輯原始碼]
pipe.handler
port.handler
sfs.handler
fat.handler
pfs.handler
fuse.handler
ffs.handler

檔案系統處理器擁有自己獨立的系統,該系統由完全不同結構的訊息組成,dos.library使用這些訊息將請求(例如讀取、寫入、獲取目錄內容等)傳遞給它們。AROS最初選擇將檔案系統處理器實現為裝置,這可能與AmigaOS API的其他部分更加一致,但與AmigaOS本身存在相當大的不相容性。然而,這使得移植檔案系統變得更加困難,而收益相對較小,因此修復這種不相容性一直是一個長期的目標。現在,截至2011年6月,它已被重新引入所有AROS版本。

argstr和argsize對於處理器啟動環境是否有效?DOS/RunHandler()呼叫DOS/CreateNewProcTags(),然後呼叫CallEntry()(在rom/dos/exit.c中)來啟動處理器,所以是的,argstr和argsize在處理器的呼叫簽名中是*存在的*。

當然,argstr將為NULL,argsize為0,但這些值*確實*使用以下方法傳遞給處理器函式

AROS_UFC3(ULONG, entry,
                         AROS_UFCA(STRPTR, argptr, A0),
                         AROS_UFCA(ULONG, argsize, D0),
                         AROS_UFCA(struct ExecBase *, SysBase, A6));

建立你自己的[無需整個構建樹http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip],然後

make stub
make
make install

SFS有兩個根塊,一個位於磁碟開頭,一個位於磁碟末尾。根塊都包含相同的資訊。它們包含有關磁碟結構的各種資訊,幷包含檔案系統使用的一些重要塊的位置。

根ObjectContainer包含根目錄物件。此物件的名稱是卷的名稱。它與普通目錄物件相同。

點陣圖用於跟蹤空閒空間。點陣圖中的每個位代表一個塊。設定的位表示空閒塊,清除的位表示已用塊。

AdminSpaceContainers用於跟蹤已保留用於儲存管理塊的空間。只有點陣圖、根塊和儲存在檔案中的實際資料未儲存在管理空間中。管理空間一次以32個塊的塊分配。單個AdminSpaceContainer可以儲存有關大量此類區域的資訊,每個區域都有自己的32位小點陣圖。

範圍儲存在B樹中。根塊儲存指向範圍B樹根的指標。範圍跟蹤特定檔案正在使用的空間。檔案的每個片段都有自己的範圍。範圍位於雙向連結串列中。該列表可用於查詢檔案的下一個或上一個片段。

以下是標準塊頭。此標頭位於檔案系統中使用的每種型別的塊之前,資料塊除外。id欄位用於在使用BLCK指標引用塊時檢查塊是否為正確的型別。校驗和欄位是塊中所有LONG的總和加1,然後取反。應用校驗和時,校驗和欄位本身應設定為零。檢查校驗和時,如果校驗和結果等於零,則校驗和正確。ownblock BLCK指標指向塊本身。此欄位是額外的安全檢查,以確保我們使用的是有效塊。

欄位 型別 描述 id ULONG id欄位用於識別我們正在處理的塊型別。它用於確保在引用塊時,我們獲取的是正確型別的塊。id由4個位元組組成,每個塊型別都有自己唯一的四個字母程式碼。 checksum ULONG 此欄位包含此塊中所有長整數的總和,加1,然後取反。校驗和可用於檢查塊是否以任何方式損壞。 ownblock BLCK 指向自身,換句話說,此欄位包含此塊的塊號。這是另一種檢查塊是否有效的方法。

struct fsBlockHeader {
    ULONG id;
    ULONG checksum;
    BLCK ownblock;
};

計算塊的校驗和的演算法

ULONG calcchecksum(struct fsBlockHeader *block, LONG blocksize} {
    ULONG *data=(ULONG *)block;
    ULONG checksum=1;

    block->checksum=0;

    while(blocksize>0) {
        checksum+=*data++;
        blocksize-=4;
    }

    return(-checksum);
} 

根塊包含有關SFS磁碟結構的非常重要的資訊。它包含有關磁碟的位置和大小、使用的塊大小、各種重要塊的位置、版本資訊和一些特定於檔案系統設定的資訊。

SFS磁碟有兩個根塊;一個位於分割槽的開頭,一個位於末尾。在啟動時,檔案系統將檢查兩個根以檢視它是否為有效的SFS磁碟。如果缺少其中一個,SFS仍然可以繼續(儘管目前不會)。

根塊可能會故意丟失。例如,如果您擴充套件末尾的分割槽(新增幾個MB),那麼SFS可以透過儲存在開頭位置的根塊中的資訊檢測到這一點(因為只有末尾偏移量發生了變化)。反之亦然,只要您不同時更改起點和終點。

當根塊由於分割槽被放大而丟失時,SFS將來將能夠調整自身大小而無需重新格式化磁碟。

欄位 型別 描述 bheader struct fsBlockHeader 標準塊頭。 version UWORD 檔案系統塊結構的版本。您可以檢查此欄位以識別您正在處理的檔案系統版本,以及檢視您是否可以正確處理此結構。當此欄位包含未知版本號時,請勿嘗試解釋磁碟的結構! sequencenumber UWORD 用於識別哪個根塊最後寫入,以防兩個根塊上的sequencenumber不匹配。 datecreated ULONG 此卷的建立日期。這是磁碟上次格式化的日期,並且永遠不會更改。 bits UBYTE 各種設定,請參見下文。 pad1 UBYTE 保留,保留為零。 pad2 UWORD 保留,保留為零。 reserved1 ULONG[2] 保留,保留為零。 firstbyteh ULONG 64位數字的高32位。這是我們分割槽相對於磁碟開頭的第一個位元組。 firstbyte ULONG 64位數字的低32位。 lastbyteh ULONG 64位數字的高32位。這是我們分割槽相對於磁碟末尾的最後一個位元組(不包括)。 lastbyte ULONG 64位數字的低32位。 totalblocks ULONG 此分割槽包含的塊總數。 blocksize ULONG 此分割槽的塊大小。 reserved2 ULONG[2] 保留,保留為零。 reserved3 ULONG[8] 保留,保留為零。 bitmapbase BLCK 點陣圖開始的塊號。 adminspacecontainer BLCK 第一個AdminSpaceContainer的塊號。 rootobjectcontainer BLCK 包含磁碟根的ObjectContainer的塊號(此處儲存卷名)。 extentbnoderoot BLCK 範圍B樹根的塊號。 reserved4 ULONG[4] 保留,保留為零。

struct fsRootBlock {
  struct fsBlockHeader bheader;
  UWORD version;
  UWORD sequencenumber;
  ULONG datecreated;
  UBYTE bits;
  UBYTE pad1;
  UWORD pad2;
  ULONG reserved1[2];
  ULONG firstbyteh;
  ULONG firstbyte;
  ULONG lastbyteh;
  ULONG lastbyte;
  BLCK  totalblocks;
  ULONG blocksize;
  ULONG reserved2[2];
  ULONG reserved3[8];
  BLCK  bitmapbase;
  BLCK  adminspacecontainer;
  BLCK  rootobjectcontainer;
  BLCK  extentbnoderoot;
  ULONG reserved4[4];
};

AdminSpaceContainers用於儲存每個管理空間的位置和點陣圖。AdminSpaceContainers位於雙向連結串列中,它們包含一個fsAdminSpace結構陣列。磁碟上的每個管理空間都有一個fsAdminSpace結構。

欄位 型別 描述 bheader struct fsBlockHeader 標準塊頭。 next BLCK 下一個AdminSpaceContainer,如果它是鏈中的最後一個,則為零。 previous BLCK 上一個AdminSpaceContainer,如果它是第一個AdminSpaceContainer,則為零。 bits UBYTE fsAdminSpace結構中每個bits ULONG中的位數。 pad1 UBYTE 保留,保留為零。 pad2 UWORD 保留,保留為零。 adminspace struct fsAdminSpace fsAdminSpace結構的陣列。陣列的大小由當前塊大小決定。

struct fsAdminSpaceContainer {
  struct fsBlockHeader bheader;
  BLCK next;
  BLCK previous;
  UBYTE bits;
  UBYTE pad1;
  UWORD pad2;
  struct fsAdminSpace adminspace[0];
};

欄位 型別 描述 space BLCK 管理空間的第一個塊。 bits ULONG 一個小點陣圖,用於確定管理空間中的哪些塊已在使用。此點陣圖中的位數由AdminSpaceContainer中的bits欄位確定。

struct fsAdminSpace {
  BLCK  space;
  ULONG bits;
};

fsBitmap結構用於點陣圖塊。點陣圖塊用於跟蹤磁碟特定區域的哪些空間正在使用,哪些空間未在使用。所有點陣圖塊共同跟蹤整個磁碟的空閒空間。第一個點陣圖塊的位置是已知的,所有其他點陣圖塊都按順序儲存在第一個點陣圖塊之後。

欄位 型別 描述 bheader struct fsBlockHeader 標準塊頭。 bitmap ULONG ULONG的陣列。這些儲存有關哪些塊正在使用以及哪些塊未在使用的實際資訊。

struct fsBitmap {
    struct fsBlockHeader bheader;
    ULONG bitmap[0];
};

點陣圖塊中的每個位(塊頭除外)都代表一個塊。如果位已設定,則該塊為空閒,如果位已清除,則該塊已滿。第一個點陣圖塊的點陣圖區域中的第一個ULONG表示磁碟上的塊0到31。此ULONG的位31是塊0,30是塊1,依此類推。第一個ULONG的位0表示塊31。

下表進一步闡明瞭點陣圖的工作原理。第一列是點陣圖塊號,第二列是點陣圖陣列中ULONG的編號。第三列是此ULONG中的位號,最後一列是此特定位在此特定點陣圖塊中表示的塊。

我們在此假設點陣圖塊有空間容納120個ULONG(這意味著有空間儲存32 * 120位)。

Bitmap block	ULONG number	Bit number	Block represented
1 (first)	0	31	0
1	0	30	1
...	...	...	...
1	0	1	30
1	0	0	31
1	1	31	32
...	...	...	...
1	2	31	64
1	2	30	65
...	...	...	...
1	119	0	3839
2	0	31	3840
2	0	30	3841
...	...	...	...

最後一個位圖塊不需要完全使用。所有未使用的位(屬於不存在的塊)都必須清除,以指示這些塊正在使用。

fsObjectContainer結構用於儲存可變數量的fsObjects結構(物件),這些結構具有相同的父目錄。每個ObjectContainer必須至少包含一個物件。如果ObjectContainer中存在未被可變數量的物件使用的空間,則該空間將填充零。物件始終從2位元組邊界開始,這意味著有時會在兩個物件之間插入一個填充位元組。

欄位 型別 描述 bheader struct fsBlockHeader 標準塊頭。 parent NODE 父物件的節點號,如果此物件沒有父物件(僅根目錄的情況),則為0。 next BLCK 屬於此目錄的下一個ObjectContainer,如果它是鏈中的最後一個,則為零。 previous BLCK 屬於此目錄的上一個ObjectContainer,如果它是此目錄中的第一個ObjectContainer,則為零。 object struct fsObject 可變數量的fsObject結構。結構的數量取決於每個fsObject結構的各個大小和塊大小。這些結構彼此直接位於,它們之間最多有1個位元組的填充,以使結構與2位元組邊界對齊。

struct fsObjectContainer {
    struct fsBlockHeader bheader;
    NODE parent;
    BLCK next;
    BLCK previous;
    struct fsObject object[0];
}; 

fsHashTable是HashTable塊的結構。它的功能與FFS使用者目錄塊中找到的雜湊表非常相似,只是它儲存在單獨的塊中。此塊包含多個雜湊鏈(對於512位元組塊,大約有120個)。每個雜湊鏈都是節點鏈。每個節點都包含指向物件的指標和指向雜湊鏈中下一個條目的指標。使用此類雜湊鏈,您只需知道物件的名稱即可快速找到該物件。

欄位 型別 描述 bheader struct fsBlockHeader 標準塊頭。 parent NODE 此HashTable塊所屬的目錄物件的節點號。 hashentry NODE 節點的陣列。每個節點都表示雜湊鏈的開頭(單向連結)。使用檔案的名稱或目錄計算雜湊值,此值確定物件連結到哪個鏈中。如果雜湊鏈中沒有條目,則hashentry值為零。

struct fsHashTable {
    struct fsBlockHeader bheader;
    NODE parent;
    NODE hashentry[0];
};

要使用物件的名稱作為輸入計算雜湊值,請使用以下例程

UWORD calchash(UBYTE *name) {
    UWORD hash=0;
    /* Calculates a hash value over the passed in string.
       The end of the string can be either a NUL byte or a
       slash. The hash function is the same as the one
       used in FastFileSystem set to international mode. */
    while(name[hash]!=0 && name[hash]!='/') {
        hash++;
    }
    while(*name!=0 && *name!='/') {
        hash=hash*13+upperchar(*name++);
    }

    return((UWORD)(hash % (UWORD)((blocksize-sizeof(struct fsHashTable))>>2)));
}
UBYTE upperchar(UBYTE c) {
    if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z')) {
        c-=32;
    }
    return(c);
}

BNodeContainer用於儲存B樹。目前,此檔案系統僅使用一棵B樹,用於儲存檔案資料的位置。fsBNodeContainer結構包含另外兩個結構。fsBlockHeader結構和BTreeContainer結構。

欄位型別 描述 bheader struct fsBlockHeader 標準塊頭。 btc struct BTreeContainer 包含有關B樹及其包含在此塊中的節點的資訊。

struct fsBNodeContainer {
    struct fsBlockHeader bheader;
    struct BTreeContainer btc;
}; 


首先嚐試找到根塊。它應該以“ROOT”開頭。SFS有兩個這樣的塊,一個在分割槽的開頭,一個在結尾。其中一個欄位包含塊大小,這將是所有重要SFS塊的大小。

根塊包含根物件容器,其中包含有關根目錄中檔案和目錄的資訊。物件容器基本上儲存一個或多個表示檔案和目錄的較小結構。掃描所有這些結構應該會給你一個檔案和目錄的列表。

根塊還包含擴充套件B樹的根。這是一個標準的B樹結構(不是二叉樹),在各種系統中普遍使用,如果需要,您可以閱讀維基百科上關於它們如何工作的資訊。B樹儲存有關檔案所有資料*所在位置*的資訊。

要恢復您的檔案,我會這樣做

  • 找到一個根塊,如果不存在,則找出磁碟使用的塊大小,並依次掃描每個塊以檢視它

是否看起來像一個ObjectContainer(檢查fsBlockHeader的ID,檢查ownblock編號是否等於您當前正在掃描的塊,並檢查其校驗和)。因此,如果您當前擁有塊12,並且您看到一個具有正確ID、ownblock=12且校驗和良好的塊,那麼這可能是一個有效的ObjectContainer。

  • 找到所有ObjectContainer後,您可以從中提取檔名和目錄名,還可以提取其第一個資料

塊(在data欄位中)和檔案大小。對於小檔案(小於塊大小),此資料塊足以恢復資料。對於較大的檔案,您可能很幸運,所有剩餘的塊都在第一個塊之後找到(如果檔案已碎片整理)。但是您不能確定這一點,因此...

  • 對於較大的檔案,您需要找到所有BNodeContainer。您可以像找到所有ObjectContainer一樣掃描它們(查詢

具有正確ID、ownblock編號和校驗和的塊)。

  • 找到所有BNodeContainer後,您可以嘗試在B樹結構中查詢檔案的第一個資料塊。這有點複雜

-- B樹由非葉節點(僅包含指向其他B樹塊的指標的塊)組成,isLeaf標誌指示這一點。或者它可以是B樹葉塊。葉塊為每個條目包含額外的資訊(請參閱https://hjohn.home.xs4all.nl/SFS/extents.htm

struct fsExtentBNode {
     ULONG key;
     ULONG next;
     ULONG prev;
     UWORD blocks;
};

鍵應該是檔案的一個塊(一個範圍的第一個),長度為1到65535塊(取決於“blocks”欄位)。如果檔案被分成多個部分,則“next”將包含下一範圍塊的塊號。您需要在B樹結構中再次查詢它以瞭解其大小。

您可以在大多數情況下忽略其他結構(點陣圖、管理容器)。fsObjects和B樹容器是您恢復資料所需的。


rom/storage/mmakefile.src 
rom/storage/storage.conf 
rom/storage/storage_device.c 
rom/storage/storage_ids.c 
rom/storage/storage_init.c 
rom/storage/storage_intern.h 
rom/storage/storage_mount.c 
rom/storage/storage_unit.c
rom/storage/includes/device.h 
rom/storage/includes/unit.h 
rom/storage/includes/volume.h 
rom/storage/storage_intern.h 


除錯程式碼

[編輯 | 編輯原始碼]

如果發現任何問題,請使用AROS錯誤跟蹤器


GRUB命令列列表

sysdebug  
usbdebug - allows to see Poseidon's log in debug output


如何從InitResident獲得除錯資訊?如果在Linux上執行i386,則在命令列上使用sysdebug=initresident。這樣,您可以啟用任何列出的標誌。sysdebug=all代表“所有”


有一個可執行檔案(交叉編譯的C++程式碼),它在磁碟上的大小為6MB,但在載入到記憶體後,佔用250MB的RAM。有什麼軟體可以將AROS可執行檔案拆分為ELF部分,從而顯示實際的大小值?

readelf -S executable

它將顯示ELF檔案中的所有段,包括大小和請求的對齊方式。

objdump -h filename

這將為您提供對段和大小的快速概述。忽略所有.debug.*段。我猜您可能有一個很大的.bss段。在C++中這很常見。

下一步

nm—size-sort filename | grep ' [bB] '

最後幾個將是您最大的資源消耗者。建議使用-C來反混淆符號... ;)


建議分析程式(只需在主迴圈中使用一些printf來檢視每個部分花費的時間),通常很容易在遊戲或應用程式中發現緩慢的部分。

如果有人在某個地方使用了“#define IPTR ULONG”。要檢視該定義在哪裡,請在失敗的原始碼中重新定義IPTR,就在失敗的行上方,預處理器會告訴您它在哪裡第一次定義。

如何在AROS/hosted中設定gdb

[編輯 | 編輯原始碼]

aros.sourceforge.net/download.php下載AROS原始碼(AROS-xxxxxxxx-source.tar.bz2,其中xxxxxxxx是當前日期)和AROS contrib原始碼(AROS-xxxxxxxx-contrib-source)。

解壓bzip2並cd到解壓後的存檔目錄。

> tar -xvjf AROS-xxxxxxxx-source.tar.bz2
> cd AROS-xxxxxxxx-source

檢查到“contrib”(contrib-source)的連結(在目錄內),例如,正確的連結如下所示

> rm contrib
> ln -s ../AROS-xxxxxxxx-contrib-source.tar.bz2 contrib

確保您具有正確的區域設定,否則編譯將在某個時候失敗。請參閱此處(或下面的連結)以瞭解更多資訊。您可能需要輸入以下內容

> export LANG="en_US.ISO-8859-1"

現在配置用於除錯構建 - 請參閱“./configure --help”以瞭解更多資訊 - 以下有兩個示例

> ./configure—enable-debug=stack,modules,symbols

> ./configure—enable-debug=all

您現在可以“make”,或者為您的構建選擇一個單獨的目錄(例如,便於刪除),例如,如果為i386架構編譯,您可以建立如下所示的目錄

> mkdir linux-i386
> cd linux-i386
> ../AROS/configure—enable-debug=stack,symbols,modules

配置完成後,您就可以開始了

> make

構建AROS需要一些時間 - 在快速的機器上需要幾分鐘(例如,2.5 GHz四核),在較慢的機器上則需要幾個小時。結果將是啟用了gdb除錯功能的AROS Linux託管版本。

請參閱aros.org文件以瞭解有關編譯AROS的更多資訊,包括更多--enable-debug選項。


完成後,進入bin/linux-i386/AROS目錄(將“linux-i386”替換為您編譯的目標平臺,例如linux-x86_64等)在解壓後的存檔目錄內。此目錄包含在gdb中正確執行AROS所需的.gdbinit檔案。

> cd bin/linux-i386/AROS

從gdb執行AROS(此處:使用128MB記憶體)

> gdb—args boot/aros-unix -m 128

或者

> gdb—args boot/arosboot -m 128
(gdb) r

觀察shell輸出 - 如果AROS抱怨“LoadKeyCode2RawKeyTable: Loading "DEVS:Keymaps/X11/keycode2rawkey.table" failed!”,您還應該看到一些有關如何建立鍵對映表的說明。(請參閱上面“編譯更多資訊”中的連結)。退出gdb,並嘗試預設的鍵對映表

(gdb) q
The program is running.  Quit anyway (and kill it)? (y or n) y
> cd ../../..
> make default-x11keymaptable

如上所述重新執行AROS。嘗試例如RAros(=右視窗鍵)+ W開啟shell。如果這不起作用,您必須自己建立鍵對映表,再次退出gdb,並建立一個新的鍵表

> make change-x11keymaptable

將開啟一個視窗。觀察視窗的標題欄,並按照說明操作。

完成後,重新執行AROS。RAros + W現在應該開啟一個shell。

接下來,使用gdb支援編譯您的程式。


當您啟動GDB時,是否會顯示以下警告

  warning: File "<whatever>/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to ...

如果是,則使用“-ix .gdbinit”啟動gdb


Summary - In short:

* build AROS with debugging support (i.e. ./configure --enable-debug=all)
* build your application with debugging support (i.e. option -g)
* run AROS in the GNU debugger (you may use the GUI frontend "ddd" which simplifies usage a bit)
* start your application
* use the commands "findaddr" and "add-symbol-file" as written in the debugging manual
* if the debugger doesn't find the source code of your application use the "dir" command of the debugger. 

如何使用gdb

[編輯 | 編輯原始碼]

在AROS中開啟一個shell,然後(在主機shell中)使用CTRL-Z進入gdb。使用“b Exec_CreatePool”(啟動程式碼在程式中早期使用的一個函式)新增斷點,然後使用“cont”,gdb將在程式啟動的早期某個地方中斷。使用“bt”顯示回溯,使用“loadseg”顯示“??”條目。其中一個將是“program”。之後,您可以使用“disassemble program”。

您需要確保的一件事是,構建目錄中的.gdbinit與原始碼樹中的相同。它在一段時間前被修改過,但構建系統沒有重新整理它 - 您需要手動複製它

概括地說,請閱讀我們的除錯手冊


要檢測載入時的段錯誤,請嘗試...

./configure—enable-debug—with-optimization="-O2"

因為崩潰與否可能取決於最佳化。對於較新的編譯器,也許這會有幫助...

--with-optimization=-"-O2 -fno-strict-aliasing"

使崩潰不那麼隨機(更容易重現)的一種方法是啟用rom/exec/freemem.c中空閒記憶體的混淆,這通常是註釋掉的

Index: freemem.c
===================================================================
--- freemem.c   (revision 34289)
+++ freemem.c   (working copy)
@@ -154,11 +154,12 @@
         * created with their TCB placed in the tc_MemEntry list. The workaround
         * is to avoid munging when FreeMem() is called with task switching disabled.
         */
+
        /* DOH! it doesn't work even this way. What's wrong???
-        *
-        * if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0))
-        *      MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize);
         */
+
+       if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0))
+           MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize);

     }

Mungwall可以在執行時開啟。目前,這在所有託管版本中都有效。只需在核心命令列上指定“mungwall”,它就可以工作。它也可以在原生版本中工作。為了啟用它,您需要解析核心命令列,如果存在“mungwall”,則在IntExecBase.IntFlags中設定EXECF_MungWall位。

由於顯而易見的原因,這需要在第一次AllocMem()之前完成。並且永遠不要重置此標誌!如果您在工作系統上更改它,您將陷入困境。

託管埠在rom/exec/prepareexecbase.c中進行處理 --enable-debug=mungwall選項在configure中仍然有效,但即將過時。rom/exec/allocmem.c中的一個技巧負責此操作,並且在轉換完成後需要將其刪除。

順便說一句,在i386-pc埠上,可以透過命令列上的“mungwall”引數啟用它,您不需要重新構建AROS。新的mungwall不僅影響AllocMem()/FreeMem(),還影響池。我還使用AllocAbs()對其進行了測試,似乎工作正常。

執行時mungwall適用於

  • pc-i386
  • pc-x86_64
  • linux-i386
  • linux-x86_64
  • darwin-x86
  • linux-ppc

適用於所有託管埠,如果埠本身正在工作。

  • amiga-m68k
  • 不適用於sam440-ppc和efika-chrp-ppc,即使它們目前能夠構建。不適用於(目前,需要NVRAM支援)

當我啟動我新構建的、使用完整除錯支援編譯的i386-linux-aros時,有時會出現“Program exited with code 0377”錯誤。將以下內容新增到您的.gdbinit中

set follow-fork-mode child

以下是一些自定義的AROS gdb 函式(定義在“.gdbinit” 檔案中),用於解決反跟蹤中“in ?? ()” 的條目。

#0 0xb7ffd424 in __kernel_vsyscall ()
#1 0xb7e2a657 in sigsuspend () from /lib/libc.so.6
#2 0xb7c63900 in ?? ()
#3 0xb7c640e3 in ?? ()
#4 0xb7c641e0 in ?? ()

您可以使用以下命令:

loadseg 0xb7c63900
loadframe 2

或者

loadbt

以及其他一些命令。使用“help ”可以獲取簡短的幫助資訊。如果命令不起作用,請先嚐試“loadkick”。


使用“thistask”、“taskready”、“taskwait”獲取AROS任務列表。“bttask ”顯示處於就緒或等待佇列中的任務的反跟蹤,而“loadseg”則用於解決其反跟蹤中的“??”條目(“loadframe”無法使用,因為它假設當前正在執行的任務)。

AROS的原生除錯工具

[編輯 | 編輯原始碼]
to enable debugging at boot time entering the GRUB menu editing line (E key) and adding "debug=memory" to your boot line, then press Ctrl+X to complete booting.


SYS:Tools/Debug/Bifteck

開啟一個shell並輸入以下命令執行Biftek,並將RAM中收集的除錯訊息抓取到一個文字檔案中。

tools/debug/bifteck > ram:debug.txt

它肯定不會開啟一個視窗。它是一個shell工具,只轉儲位於除錯位置的資料。因此,必須儘快“捕獲”除錯資料(在它被覆蓋之前)。您應該在第一次有機會時呼叫bifteck,然後再執行其他任何操作。您可以使用TO選項將bifteck輸出儲存到檔案,或者您可以手動將其管道到檔案。


SYS:Tools/Debug/Sashimi - 顯示錯誤訊息

建議使用bug()進行除錯。每次執行bug()時,它都會在sashimi上輸出。您需要包含<aros/debug.h>並在原始碼中放置bug("something\n");,該位置是控制流程經過的地方。

要獲取輸出 - 開啟一個aros shell

SYS:Tools/Debug/sashimi > RAM:out.txt

Ctrl C結束輸出到RAM磁碟。

  1. 開啟shell,然後輸入
  2. ram: (切換到ram驅動器)
  3. System:Tools/Debug/Sashimi > mylogfile.txt
  4. 使用wanderer開啟AHI首選項(或使用另一個開啟的shell)
  5. 播放測試聲音
  6. 關閉AHI首選項
  7. shell仍然開啟並執行Sashimi:按ctrl-c中斷Sashimi並返回提示符。
  8. 在shell中:複製mylogfile.txt到System:(或您需要的任何位置)


SYS:Utilities/Snoopy - 監視作業系統函式呼叫,執行“Sashimi”檢視Snoopy的輸出


SYS:Tools/WiMP - 視窗(和螢幕)操作程式

您可以使用gcc的-E選項來了解預處理器宏是如何展開的。

strcasecmp中的崩潰通常意味著其引數之一為NULL。

這兩個名稱之間有空格,可能是某些不可見的字元。

舊的Amiga Guru程式碼

如果崩潰發生在intuition中。有時,如果它與文字相關,則空指標會觸發它。未初始化的指標可以具有任何地址(這是一個常見的錯誤)。


在64位系統上編譯,許多舊程式碼在執行指標-整數轉換時不會正確進行型別轉換,因此至少會丟擲一個警告。這很容易找到並修復。

可移植程式碼

  • 使用文字編輯器或某些工具將原始碼中的所有“ULONG”替換為“IPTR”,將“LONG”替換為“SIPTR”。
  • 修復(將IPTR/SIPTR改回ULONG/LONG)那些真正依賴ULONG/LONG正好為32位的少數地方。這適用於畫素(ARGB)緩衝區、寫入/讀取到磁碟的結構、顏色對映,但可能沒有其他用途了。

再說一次,當您嘗試將指標值分配給整數並且整數可能太小的時候,許多當前的編譯器也會丟擲一個警告。例如,在.NET下,當一個64位指標被分配給ULONG時就會發生這種情況 - 所以這正是您描述的情況。


/* 1. Header for your name,date,purpose of program.
2. Pre-processor directives. This will include the #includes for files you want to add. 
3. Includes for function prototypes if necessary.
4. Main()
Create Pointers for Libraries and any Window you want to open.
5. Open necessary libraries.
6. Check if open exit program if fail.
7. Open a window exit program if fail.
8. Add your program
9. Close Window
10 Close Libraries.
11 End Program. */

/* standard os included headers <.h> */
#include <dos/dos.h>
#include <dos/dosasl.h>
#include <dos/dosextens.h>
#include <dos/exall.h>
#include <dos/rdargs.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <utility/utility.h>
#include <intuition/intuition.h>

/* define as unresolved external references (proto/xxx.h) and compiler will link to auto(matically) open library */ 
#include <proto/arossupport.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/cybergraphics.h>
#include <proto/datatypes.h>
#include <proto/icon.h>

#include <workbench/workbench.h>
#include <workbench/icon.h>

#include <datatypes/pictureclass.h>

#include <proto/muimaster.h>
#include <libraries/mui.h>

#include proto/bsdsocket.h

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* my own headers ".h" */

#define CTRL_C      (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
#define  isDir(fib) ((fib)->fib_DirEntryType >= 0)

#define ARG_TEMPLATE    "FILE/A,ALL/S,QUIET/S,W=WIDTH/N,H=HEIGHT/N,M=METHOD,DEFTOOL"

int main(void)
{


	return retval;
} /* main */

如果您使用了c++,我們的共享庫系統中還沒有c++支援。建立/編譯共享庫最簡單的方法是使用AROS構建系統,但庫也可以手動建立。您必須建立一個ROMTAG結構和一些標頭檔案。

共享庫使用%build_module宏構建,程式碼如下所示

%build_module mmake=MetaTarget modname=mylib modtype=library files=SourceFiles 

此宏可以構建不同的AROS模組型別,例如裝置、Zune類、HIDD等。

##begin config
version 1.0
##end config

##begin functionlist
void func1(LONG a, LONG b)
int func2(char *s, ULONG a)
##end functionlist

更多資訊請點選此處

或者,

#ifndef LIB_H
#define LIB_H

#define __NOLIBBASE__

#include <exec/libraries.h>
#include <exec/semaphores.h>
#include <dos/dos.h>

#ifdef __AROS__
//#include <aros/debug.h>
#define reg(x)
#define __saveds
#endif

#define USESYSBASE struct ExecBase *SysBase = Base->My_SysBase;

struct MyTestBase
{
  struct Library   My_Test_Lib;
	struct ExecBase *My_SysBase;
	APTR             My_SegList;
  int              testint;
};

#endif
/*--------------------------------------------------------------------------*/
/* Resident header written for mytest.library */
/*--------------------------------------------------------------------------*/

#define __NOLIBBASE__

#define VERSION         1
#define REVISION        0

#define LIBHEADNAME     mytest
#define LIBHEADNAMESTR "mytest"
#define COMPDATE        "04.10.2015"
#define VERS            "1.0"

#define LIBBASETYPE 	struct MyTestBase
#define LIBBASETYPEPTR  LIBBASETYPE *

#include <aros/debug.h>
#include <exec/exec.h>
#include <proto/exec.h>
#include <exec/resident.h>
#include <exec/nodes.h>
#include <exec/libraries.h>
#include <aros/symbolsets.h>
#include "lib.h"

const UBYTE lib_name[] = LIBHEADNAMESTR ".library";

const UBYTE lib_id[] = "$VER: " LIBHEADNAMESTR ".library " VERS " (" COMPDATE ") by ALB42\n";

extern const APTR FuncTable[];

AROS_UFP3 (LIBBASETYPEPTR, InitLib,
    AROS_UFPA(LIBBASETYPEPTR, Base, D0),
    AROS_UFPA(BPTR, seglist, A0),
    AROS_UFPA(struct ExecBase *, sysbase, A6)
);

static struct LibInitStruct
{
    IPTR                   LibSize;
    const APTR             *FuncTable;
    const struct DataTable *DataTable;
    APTR                    InitFunc;
}
const LibInitStruct =
{
    sizeof(LIBBASETYPE),
    FuncTable,
    NULL,
    (APTR)InitLib
};

const struct Resident romtag =
{
  RTC_MATCHWORD,              /* match word */
  (APTR)&romtag,              /* back pointer */
  (APTR)(&romtag + 1),        /* skip pointer */
  RTF_AUTOINIT | RTF_EXTENDED,/* flags */
  VERSION,                    /* version */
  NT_LIBRARY,                 /* type of module */
  0,                          /* init priority */
  (STRPTR)lib_name,           /* module name */
  (STRPTR)lib_id + 6,
  (APTR)&LibInitStruct,
  REVISION, NULL
};

AROS_UFH3 (LIBBASETYPEPTR, InitLib,
    AROS_UFHA(LIBBASETYPEPTR, Base, D0),
    AROS_UFHA(BPTR, seglist, A0),
    AROS_UFHA(struct ExecBase *, sysbase, A6)
    )
{
    AROS_USERFUNC_INIT
    
    Base->My_SegList = seglist;
    Base->My_SysBase = (APTR)sysbase;
    Base->testint = 0;
    
    USESYSBASE
    bug("InitLib\n");
    
    if (!set_open_libraries())
    {
      set_close_libraries();
      return NULL;
    }
    
    return Base;
    
    AROS_USERFUNC_EXIT
}

AROS_LH1(LIBBASETYPEPTR, LibOpen,
    AROS_LHA (ULONG, version, D0),
    LIBBASETYPEPTR, Base, 1, LIBHEADNAME
    )
{
    AROS_LIBFUNC_INIT
    
    USESYSBASE
    bug("LibOpen\n");

    (void)version;
    
    Base->My_Test_Lib.lib_OpenCnt++;
    return Base;

    AROS_LIBFUNC_EXIT
    
}

__saveds APTR LibExpungeInternal(LIBBASETYPE *Base reg(a6))
{
  USESYSBASE
  APTR seglist;
  bug("LibExpungeInternal\n");

  if (Base->My_Test_Lib.lib_OpenCnt)
  {
    return 0;
  }

  seglist = Base->My_SegList;

  Forbid();
  Remove((struct Node*)Base);
  Permit();
  FreeMem((APTR)Base - Base->My_Test_Lib.lib_NegSize, (LONG)Base->My_Test_Lib.lib_PosSize +
    (LONG)Base->My_Test_Lib.lib_NegSize);
  
  set_close_libraries();
  return seglist;
}

AROS_LH0(BPTR, LibClose,
    LIBBASETYPEPTR, Base, 2, LIBHEADNAME
    )
{
    AROS_LIBFUNC_INIT
    USESYSBASE
    bug("LibClose\n");

    if (!(--Base->My_Test_Lib.lib_OpenCnt))
    {
      return LibExpungeInternal(Base);          
    }
    return 0;
	
    AROS_LIBFUNC_EXIT
}

AROS_LH1(BPTR, LibExpunge,
    AROS_LHA(LIBBASETYPEPTR, Base, D0),
    struct ExecBase *, sysBase, 3, LIBHEADNAME
    )
{
    AROS_LIBFUNC_INIT

    (void)sysBase;
    
    USESYSBASE
    bug("LibExpunge\n");

    return LibExpungeInternal(Base);
	
    AROS_LIBFUNC_EXIT
}

AROS_LH0(LIBBASETYPEPTR, LibReserved,
    LIBBASETYPEPTR, Base, 4, LIBHEADNAME
    )
{
    AROS_LIBFUNC_INIT
    USESYSBASE
    bug("LibReserved\n");

    return 0;
    //return (APTR)LibReserved();
    
    AROS_LIBFUNC_EXIT
}


// Space for your own functions
// do not forget to update the FuncTable as well

AROS_LH1(int, TestFunction,
    AROS_LHA(int, TestValue, D0),
    LIBBASETYPEPTR, Base, 5, LIBHEADNAME
    )
{
    AROS_LIBFUNC_INIT
    USESYSBASE
    bug("TestFunction\n");

    Base->testint = TestValue + Base->testint;
    
    return Base->testint;
    
    AROS_LIBFUNC_EXIT
}

// Functable -> Table of all functions in the Library, in right order - important!

const APTR FuncTable[] = 
{
    &AROS_SLIB_ENTRY(LibOpen,LIBHEADNAME,1),
    &AROS_SLIB_ENTRY(LibClose,LIBHEADNAME,2),
    &AROS_SLIB_ENTRY(LibExpunge,LIBHEADNAME,3),
    &AROS_SLIB_ENTRY(LibReserved,LIBHEADNAME,4),
    &AROS_SLIB_ENTRY(TestFunction,LIBHEADNAME,5),
    (void *)-1
};

// AutoInit stuff
void *__PROGRAM_ENTRIES__symbol_set_handler_missing;
void *__LIBS__symbol_set_handler_missing;
// end of AutoInitStuff

Makefile

VPATH = 
CFLAGS = -O2 -g -fomit-frame-pointer -W -Wall -Wno-parentheses
CC = i386-aros-gcc
LD = i386-aros-gcc
LDFLAGS = -nostartfiles -Wl,-Map -Xlinker linkermap
LIBS = -lautoinit -llibinit
STRIP = i386-aros-strip --strip-unneeded --remove-section .comment

OBJS = lib_header.o 

all: mytest.library

mytest.library: $(OBJS)
	$(LD) $(LDFLAGS) $^ $(LIBS) -o $@

lib_header.o: lib_header.c lib.h

clean:
	rm -f *.o *.library *.ppu testlibrary linkermap


將UNIX庫移植到AROS - 處理靜態變數,這將使此類庫更容易移植到AROS,保持在磁碟上共享它們的優勢,但失去在記憶體中實際共享它們的優勢。

我們的問題在於我們希望共享實際程式碼(庫的.text部分)和常量資料,但我們需要為每個任務提供.bss和.data部分。如果我們放棄共享.text和.rodata部分的意圖,事情就變得非常簡單:只要在任何開啟庫的人開啟它時載入並重新定位庫即可。這就像將庫靜態連結到可執行檔案中一樣,只是最終的連結是在執行時完成的。

在V0分支中,在workbench/hidds/hidd.nouveau中提交了pcimock.hidd。這是一個PCI驅動程式,允許在Linux主機下模擬真實的PCI裝置。其主要思想是能夠在Linux主機下執行真實的硬體驅動程式,並儘可能減少改動(除非有人想編寫完整的裝置模擬器,否則始終需要進行一些更改),以便可以使用gdb執行和除錯驅動程式的程式碼路徑。在移植nouveau時,這是一個非常有用的功能。現在,它已從nouveau.hidd中分離出來,其他人可以用來移植驅動程式。pcimock.hidd目前可以模擬4種不同的nvidia顯示卡、1個AGP橋接器,還可以模擬irq.hidd。

這個驅動程式與pcilinux.hidd有什麼區別?我用它開發了許多不同的AROS硬體驅動程式。據我所知,pcilinux.hidd的目的是訪問在Linux下執行的真實硬體。pcimock.hidd的目標是模擬硬體。例如,我的開發機器是一個PCIE系統,但我仍然希望在Linux主機下執行nouveau中的AGP程式碼路徑,以檢查它們是否不會出現段錯誤。另一種情況是在開發人員沒有的硬體上執行程式碼路徑(在我的例子中是Fermi卡)。在pcimock.hidd的情況下,只要添加了適當的模擬(例如,填寫PCI配置區域或BAR中暫存器的值),AROS驅動程式的程式碼路徑就會執行。這對移植的驅動程式來說是一個優勢 - 程式碼應該已經可以工作了(因為它在另一個系統上工作過),但在移植過程中可能出現了一些錯誤,這些錯誤可以使用gdb輕鬆檢測到。

如果您是從頭開始編寫驅動程式,pcilinux.hidd hidd將為您提供更多優勢,因為您實際上可以從Linux主機訪問真實的硬體。



APL、MPL、BSD、GPL和LGPL許可證

[編輯 | 編輯原始碼]

大多數AROS原始碼都使用AROS公共許可證(APL)許可,這(在某種程度上)保護了我們免受某些人獲取AROS原始碼而不回饋改進的影響(例如,MorphOS獲取了一些AROS原始碼,然後回饋了更改)。

它被編寫為允許在其他開源或商業專案中使用AROS程式碼,無一例外,同時提供了一種機制,使改進/新增功能能夠以某種形式返回到原始原始碼。

AROS使用的一些第三方應用程式不受此許可證約束,它們作為額外的“Contrib”下載,方便使用者使用。

任何人都可以將GPL許可的網路和聲音驅動程式移植到AROSTCP和AHI中,因為它們是GPL許可的。在AROS的其他部分(圖形、SATA、USB)中直接使用(移植)GPL許可的程式碼是不可能的,因為AROS許可證與GPL不相容。您需要使用寬鬆許可的程式碼,例如BSD或MIT/X11。


BSD和MPL許可證與APL最接近。

然而,APL與LGPL/GPL並不相容。

LGPL的情況 - 您不能將APL程式碼與LGPL靜態組合。但是,由於LGPL的限制性較小,您可以在APL程式碼中使用動態載入的LGPL庫。

GPL的情況 - 如果GPL許可的程式碼作者沒有明確的條款允許這樣做,則您不能以任何方式將APL程式碼與GPL組合。如果您以上面描述的“錯誤”方式將APL與GPL組合 - 您就會遇到問題(您違反了GPL)。此問題可能會導致AROS中的所有內容都變成GPL,或者在AROS上執行的所有內容都變成GPL(這裡我不確定)。另一種情況是,您根本不允許合法地分發此類程式碼。老實說,我已經瞭解瞭如何違反GPL,但我仍然不確定違反GPL會發生什麼(但我確定不會是什麼好事)。

GPL軟體可以在非GPL“系統元件”之上執行(參見GPL的系統元件例外),但反過來(非GPL使用GPL)會導致問題。這意味著像Scout或Quake III這樣的應用程式是可以的(在大多數情況下)。

沒有理由不能移植GPL驅動程式 - 但它們不能在AROS的ROM中(需要將APL程式碼與GPL連結),也不能讓AROS依賴於它們(例如,它們必須使用現有的API)。如果它們是由使用者操作(動態連結)啟動的,那是允許的。為了方便起見,分發此類二進位制檔案也是允許的。

GPL不是關於靜態或動態連結,而是關於執行程序和函式呼叫。


這些元件 - SFS、isapnp、Zune文字編輯器、AHi、網路驅動程式、freetype、openuirl、BHFormat、Edit和(“動態載入的庫”)是LGPL,而不是GPL。Mesa/Nouveau的東西是MIT許可的。不過,一些使用者工具是GPL許可的。

AROS(系統)

  • 系統元件(庫/類/裝置等)不能是GPL,因為它們會將GPL傳播到整個系統,而且GPL與APL所基於的MPL不相容。
  • 系統元件可以是LGPL v2或寬鬆許可證(MIT/BSD)。
  • 系統應用程式可以是任何你喜歡的(但我仍然更傾向於APL或寬鬆許可證,這樣如果需要,程式碼可以被重用)。

Contrib

  • 沒有規則 - Contrib不會影響AROS系統,因為AROS系統中的任何內容都不依賴於Contrib。

關於竊取程式碼:無論我們是APL還是GPL,發生這種情況的可能性完全相同。如果任何閉源選項想要這樣做,沒有人能夠驗證其是否合法。MorphOS使用了一些AROS程式碼,但回饋了更改。

APL 的基本原理是,雖然它保證了原始開發者在一定程度上(基於檔案)可以獲得改進後的程式碼,但使用程式碼的人不必開啟他自己的原始程式碼。BSD 不保證原始開發者獲得改進。GPL 要求使用程式碼的人也公開他的程式碼。

版權持有者需要保留 - 我們只需要他們提供資訊,證明這些程式碼是在 APL 下可用的(例如像 Poseidon 一樣簽入的檔案)。我們不進行版權轉讓。

最終,什麼可以做,什麼不可以做,取決於作者(們),而不是許可證。

AROS 原始碼樹

[編輯 | 編輯原始碼]


發現了一個有趣的(非 GPL)許可“異常” - 發行商需要記住這一點。

如果出售,將失去許可證的程式(“僅限非盈利”許可)

 contrib/aminet/comm/term/TinyTerminal
 contrib/aminet/dev/basic/bwBASIC
 contrib/aminet/text/edit/xdme
 contrib/fish/aroach
 contrib/fish/lotto
 contrib/fish/shuffle
 contrib/fish/touch
 + cdvdfs.


這是一個 fossology 找到的所有 GPL/GPLv2/GPLv3 許可證的列表,這些許可證在其註釋中具有明確的許可證。


excluded LGPL, BSD/GPL dual licensed and programs (such as Prefs/Edit and BHFormat)
AROS/rom/dbus/include/  AFL_v2.1 ,GPL_v2+  (supposedly AFL < 3 is GPL incompatible) 
AROS/workbench/classes/zune/betterstring/include/  GPL_v2+
AROS/workbench/classes/zune/texteditor/include/  GPL_v2+
AROS/workbench/classes/datatypes/gemimage/ GPL_v2+ GPL
AROS/workbench/classes/datatypes/degas/  GPL_v2+
AROS/workbench/libs/openurl/README: GPL
AROS/workbench/network/smbfs/documentation/  GPL_v2
AROS/workbench/network/smbfs/source_code/  GPL_v2+
AROS/workbench/network/stacks/AROSTCP/bsdsocket/kern/  GPL_v2
AROS/workbench/network/stacks/AROSTCP/bsdsocket/mmakefile.src conf.h  GPL_v2
AROS/workbench/network/stacks/AROSTCP/bsdsocket/sys/  CMU ,GPL_v2
AROS/workbench/network/stacks/AROSTCP/bsdsocket/net/  GPL_v2
AROS/workbench/network/stacks/AROSTCP/bsdsocket/api/  GPL_v2
AROS/workbench/network/stacks/AROSTCP/bsdsocket/conf/conf.h: GPL_v2
AROS/workbench/network/stacks/AROSTCP/netinclude/net/radix.h: CMU ,GPL_v2
AROS/workbench/devs/AHI/AHI/  GPL_v2+
AROS/workbench/devs/AHI/AddAudioModes/ GPL_v2+  AROS/workbench/devs/AHI/AddAudioModes/COPYING: GPL 
AROS/workbench/devs/AHI/Docs/texinfo.tex: GPL_v2+
AROS/workbench/devs/AHI/COPYING: GPL
AROS/workbench/devs/AHI/Drivers/EMU10kx/  GPL_v2+
AROS/workbench/devs/AHI/AHI-Handler/  GPL_v2+
AROS/workbench/devs/networks/rtl8029/  GPL   GPL_v2+
AROS/workbench/devs/networks/pcnet32/  GPL   GPL_v2+
AROS/workbench/devs/networks/ppp/LEGAL: GPL
AROS/workbench/devs/networks/atheros5000/  GPL_v2+
AROS/workbench/devs/networks/rhine/  GPL_v2+
AROS/workbench/devs/networks/nForce/  GPL_v2+  GPL
AROS/workbench/devs/networks/prism2/  GPL  GPL_v2+
AROS/workbench/devs/networks/fec/LEGAL: GPL
AROS/workbench/devs/networks/rtl8139/  GPL  GPL_v2+
AROS/workbench/devs/networks/etherlink3/  GPL  GPL_v2+
AROS/workbench/devs/networks/intelpro100/  GPL  GPL_v2+
AROS/workbench/devs/networks/rtl8169/  GPL   GPL_v2+
AROS/workbench/devs/networks/emac/   GPL   GPL_v2+
AROS/workbench/devs/networks/rtl8168/  GPL  GPL_v2+
AROS/workbench/devs/networks/realtek8180/   GPL_v2+
AROS/workbench/devs/networks/via-rhine/via-rhine.c: GPL_v2+
AROS/workbench/devs/networks/via-rhine/   GPL  GPL_v2+
AROS/workbench/devs/networks/e1000/  GPL_v2
AROS/workbench/devs/networks/sis900/  GPL   GPL_v2+

AHI:它有特殊條款(COPYING.DRIVERS)。庫是 LGPL,首選項軟體是 GPL,驅動程式可以是任何東西,而不會違反 GPL/LGPL。

網路堆疊:好吧,我們早就應該有一個新的支援 IPv6 的網路堆疊了,有人感興趣嗎?;) 說真的,膠水程式碼似乎是 GPL,以及所有驅動程式。但是,一些驅動程式是我們自己的程式碼,因此可以重新授權為 LGPL。

Same filter as the AROS trunk list. These should all be libraries or plugins - no programs.
contrib/regina/utsname.h: GPL_v2+

contrib/mui/classes/nlist/include/default-align.h: GPL_v2+
contrib/mui/classes/nlist/include/amiga-align.h: GPL_v2+

contrib/mui/classes/BWins/include/MUI/BWin_mcc.h: GPL
contrib/mui/classes/BWins/include/BWin_private_mcc.h: GPL
contrib/mui/classes/BWins/COPYING: GPL_v2
contrib/mui/classes/BWins/MCC_BWins.readme: GPL_v2

contrib/mui/classes/thebar/include/default-align.h: GPL_v2+
contrib/mui/classes/thebar/include/amiga-align.h: GPL_v2+

contrib/gfx/libs/wazp3d/LEGAL: GPL
contrib/gfx/libs/wazp3d/Wazp3D.readme: GPL
contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d.c: GPL
contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.h: GPL
contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.c: GPL
contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.h: GPL
contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.c: GPL

contrib/libs/mpega/  GPL_v2+

http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt

在 AROS 上,適用以下規則

 
1. BYTE/UBYTE is 8bit, WORD/UWORD is 16bit, LONG/ULONG is 32bit, QUAD/UQUAD is 64bit, the types are comparable with stdint types (int8_t, int16_t, int32_t, int64_t)
2. IPTR/SIPTR are integer types large enough to fit pointer, that is sizeof(IPTR) = sizeof(APTR) = 4 on 32bit system, and = 8 on 64bit system
3. ti_Data in TagList is large enough to hold a IPTR/APTR type.
4. never store a pointer in integer of type LONG. It may work (if the pointer has upper 32bits clear), but does not have to. Compiler should warn you about that.
5. If you are unsure about point 4, allocate your memory with MEMF_31BIT flag set. But don't expect that AROS internals will do the same.

第 4 點實際上很重要。


  • UBYTE/BYTE 用於 8 位
  • UWORD/WORD 用於 16 位
  • ULONG/LONG 用於 32 位
  • UQUAD/QUAD 用於 64 位
UBYTE    Unsigned 8 bit integer variable (byte).
BYTE     Signed 8 bit integer variable (byte).
UWORD    Unsigned 16 bit integer variable (word).
WORD     Signed 16 bit integer variable (word).
ULONG    Unsigned 32 bit integer variable (longword).
LONG     Signed 32 bit integer variable (longword).
FLOAT    32 bit IEEE floating point variable.
UQUAD    Unsigned 64 bit integer variable.
QUAD     Signed 64 bit integer variable.
DOUBLE   64bit IEEE floating point variable.
BOOL     Boolean variable, TRUE and FALSE are also defined in exec/types.h.
VOID     Void.

APTR     A generic pointer for multiple purposes - Arrays.
STRPTR   A pointer to a null-terminated string.
IPTR     Really important in AROS, the only way to declare a field that can contain both: an integer or a pointer.

如果您想編寫真正可移植的應用程式,您可能對 C99 中定義的標準資料型別感興趣:int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t、intptr_t、uintptr_t。它們都定義在 inttypes.h 標頭檔案中。

在 exec/types.h 中,以下快捷方式被 typedef。它們在 AROS 中經常使用,因此您幾乎總是應該包含 exec/types.h,並且很快它們將僅從 sys/_types.h 標頭檔案中刪除,所有型別現在都定義在名為 aros/types/xxx.h 的標頭檔案中。

(為 C 庫拆分做準備;僅在使用 POSIX C 庫編譯時,sys/xxx.h 標頭檔案才在那裡可用)


編譯器特定的型別,如 int 和 long 可能會更改其大小。在 AROS 的情況下,類似於 Linux,int 保持 32 位,而 long 的大小增加到 64 位。

如果您使用 Amiga 式的資料型別,即 BYTE/UBYTE、WORD/UWORD、LONG/ULONG 和 QUAD/UQUAD 或 C99 標準型別(uint8_t 等,請參閱 stdint.h 標頭檔案),那麼您應該比使用沒有大小保證的型別遇到更少的問題。

當然,使用 64 位 CPU 時,所有指標都增長到 64 位元組。大多數程式碼只需重新編譯即可工作。在某些罕見的情況下,例如將指標轉換為整數,必須特別注意。尤其是在將指標轉換為 LONG/ULONG 的情況下(此程式碼將在 64 位 AROS 上中斷),例如 '#define IPTR ULONG'。

使用編譯器 delint 補丁,其中大部分是簡單的強制轉換問題,以使編譯器滿意。請注意,一些更改涉及引入雙重強制轉換。在最近版本的 GCC 中。是的,大部分雙重強制轉換用於將 32 位地址(即來自 32 位 PCI DMA 地址暫存器)轉換為 64 位指標。第一次強制轉換是轉換為 IPTR(擴充套件到 64 位,並防止地址超過 0x7FFFFFFF 時發生符號擴充套件),然後轉換為 APTR。

ULONG != IPTR,除非在 32 位上……因此,如果您需要儲存指標,請確保使用 IPTR 而不是 ULONG(某些舊程式碼使用)。出於這個原因,像 Taglist 元素這樣的東西是 64 位(因為標籤資料可以是指標)。如果在堆疊上傳遞專案,則應使用 STACKED 屬性確保它們正確對齊(在 64 位上,堆疊上的所有專案都是 64 位…)。

還有更多問題,例如使用“== 0L”會導致問題。

位元組序

[編輯 | 編輯原始碼]
  • 大端
  • 小端

使用 中的宏,而不是根據體系結構定義進行猜測

#if _BYTE_ORDER == _BIG_ENDIAN

#elif _BYTE_ORDER == _LITTLE_ENDIAN

#else
+
#error <whatever.h> - Byte order for this architecture is unsupported! 


SVN 和 GIT

[編輯 | 編輯原始碼]

如果您想幫助開發 AROS OS 本身,您可以

如果您有 SVN 訪問許可權(2015 年初引入了一個新的 SVN 伺服器,在 trac aros org 上建立一個新帳戶)和/或獲得了原始碼 AROS 網站 - 您可以使用以下命令編譯當前的構建工具/環境

> make development

並按照此 過程指南


https://trac.aros.org/trac#Developing

如果您計劃貢獻更改,請首先在此 郵件列表 上釋出有關此類更改的資訊,以便更有經驗的開發人員可以驗證它們是否正確。


然後是每晚構建機器。它們在構建之前進行 svn 更新,並在接下來的步驟之一中執行配置。autoconf 可能會新增到每晚構建指令碼中。

我們的構建依賴於從網際網路下載的軟體包(例如 SDL) - 它一直都是這樣。最小要求(僅構建核心 AROS 時)是 binutils 和 gcc。如果您也構建 contrib,則需要下載更多軟體包。

https://gitorious.org/aros/aros/commits/crosstools-II

git://gitorious.org/aros/aros.git

分支 crosstools-II 在 ABI_V1 之上只有一個提交

../../aros-src/AROS/configure --enable-ccache
--with-portssources=~/aros/Sources --target=pc-x86_64
--with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-x86_64

以及

../../aros-src/AROS/configure --enable-ccache
--with-portssources=~/aros/Sources --target=pc-i386
--with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-i386

構建成功。


更多資訊:AROS 維護者文件

SDI 呼叫

[編輯 | 編輯原始碼]

整合“SDI”標頭檔案,以便更容易移植到所有類似 Amiga 的平臺。

PUTCHARPROTO( PutTheChar, char c, struct SPrintfStream *s  )
{
 // REAL CODE
}

包含“SDI_compiler.h”和“SDI_hook.h”

它更有組織性,例如

#include SDI/SDI_hook.h

#include SDI_hook.h

選項 1 --- 我在從 Amiga 回溯時也使用它。

#ifdef __AROS__
#include SDI/SDI_hook.h
#else
#include SDI_hook.h
#endif

如果您不想新增或編輯任何檔案,可以新增 -i include/sdi/ 位置。


定義 HOOKPROTO 為 IPTR name(struct IClass * cl, Object * obj, Msg msg);解決了這個問題

MUI 應用程式很可能只需要 HOOKPROTOxxx SDI 宏。它們與 AROS 相容,只需要按正確的順序給出屬性(掛鉤、物件屬性)。檢查 compiler/include/aros/symbolsets.h (AROS_LIBREQ)

為 aros 設定編譯 mui 東西需要 -std=gnu99(我大部分時間都使用 -std=c99)。

使用 Flexcat 的語言環境

[編輯 | 編輯原始碼]

大多數語言都有語言環境,但並非每個應用程式都已本地化,唯一需要的是翻譯“目錄”檔案。這只是一個找到正確的目錄並儲存翻譯版本的問題。

對於每個缺少您語言目錄且已本地化的應用程式,您應該在(原始碼中)找到與語言環境相關的檔案

  • file.cd = 目錄描述符,包含基本訊息,以及內部語言(通常是英語)
  • language.ct = 目錄翻譯,包含每個翻譯的訊息,索引與 file.cd 中的索引相同。

與其他本地化應用程式進行比較...然後,“make my_app-catalogs”應該建立並安裝您的翻譯目錄。例如:對於 sys:prefs/wanderer

在 AROS 原始碼的根目錄下,鍵入

"make workbench-prefs-wanderer-catalogs"

然後(如果您更改了 .cd 檔案)

"make workbench-prefs-wanderer"

對於未本地化的應用程式,您必須調整其程式碼以支援它,如果可能的話…

注意到原始的 .cd 檔案在任何語音的末尾都有很多(//)字串,因此也將其新增到 .ct 檔案中。該(//)僅用於 cd 檔案。我強烈建議使用 FlexCat 更新 ct 檔案,例如這樣

flexcat app.cd deutsch.ct newctfile deutsch.ct

您將獲得錯誤檢查,新條目在生成的 ct 檔案中被標記。

編輯 .ct 檔案時,僅更改包含翻譯和版本字串的行,其他內容不要更改。其餘部分由相關工具 flexcat 負責。要更新您的翻譯,請在 shell 中鍵入以下內容

flexcat xyz.cd xyz.ct NEWCTFILE xyz_upd.ct COPYMSGNEW

這樣,您不僅可以確保擁有正確的翻譯檔案,而且 flexcat 還會使用“*** NEW *** text”預填充新新增的字串。用於檢查 cd/ct/catalog 檔案的更好工具是 catcheck,但遺憾的是,此工具僅適用於 AmigaOS/68k…

某些語言有多種變體,例如葡萄牙語(葡萄牙)和巴西葡萄牙語有所不同…

這是正確的方法。我會檢視語言檔案,但基本上,如果這兩種語言有所不同,您必須執行兩組分開的翻譯檔案,是的。(您也可以建立一個巴西俚語語言本地化)

  • 在系統級別,一種語言的本地化是一個點語言檔案。

(例如:locale:languages/klingon.language)

  • 在應用程式級別,本地化是一個點目錄檔案

(例如:locale:catalogs/klingon/system/libs/dos.catalog)

  • 在原始碼級別,點 ct 檔案,以及“$language”點 cd 檔案和一些構建框架。

(例如:catalogs/my_app.ct catalogs/klingon.cd catalogs/mmakefile.src support.c support.h)

請使用 Flexcat 生成 CT 檔案

FlexCat wanderer.cd NEWCTFILE=deutsch.ct

然後用一些有用的內容填充前兩行。

## version $VER: wanderer.catalog 1.1 (9.2.2006)
## language deutsch

你甚至可以更新CT檔案:(這會新增新的字串)

FlexCat wanderer.cd deutsch.ct NEWCTFILE=deutsch.ct


要編譯目錄,你只需要.cd檔案和你的翻譯(.ct檔案)。

FlexCat multiview.cd deutsch.ct CATALOG=MultiView.catalog


FlexCat的Linux版本

更多資訊


一個指令碼,它將所需版本(例如,應用程式/模組等嘗試開啟的版本)與現有CT檔案的版本進行比較。結果在此表中。

https://github.com/aros-translation-team/translations/wiki/Progress

以下情況會被突出顯示

   n/a i.e. CT misses at all
   version in existing CT file is lower than the required version


如果你以前沒有使用過Git,參與可能會有點困難,但作為替代方案,你可以將你的CT檔案傳送到我們的Slack頻道。

當ct檔案透過flexcat生成時(flexcat keyshow.cd NEWCTFILE=spanish.ct),它具有以下頭部


    1. version $VER: <name>.catalog <ver>.<rev> (04.01.2021)
    2. language nolanguage
    3. codeset 0

這些值<ver>.<rev>是該語言的CT檔案的版本和修訂版,還是正在本地化的應用程式的值?

<ver>部分必須與應用程式嘗試開啟的版本匹配。你可以在上面我連結的表格的“所需版本”列中找到該值,或者你可以在git儲存庫中查詢。對於keyshow,它將是https://github.com/aros-translation-team/keyshow。你可以在檔案“catalog_version.h”中找到正確的版本號。對於新的CT檔案,<rev>部分從0開始,並且每次更新CT檔案時都應該增加。

更新了幾個檔案,並建立了一些西班牙語目錄中缺少的檔案。

目錄位於https://github.com/aros-translation-team的Git儲存庫中。

a) 你告訴我你的Github使用者名稱。我會邀請你。你可以直接使用Git儲存庫。

b) 你建立目錄儲存庫的Github分支並建立拉取請求。

c) 你將CT檔案傳送到mrustler gmx de


C 工具 雜項

[編輯 | 編輯原始碼]

AROS原始碼在多個地方使用__DATE__宏來填充$VER標籤的日期條目。問題是c:version不理解該日期格式(例如,“2011年5月21日”)。結果,例如>“version c:shell full”的輸出包含“(null)”。擴充套件版本命令以理解__DATE__的格式是解決此問題的正確方法嗎?

AmigaOs編譯器應該使用__AMIGADATE__宏或類似形式,如果它沒有實現,則可以在makefile中模擬:-D__AMIGADATE__=\"$(shell date "+%d.%m.%Y")\"

順便說一句。我認為DD.MM.YYYY比“Month DD YYY”更好的格式,因為“Month DD YYY”沒有進行任何本地化。

“strnicmp”不應該與NULL指標一起使用

情況

使用c++目標檔案編譯了一個linklib(使用c++交叉編譯器)。編譯了一個使用linklib的C存根(使用c++交叉編譯器)。

嘗試將它們連結在一起(使用c++交叉編譯器)以及需要使用的C目標檔案(使用正常的目標c編譯器)-nostartup = 不能這樣做,因為使用c++檔案會引入arosc(用於stdio等) - 所以希望存在autoinit內容。

我該怎麼辦?

如果可以手動開啟它,我需要確切地做什麼?

ENV背後的理念是:將配置檔案儲存在那裡允許你透過在ENVARC:中保留副本來“使用”首選項。但是,在某些情況下(例如這種情況),不需要這樣做。

99%的時間,對於ENV:中的幾乎每個檔案,該語句都是正確的(不需要),或者人們每次啟動時都會更改其預設圖示和首選項設定嗎?

開發人員最近似乎養成了一個壞習慣,即更改某些內容以反映他們自己的個人偏好,而更改實際上並非必要 - 如果人們能夠避免在樹中進行此類更改,而至少不先在開發人員列表中討論(並且有充分的理由,除非他們首先提交了這項工作..),那將是很好的。

我們不熱衷於“S:”目錄的汙染:它應該是用於指令碼的。 “ENV:”有什麼問題?唯一的問題是它佔用RAM。我理解對於擁有幾GB RAM的PC來說,這無關緊要。但讓我們記住其他機器。ENV:背後的理念是:將配置檔案儲存在那裡允許你透過在ENVARC:中保留副本來“使用”首選項。

但是,在某些情況下(例如這種情況),不需要這樣做。

那麼以HappyENV的風格實現怎麼樣?RAM磁碟處理程式,如果其中尚未儲存此類檔案,則會貫穿到從ENVARC:讀取。對於未更改的檔案,消除了RAM的使用,消除了在啟動序列中將ENVARC複製到ENV的需要。從AmberRAM製作它應該不難,甚至可以擴充套件AmberRAM以提供此服務。

是否可以構建一個特殊的AmberRAM版本來處理ENV:,如果在ENV:中找不到請求的檔案,它將嘗試從ENVARC:複製該檔案?此外,它可以將關閉的“檔案”標記為未觸碰 - 並在一段時間後或系統記憶體不足時將其從ENV:中刪除以釋放額外的RAM?

檔案靜默消失可能不是一個好計劃。如果以下內容有效將是很好的

ASSIGN :ENV SYS:Prefs/Env-Arc ADD ASSIGN :ENV RAM:ENV ADD

將新檔案放入ENV:中最終會進入RAM:ENV,並且開啟檔案會先在RAM:ENV中查詢,然後在SYS:Prefs/Env-Arc中查詢

好吧 - 這基本上是我建議的,但沒有分配 - 或者不需要RAM:ENV目錄。將其新增為AmberRAM的功能聽起來是最節省記憶體的方式(一個處理程式載入到RAM中),但這僅在它可以除了RAM:之外還可以處理ENV:,並且如果可以新增建議的功能(...以及如何在訪問ENV:時啟用它)。

(AS)MP支援

[編輯 | 編輯原始碼]

如果必須為SMP多核重新編譯軟體,是否有任何特殊的事情需要做才能使軟體執行?如果需要查詢有關正在執行的任務的資訊,請使用task.resource,並在分配訊息埠時完全清除它們。

大多數程式碼不需要Forbid。使用訊號量、訊息等來同步你自己的程式碼。

訪問系統結構是另一回事。儘可能使用正確的API。

將來如何保護單個結構仍然是一個移動的目標,至少它沒有記錄。並且你永遠不應該使用未記錄的內容



關於SMP多核的想法

另一個建議是... Forbid/Permit函式呼叫旨在停止多工處理,以便沒有其他任務可以干預呼叫任務正在執行的操作,例如設定訊號量。Disable/Enable呼叫旨在停止中斷,並且作為副作用,它們還會停止任務切換。

一種選擇是強制使用訊號量保護共享資源,並禁止使用簡單的Forbid()呼叫來保護某些內容。如果可能,應使用原子指令設定訊號量(在一個指令中檢查和更改)。或者使第二個併發ObtainSemaphore呼叫停止第二個呼叫任務,並儘可能強制進行任務切換,無論哪個給出更好的結果。

訊號量可以儲存擁有任務的任務指標而不是布林值,以簡化操作。

只要CPU透過OS啟動DMA傳輸,並且OS確保傳輸的記憶體位於啟動傳輸的使用者可訪問的區域內,一切就正常。CPU是指揮者,並且CPU因此控制著啟動哪個DMA傳輸以及不啟動哪個DMA傳輸。你只需要編寫合理的裝置驅動程式即可。提示:CachePreDMA和CachePostDMA存在。OS需要做的就是驗證要傳輸的記憶體區域是否有效,並禁止使用者空間直接訪問DMA控制暫存器。這些演算法都不意味著巨大的成本。當前的OS設計實際上不允許虛擬記憶體,Forbid()再次成為問題。

memory.library API似乎是底層的。恕我直言,程式不應該知道交換是如何實現的。我只會使用一個新的記憶體標誌MEMF_SWAPPABLE,它指示某個記憶體區域或整個記憶體池在Forbid()/Permit()等期間不會被訪問。它只解決了部分問題,它只實現了虛擬記憶體,而不是記憶體保護。對於後者,你需要能夠使某些記憶體對其他程式不可訪問,某些記憶體對一個任務只讀,對其他任務讀寫等。我認為這應該在同一個地址空間中完成,以避免你不斷需要在不同的地址空間之間切換。因此,總而言之,如果有程式使用此API,我們可以提供一個包裝層以使它們工作,但我並不認為此API應該是提供VM給AROS程式的參考API。

可變引數

[編輯 | 編輯原始碼]

可變引數函式(即具有任意數量引數的函式)。

    #include <stdarg.h>
    [...]

    char * STDARGS GetKeyWord(int value, char *def, ...)
    {
        [...]
        va_list va;
        [...]
        va_start(va, def);
        [...]
        va_end (args);

請繼續使用stdarg,而不是將va轉換為LONG *型別並手動處理varargs。這樣做可以防止大量的轉換,而可以使用簡單的va_arg。因此,string = *((char **) args) 而不是string=va_arg(va, char *)。

#include <stdio.h>
#include <stdarg.h>

int printf (const char * format, ...)

{
    int     retval;
    va_list args;

    va_start (args, format);

    retval = vfprintf (stdout, format, args);

    va_end (args);

    fflush (stdout);

    return retval;
} /* printf */

找不到varargs.h或stdarg.h,並且不使用AROS_SLOWSTACKHOOKS或AROS_SLOWSTACKTAGS。

GCC在不同的位置查詢stdarg.h

/bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/include/stdarg.h

這是一個“正常”頭的路徑

bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/../../../../i386-aros/sys-include/aros/system.h


較新的gcc版本不支援使用vararg.h。如果希望程式碼在將可變引數的一部分傳遞到多個暫存器中的體系結構上執行,則需要使用AROS_SLOWSTACK宏。否則,程式將無法在powerpc和x86_64埠上執行。

當然,在可以使用va_list、va_start、va_arg和va_end的函式中不需要SLOWSTACK內容。僅當要編寫DoMethod或類似的函式時才需要它。

#include <stdarg.h>

無論你是交叉編譯還是原生編譯,這都應該足夠了。如果它不起作用,則說明某些地方有問題,需要進行修正。

Stdarg.h 位於這裡:Development:lib/gcc/i386-aros/4.2.2/include/

……這是編譯器預設包含路徑的一部分。換句話說,#include 可以直接使用。(抱歉,我應該在呼叫“搜尋”或“查詢”之前先嚐試一下……)

此外,上面所示的 myprintf() 無法工作,因為……

printf(format, args);

……是錯誤的 - 第二個引數與 printf() 的原型不匹配,它期望一個引數列表,但 args 的型別為 va_list(顯然) - 所以必須使用……

vfprintf(stdout, format, args);

……代替,就像在原始的 printf() 中一樣,並新增 fflush(stdout)。

此外,可以使用……

int myarg = va_arg(args, int);

……在 va_start() 和 va_end() 之間訪問各個引數,其中每次呼叫 va_arg() 都返回從給定列表(此處為“args”)中轉換為所需型別(此處為“int”)的引數,並前進到下一個引數。

封裝 vfprintf() 並修改格式字串現在是一個巨大的加速!不再需要輸入反斜槓-n 了!這困擾了我很多年!

在 MOS 和 AmigaOS 上,NewObject 可變引數函式保留在靜態庫中。它將大部分引數放在堆疊上 - 因此 NewObject 的實現呼叫 NewObjectA 函式。一切正常,並且可以輕鬆使用典型的 MUI 宏。

但是,當你為 AROS 編譯時情況並非如此。在這裡,NewObject 是一個可變引數宏,而不是函式。由於這種方法,我們不需要任何自定義編譯器,在系統中,可變引數函式的引數部分透過暫存器傳遞,部分透過堆疊傳遞(這是 PPC 和 x86_64 的情況,這也是 OS4 和 MOS 都需要特殊修補的編譯器的原因)。

由於 NewObject 是一個宏,gcc 的預處理器期望宏引數列表用括號括起來。在 MUI 宏中情況並非如此。想象一下以下測試程式碼

#define foo(a,b) ((a)+(b))

int loosy_function(int a, int b)
{
    return foo(a,b);
}

這將編譯並工作,但以下程式碼段

#define foo(a,b) ((a)+(b))
#define END )

int loosy_function(int a, int b)
{
    return foo(a,b END;
}

將失敗並出現錯誤:呼叫宏“foo”時引數列表未終止。

有兩種方法可以解決你的問題。要麼在這些巨大的 MUI 結構之外建立新的物件,並在其中只使用一個指標,要麼去掉“End”宏並用“TAG_DONE)”替換它。


例如,編寫不佳的軟體會將 va_list 轉換為 APTR,或者甚至將其視為函式引數的普通表。此類程式碼需要修復,因為它除了在作者的機器上幾乎沒有機會工作 ;)

問題不在於它們假設 sizeof(APTR) == 4,而在於它們通常不使用 APTR,而是使用 ULONG 來專門儲存指標。如果程式碼按應有的方式使用 APTR/IPTR - 大多數“問題”將不存在。

如果人們開始正確使用可變引數,那也將有所幫助。許多編碼人員會做出不應該做出的假設。相反,他們應該考慮使用 stdarg.h 檔案和所有 va_* 函式 :)

在我們的 SVN 倉庫的頭部,現在只有 3 個目錄

admin/
branches/
trunk/

我們在那裡添加了兩個額外的目錄:tags 和 imports

正如我們在建立 ABI V0 和 ABI V1 分支時所討論的,引入標籤也是一個好主意。通常,這是在儲存庫中名為 tags 的目錄中完成的。目前,我們那裡沒有這個目錄。(我們確實有 branches/tags,這是一個我做的技巧,因為一個人沒有頂級目錄的寫入許可權。我認為這個目錄不乾淨,應該刪除)。

我想引入的第二個目錄是 imports 目錄,用於實現供應商分支,如 svn 手冊 中所討論的那樣。目前,我們使用來自幾個不同專案的程式碼,並且這些程式碼儲存在 AROS 樹中;我們似乎在保持這些程式碼更新和將我們的更改合併到上游方面存在問題。上游專案的維護者(例如 MUI 類等)對此表示了抱怨(輕描淡寫地說)。

引入這些供應商分支將使我們更容易看到我們所做的更改,並更容易向上遊傳送補丁,並更容易匯入其程式碼的更新版本。雖然不能“複製”供應商分支到主分支,因為它已經存在,所以從“合併”開始。

是的,使儲存庫中已有的程式碼與供應商分支相容的第一步將是最困難的。最好的方法是以下方式

  • 首先將當前 AROS 程式碼所基於的版本匯入到供應商分支中
  • 然後在供應商分支中匯入新版本
  • 最後,合併儲存庫中存在的 AROS 程式碼中這兩個版本之間的差異。

例如,將 NList 直接放在 vendor 下,而不是放在像“contrib/zune/classes”這樣的子目錄中。

實際上,在我們擁有穩定的 ABIv1(2012 年或之後) 之後。我們需要儘可能地從 contrib 目錄遷移到其他儲存庫。原因是……

  • AROS 儲存庫應該是核心 AROS 程式碼的儲存庫。
  • 其他 contrib 專案應該嘗試為所有類似 Amiga 的作業系統進行編譯。
  • AROS 和其他程式的釋出方案不必保持一致。
  • 二進位制版本應在 aros-archives 和 aminet 和/或 OS4Depot 上提供,以便安裝它們。(一些智慧程式可能需要提供,以使發行版開發人員的生活更輕鬆)。
  • 避免為 AROS 和其他 Amiga OS 並行派生程式。

如果確實需要一個託管 AROS 專案的地方,我們可以調查設定這樣的伺服器,但隨後為每個專案單獨包含錯誤跟蹤、治理、郵件列表等。我個人認為,像 sourceforge、google code、savannah 等地方已經足夠多,人們可以去那裡託管此類專案。

In the future...?
  • AROS 64 位 - SMP,具有 OpenGL 相容層級的 Vulkan
  • AROS 32 位 - 出於歷史原因保留

你想看到 AROS 中實現了什麼?完成 ABIv1、SMP(x86_64)、SendMsg()/GetMsg() 支援目標和目標之間的記憶體保護,依此順序。Michal Schulz 和 Jason McMullan 一直在思考“為支援 SMP,AmigaOS 3.1 API 需要做哪些最小的更改?”這個問題。到目前為止,答案似乎是“很少,但很微妙”。例如,SysBase->ThisTask 在 SMP 上不再有意義,但 FindTask(NULL) 有意義。Disable() 和 Forbid() 在效能方面非常糟糕,但是為 SignalSemaphore 新增一個自旋鎖訊號量模式將有助於 SMP 上的新程式碼。

利用具有大量機器支援的“通用”作業系統(Linux、MacOS、Windows、QNX 等)是 AROS 一直在做的事情,也是 AROS 最大的優勢。這種 AROS 體驗和程式設計模型,就像 Google 的 Android 在 Linux 之上分層,或者 MacOS X 在 Darwin/BSD 核心之上分層一樣,作為第一步

  • 圖形 + 圖層子系統可以作為 OpenGL ES 實現(即在任何現代 Linux 系統或 RaspberryPI 的硬體、MacOS X 等上)之上的一個墊片來實現。
 - This also allows every window to be on its own 3D surface with backing store, allowing Wanderer (or a Commodity)

重新排列/縮放/動畫應用程式視窗,而無需向它們傳送一堆重新整理

  • 使用 OpenAL 作為聲音後端
  • AROSTCP 將成為本機作業系統 TCP/IP 堆疊之上的一個薄層
  • dos.library、poseidon.library 和 input.device 將成為本機 API 之上的精簡墊片
  • 如果我們改為將所有庫載入到應用程式的任務空間中,而不是庫的單個全域性例項,這將更容易實現 SMP 和 MMU。
 - Yes, it will require a lot of work in the libraries to make this transition
 - Yes, I do think it will be worth it in the end.
  • 一種“胖二進位制”安裝格式(或者,也許是 LLVM 位元組碼),可以在安裝時“展平”到目標架構。

那麼,這個“未來的 AROS”會是什麼樣子呢?

  • AmigaOS 3.x 樣式的 API,以及對訊息傳遞的某些“根本性更改”
  • 使用底層作業系統的裝置驅動程式,因此 AROS 開發人員可以將更多精力投入到使用者可見的功能和錯誤修復中
  • 允許 AROS 應用程式與作業系統的原生應用程式並行執行


為什麼有人會想要在這個系統上程式設計呢?

  • AROS 應用程式可以在安裝了 AROS 框架的任何系統上執行
  • AROS 應用程式在所有平臺上都具有畫素級相同的效果。
  • 在瞭解你保證可以使用 OpenGL 和 OpenAL 以及其餘 AROS 框架的情況下進行開發

一個 mmake 選項,用於將其對 metatarget 的依賴關係轉儲到一個 graphviz[*] 輸入檔案中。這應該可以使視覺化依賴關係成為可能,並希望成為清理一些混亂、迴圈或不需要的依賴關係等的靈感。


AmigaOS gcc 9 舊版本 能夠為 AmigaOS 建立二進位制檔案,以及 升級 gcc 版本



參考文獻

[編輯 | 編輯原始碼]
  1. 參考文獻和來源
  2. AMIGA ROM 核心參考手冊:裝置,第 3 版。Commodore-Amiga, Inc. Addison-Wesley,1991。 ISBN 0-201-56775-X
華夏公益教科書