Embox开始攀登厄尔布鲁士峰

那些关注我们项目的人可能已经注意到e2k文件夹已出现在具有体系结构的目录中,其中包含对具有Elbrus体系结构的家用处理器的支持。 没有有关该架构的故事,有关将Embox移植到国内平台的一系列 文章是不完整的。

我将对本文的内容进行一些评论。 首先,我们掌握此体系结构的过程尚处于初始阶段,我们设法在此平台上启动了Embox,但我们尚未实现许多必要的部分,将在以后的出版物中进行讨论。 其次,这种架构很复杂,并且
详细说明所需要的文本远远超出格式允许的文本
一篇文章。 因此,我们建议以本文作为介绍,
至少包含有关架构本身的技术信息。

让我们开始吧。

研究对象-Elbrus上的嵌入式系统布局


由于我们从事Embox(如果有人不知道,它专注于嵌入式系统),因此我们主要对MTsST本身的定位选项(包括嵌入式系统)感兴趣。 谈到MCST,我们发现该公司对将其处理器用于嵌入式系统很感兴趣。 E4C-COM板是此领域的最新解决方案之一。 在与MCST进行通信的过程中,很明显,要移植和掌握体系结构,您可以使用任何可用的机器,并且为我们提供了一台名为Monocub的计算机供临时使用。 总的来说,单立方不是我们在嵌入式系统中所惯用的。 通常,嵌入式系统使用单板计算机,芯片(即芯片上的系统,甚至是微控制器),但是monocube是成熟的计算机,但是由于已经在“气候和力学”中进行了测试,因此仍可以将其视为嵌入式系统。

编译,构建,填充图像


收到系统单元后,自然会出现一个问题-如何填写图像。 MCST使用其自己的BIOS(一级系统引导加载程序)。 默认情况下,已安装Elbrus操作系统(即带有修改的Debian)。 我们有兴趣发布自己的形象。 幸运的是,MTST加载程序可以通过网络运行映像。 为此,请使用ATA over Ethernet协议

在帮助我们建立了展台并通过网络发布外部映像之后,我们开始开发自己的映像。 为此,我们需要一个编译器。 我们没有在公共领域找到编译器,但是自从我们签署了NDA以来,我们已经获得了Linux的二进制文件。 事实证明,该编译器与gcc完全兼容,我们当然无需更改任何东西,除了编译标志外,我们将其放在单独的配置文件中。 这是非常可预见的,因为尽管有修改,但Linux是由该编译器组装而成的。

几个技术问题


那些从事将OS移植到平台之类的特定活动的人都知道,第一件事就是正确地将程序代码放入内存中。 也就是说,编写一个链接描述文件(lds)并实现启动代码。 我们很快找到了链接描述文件,但是在实现启动代码时,我们遇到了第一个魔力,但我们还没有完全理解。 事实是Elbrus具有x86兼容模式,并且在0x00FF0000处有一个代码,我将简单地给出一个链接 ,因为我们是从MCST示例中借用的。 链接描述文件包含

.bootinfo : { _bootinfo_start = .; /* . = 0x1000000 - 0x10000; */ /* 0x00FF0000 */ *(.x86_boot) . = _bootinfo_start + 0x10000; _bootinfo_end = .; } SECTION_REGION(bootinfo) .text : { _start = .; /* 0x01000000 */ *(.e2k_entry); 

入门代码本身甚至不是用汇编器编写的,而只是用C语言编写的 它将放置在0x01000000中的部分中,顺便说一句,它对应于常规x86机器的起始地址- 多重引导标头或另一个标头位于该地址。

为了确保起始代码和地址正确,您需要获取一些输出。 如果可以打印任何字符,则字符串的输出很可能不会出现问题。 使用此输出,已经可以使用熟悉的printf()进行调试。 此外,大多数平台都可以通过在特定寄存器中进行简单输入来输出字符(因为引导加载程序很可能已根据需要配置了UART)。

我们的计算机使用am85c30串行端口控制器(又名z85c30,我们很快就找到了打印一个字符的方法,这足以使我们的printf正常工作。我们立即面临一个奇怪的问题-printf打印的某些字符似乎重复了,但是例如,当我尝试输出Hello,world!时,结果变得类似Hhelellloo ,, woworrlldd。现在看来事情很明显是多核的,但起初我们是在驱动程序本身中摸索的。 +(1891VM7YA)( 为了避免与多核(SMP)发生冲突,引导加载程序将激活所有处理器内核,因此,除了第一个内核外,其他所有内核都被发送到一个无限循环中。为此,我们为处理器编号引入了一个变量,并使用原子加法对其进行递增零核继续工作,而其他内核循环。

  cpuid = __e2k_atomic32_add(1, &last_cpuid); if (cpuid > 1) { /* XXX currently we support only single core */ while(1); } /* copy of trap table */ memcpy((void*)0, &_t_entry, 0x1800); kernel_start(); 

kernel_start()调用已经是对我们代码的控制权转移。
我们还借用了原子加法,对我们来说,它看起来像魔术。 但是,正如您所知,它有效-请勿触摸!

 #define WMB_AFTER_ATOMIC ".word 0x00008001\n" \ ".word 0x30000084\n" #define __e2k_atomic32_add(__val, __addr) \ ({ \ int __rval; \ asm volatile ("\n1:" \ "\n\tldw,0 %[addr], %[rval], mas=0x7" \ "\n\tadds %[rval], %[val], %[rval]" \ "\n\t{"\ "\n\tstw,2 %[addr], %[rval], mas=0x2" \ "\n\tibranch 1b ? %%MLOCK" \ "\n\t}" \ WMB_AFTER_ATOMIC \ : [rval] "=&r" (__rval), [addr] "+m" (*(__addr)) \ : [val] "ir" (__val) \ : "memory"); \ __rval; \ }) 

我必须借用的另一个魔术是一些代码,这是所有内核所必需的。 即

 static inline void e2k_wait_all(void) { _Pragma ("no_asm_inline") asm volatile ("wait \ttrap = %0, ma_c = %1, fl_c = %2, ld_c = %3, " "st_c = %4, all_e = %5, all_c = %6" : : "i" (0), "i" (1), "i" (1), "i" (0), "i" (0), "i" (1), "i" (1) : "memory"); } 

结果,在编写启动代码之后,我们不仅使用printk显示了消息,而且还开始加载模块,这对于不太标准的编译器来说通常不是很简单。 因此,我再次注意到这次与gcc的兼容性非常令人满意。

下一步通常是启动中断控制器和计时器,但是认为我们不仅必须实现对这些设备的支持,而且还必须实现中断处理程序的体系结构代码,因此我们决定从外围开始。 monocub具有PCIe总线,对于程序员而言,它看起来像是常规PCI。 我们主要对两种设备感兴趣:显示控制器和网络控制器。

monocube使用sm750系列的图形控制器。 这是用于嵌入式应用程序的图形控制器,具有对2d图形的板载支持。 据我了解,该芯片直接焊接到主板上。 Linux驱动程序的源代码可以在这里找到。

找到驱动程序后,似乎我们的问题已经解决,仅需实现PCI控制器即可。 更准确地说,对PCI配置空间的读/写操作可以找出参数。 这些功能的实现必须再次借用。 结果,读取记录归结为以下宏

 /* * Do load with specified MAS */ #define _E2K_READ_MAS(addr, mas, type, size_letter, chan_letter) \ ({ \ register type res; \ asm volatile ("ld" #size_letter "," #chan_letter " \t0x0, [%1] %2, %0" \ : "=r" (res) \ : "r" ((__e2k_ptr_t) (addr)), \ "i" (mas)); \ res; \ }) #define _E2K_WRITE_MAS(addr, val, mas, type, size_letter, chan_letter) \ ({ \ asm volatile ("st" #size_letter "," #chan_letter " \t0x0, [%0] %2, %1" \ : \ : "r" ((__e2k_ptr_t) (addr)), \ "r" ((type) (val)), \ "i" (mas) \ : "memory"); \ }) 

对正在发生的事情有一些了解。 Elbrus具有多个备用地址空间,例如在SPARC体系结构中 。 标识是使用地址空间标识符完成的。 也就是说,同一ld命令到达不同的内部地址,它还会生成不同长度(8、16、32、64位)的读取操作。 如果在SPARC中这是一个单独的lda / sta命令,那么在Elbrus中,由于参数的缘故,这是ld命令。 注册窗口是从SPARC体系结构借用的。 在以后的文章中,我将推迟更详细的故事。

结果,一切都通过PCI得以实现。 我们能够获得所有必要的数据,并将图形驱动程序转移给我们自己,但是随后遇到了以下问题。 要在视频存储器中绘制图片,您必须写两次。 一切都指向缓存。 为了解决这个问题,有必要对MMU进行处理,正如他们所说,这不能用condachka来解决,因为从原则上讲,在此体系结构的开发过程中我们遇到并且将不止一次遇到许多其他问题。

我们在其他方面取得了进展:中断和系统调用,但是我们还将在本系列的下一篇文章中讨论这一点。 在本文的最后,我将简单地将输出带到控制台(通过串行端口)。


结论


正如我在导言中所说,我主要不关注技术细节,而是关注一般感受。 因此,这种感觉是矛盾的,尽管肯定会更加积极。 一方面,处理器存在并且在架构特征方面非常有趣。 基于该处理器,可以生产计算机系统,并且具有相当高质量的软件。 正如我所说,没有任何关于编译器的抱怨(直到某个时候,我将在稍后描述),这里有一个成熟的Linux(OS“ Elbrus”)。 我亲自看到了ICST本身,开发人员是如何在Elbrus架构的桌面上直接创建的。

但是,另一方面,我不明白为什么他们会以这种持久性试图从该处理器上替代英特尔x86。 实际上,世界上没有任何地方将基于VLIW架构的处理器用作通用个人计算机。 由于其体系结构特性,VLIW是一个很酷的“数字粉碎机”,他们在其上制造DSP,他们制造了itanium服务器,他们制造了图形卡。 不,当然,使用挖掘机,您可以挖一个洞来种树,但这是值得的。

我认为,阻碍建筑发展的主要问题是整个生态系统的封闭性。 是的,为了获得命令系统的描述,您只需要签署NDA,但这还不够。 该架构不熟悉且非常复杂。 是的,我一直认为应该直接从处理器制造商那里开发一些基本软件,或者与他密切合作。 根据此原理,Elbrus上的PC带有Elbrus OS软件包。 但是,仍然天真地相信一个公司,甚至是大公司,可以为所有组件提供高质量的支持:处理器,编译器,开发和调试工具,系统软件(各种OS),应用软件,... 甚至英特尔也无法做到这一点。 长期以来,世界一直在朝着所谓的合作或联合发展迈进。

让我举一个我们偶然发现的编译器问题的例子。 串行端口驱动程序有时停止显示字符,乍一看,没有任何变化。 原来,我们删除了未使用的调试功能,我们插入了该功能是为了通过反汇编程序了解如何在汇编程序中将参数传递给该函数。 也就是说,如果该函数存在,那么一切都很好,否则,输出将消失。 最初,他们为对齐而犯了罪,但事实证明该功能可以转移到C-Schnick的末尾,因此驱动程序中的所有字符都和以前一样在同一位置,但问题仍然存在。 尽管此问题尚未解决,但我们将继续进行调查,以向MCST展示编译器的开发人员或了解我们在哪里犯了错误。

我认为,如果有更多的第三方用户,可以避免上述问题。 至少,这个问题至少可以早日发现,或者可以用谷歌搜索我们做错了什么。

ICST也意识到关闭的问题,因为打开未分类物品的过程已经开始。 例如,我在几次会议上看到Alt-Linux在多台Elbrus PC上工作。 这是今年其中一个会议的显示图片(很抱歉看到的很糟糕,很暗)。 我们也与发展联系在一起。 我们希望对ICST有所帮助,因为事实证明,Linux无法支持Elbrus体系结构的某些亮点(或者成本很高),例如标记内存。



当我们与MCST的开发人员讨论关闭问题时,另一个重要点是,他们反对,例如,Linux内核源代码很长时间都是开放的,但是只有我们和Dolomant开发人员提出问题并以某种方式使用它们。

此外,根据我的信息,MCST将组织一个摊位
可以远程访问。 在其上,可以在具有Elbrus架构的PC上组装和运行软件。 如果您有类似的兴趣并想使用该支架,则应与我联系,例如:描述如何计划使用它,花费多长时间等,因为要与更改软件共享,您需要安排时间表。 我会将数据传输到ICST,或者将需要的人与组织者联系起来。



有用的链接:

用户的邮件地址是用户[at] mcst.ru
布鲁斯建筑的简要说明
Embox来源

PS:我们将 9月1-2日的TechTrain IT节向所有想要我们获得什么的人展示。

Source: https://habr.com/ru/post/zh-CN421441/


All Articles