请原谅这个比较宽泛的问题。我想知道如何创建针对裸机x86的Ada工具链。我在osdev.org上看过Lucretia的Ada Bare Bones教程,该教程提供了一些有关为裸机开发构建合适的运行时的有用信息。这方面非常简单,但是我不确定如何为该平台构建交叉编译器,或者是否有必要。
我是否可以通过使用正确类型的RTS进行编译来创建“独立”二进制文件这一假设是否正确?如果我要创建/使用适当的独立式RTS,是否适合使用针对x86的现成的AdaCore或FSF GNAT?任何帮助理解这一点将不胜感激。
我遇到了一个问题,在 Ada 中使用不能被系统Storage_Unit(如运行时定义的system.ads)整除的模块化类型将Constraint_Error在运行时在访问时引发 a 。我最初在使用最小运行时间的裸机系统上遇到这个问题,同时尝试通过将 12 位数组覆盖在内存中的缓冲区上来从缓冲区读取 12 位值。有谁知道为什么会这样?
以下最小示例说明了我遇到的问题。我使用 AdaCore 的 GNAT 2019 对此进行了测试,并使用包含的zfp运行时编译。使用标准运行时不会重现该问题。
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
----------------------------------------------------------------------------
-- Modular type with standard size divisible by 8.
----------------------------------------------------------------------------
type Type_One is mod 2 ** 16;
type Buffer_Type_One is array (1 .. 128) of Type_One;
----------------------------------------------------------------------------
-- Modular type with non-base 8 size.
----------------------------------------------------------------------------
type Type_Two is mod 2 ** 12;
type Buffer_Type_Two is array (1 .. 128) …Run Code Online (Sandbox Code Playgroud) 如果我在这里混淆了一些术语,请原谅我,但我正在使用'$ lookup'运算符在聚合中执行连接操作,如下所示:
db.collection('items').aggregate([{$match: {}},
{
$lookup: {
from: 'usr',
localField: 'usr._id',
foreignField: '_id',
as: '__usr'
}
}, {
$project: {
info: 1,
timestamp: 1,
usr: {
"$arrayElemAt": [ "$__usr", 0 ]
}
}
}], (err, result) => {
res.json(result);
db.close();
});
Run Code Online (Sandbox Code Playgroud)
我正在对聚合结果进行投影,我正在使用'$ arrayElemAt'从结果数组中提取单个'usr'匹配.出于显而易见的原因,我不想返回包含敏感信息的整个"usr"记录.我要做的是使用'$ arrayElemAt'操作对返回的元素执行投影.我能够实现这一目标的唯一方法是使用原始投影的附加投影,如下所示:
db.collection('items').aggregate([{$match: {}},
{
$lookup: {
from: 'usr',
localField: 'usr._id',
foreignField: '_id',
as: '__usr'
}
}, {
$project: {
info: 1,
timestamp: 1,
usr: {
"$arrayElemAt": [ "$__usr", 0 ]
}
}
}, {
$project: {
info: …Run Code Online (Sandbox Code Playgroud) 如果这不符合 StackOverflow 格式,我们深表歉意。我目前正在学习编写 UEFI 应用程序。我一直在阅读 UEFI 标准以及大量在线教程,但我似乎无法弄清楚加载 UEFI 协议的正确方法是什么。所有教程似乎都在使用的方法上有所不同。
在许多情况下,教程遵循定位句柄然后遍历句柄缓冲区以打开协议的方法。示例如下所示:
EFI_HANDLE *handle_buffer;
UINTN handle_count;
EFI_GRAPHICS_OUTPUT_PROTOCOL *protocol;
// GNU-EFI wrapper.
status = uefi_call_wrapper(gBS->LocateHandleBuffer,
5,
ByProtocol,
&gEfiGraphicsOutputProtocolGuid,
NULL,
&handle_count,
&handle_buffer);
UINTN i = 0;
for(i = 0; i < handle_count; i++) {
status = uefi_call_wrapper(gBS->OpenProtocol, 6,
handle_buffer[i],
&gEfiGraphicsOutputProtocolGuid,
(VOID **)&protocol,
ImageHandle, // from `efi_main`
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
if(status == EFI_SUCCESS) {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您似乎可以直接使用该LocateProtocol功能加载协议。例子:
status = uefi_call_wrapper(gBS->LocateProtocol,
3,
&gEfiGraphicsOutputProtocolGuid,
NULL,
&graphics_service.protocol);
Run Code Online (Sandbox Code Playgroud)
以上两个例子都有效。我不确定我是否理解在加载协议之前获取句柄缓冲区的重要性,如一些教程和在线材料中所见。通过在 Github 上搜索示例,看起来两者可以互换使用,到目前为止我发现两者都可以正常工作。我知道在前一种方法中我需要释放缓冲区,因为它是从池中分配的,而在后一种方法中对此没有责任。
谁能指出哪种是加载 UEFI 协议的理想方法?这两种方法都有问题吗?任何帮助在这里将不胜感激。
当设置mstatus.mpp字段切换到主管模式时,我在调用 时遇到非法指令异常mret。qemu-system-riscv64我正在6.1版本的系统中对此进行测试riscv64-softmmu。我最近从 QEMU 5.0 升级到 6.1。在此升级之前,我的代码可以工作。我在变更日志中看不到任何相关内容。我假设我的代码中存在新版本根本无法容忍的问题。
下面是一个程序集片段,显示了正在发生的情况(删除了不相关的启动代码):
.setup_hart:
csrw satp, zero # Disable address translation.
li t0, (1 << 11) # Supervisor mode.
csrw mstatus, t0
csrw mie, zero # Disable interrupts.
la sp, __stack_top # Setup stack pointer.
la t0, asm_trap_vector
csrw mtvec, t0
la t0, kernel_main # Jump to kernel_main on trap return.
csrw mepc, t0
la ra, cpu_halt # If we return from main, halt.
mret
Run Code Online (Sandbox Code Playgroud)
如果我将该mstatus.mpp字段设置为机器模式,我就可以毫无问题地 …
从 PostgreSQL 列“u62194”获取数据时出错不存在
sql = """select userid from myusers WHERE userid='u62194' """ Of
course the hardcoded value works as it should.
import psycopg2
def select_tables():
someuserid = 'u62194'
print(someuserid)
""" Run a select using a variable that is a string """
sql = """select userid from myusers WHERE userid=%s """ %someuserid
conn = None
try:
conn = psycopg2.connect(user = "postgres",
password = "xxxxxx",
host = "127.0.0.1",
port = "5432",
database = "mydb")
cur = conn.cursor()
cur.execute(sql, (select_tables,))
print(cur.fetchone())
cur.close()
""" …Run Code Online (Sandbox Code Playgroud) 有没有一种快速可靠的方法可以找出内存中 Multiboot 1 启动信息的总大小?
\n\n只是为了澄清:我不是在询问 EBX 寄存器中的值所指向的结构的大小,而是在询问内存中所有信息的总大小。
\n\n我目前正在开发 x86 Multiboot 1 兼容内核。该标准不保证 GRUB 将在何处放置此信息或其总大小。标准规定:
\n\n\n\n\n“Multiboot信息结构及其相关子结构可以由引导加载程序放置在内存中的任何位置(当然,为内核和引导模块保留的内存除外)。这是操作系统\xe2\x80\x99的责任以避免覆盖该内存,直到使用完毕为止。”
\n
实际上,这似乎总是在最低 1MB 内存中加载。\n到目前为止,在启动期间,我使用最低 1MB 的标识映射来初始化启动分页结构,以确保可以访问多重启动信息。找出这个结构的位置很简单,但我还没有找到任何关于找到准确尺寸的信息。(最好不要走遍整个结构)。
\n我正在尝试INSERT将来的日期放入timestamp with time zonePostgres 9.6.2的表中的列中。我希望此日期为当前交易时间加上任意间隔,例如1小时。我知道如何在SELECT语句中执行日期/时间算术运算,但是相同的语法NOW() + INTERVAL '1 hour'似乎在INSERT语句中无效。
除了在应用程序级别完成此操作外,是否可以INSERT使用日期/时间算术使用单个语句来完成此操作?如果没有,在这种情况下最佳做法是什么?