跳转到内容

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
华夏公益教科书