Build original Ada port core, V client, and x86-64 boot milestone

This commit is contained in:
Admin committed 2026-11-01 16:07:00 +08:00
1 parent 9af96aa1e1
commit fc2bee6f32
28 files changed
+865 -7

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
with Interfaces; use Interfaces;
with System.Machine_Code; use System.Machine_Code;
with Agila_Ports; use Agila_Ports;
procedure Boot_Main (Magic : Unsigned_32) is
State : Manager;
Handle, Replacement : Word;
Result : Status;
Item : Message;
procedure Out_Byte (Port : Unsigned_16; Value : Unsigned_8) is
begin
Asm ("outb %0, %1", Inputs => (Unsigned_8'Asm_Input ("a", Value),
Unsigned_16'Asm_Input ("Nd", Port)), Volatile => True);
end Out_Byte;
function In_Byte (Port : Unsigned_16) return Unsigned_8 is
Value : Unsigned_8;
begin
Asm ("inb %1, %0", Outputs => Unsigned_8'Asm_Output ("=a", Value),
Inputs => Unsigned_16'Asm_Input ("Nd", Port), Volatile => True);
return Value;
end In_Byte;
procedure Line (Text : String) is
Full_Text : constant String := Text & ASCII.CR & ASCII.LF;
begin
for C of Full_Text loop
for Attempt in 1 .. 10_000 loop
exit when (In_Byte (16#3FD#) and 16#20#) /= 0;
end loop;
Out_Byte (16#3F8#, Unsigned_8 (Character'Pos (C)));
end loop;
end Line;
procedure Finish (Success : Boolean) with No_Return;
procedure Finish (Success : Boolean) is
Code : constant Unsigned_32 := (if Success then 16#10# else 16#11#);
begin
if Success then Line ("AGILA_BOOT_OK"); else Line ("AGILA_BOOT_FAILED"); end if;
Asm ("outl %0, %1", Inputs => (Unsigned_32'Asm_Input ("a", Code),
Unsigned_16'Asm_Input ("Nd", 16#F4#)), Volatile => True);
loop Asm ("cli; hlt", Volatile => True); end loop;
end Finish;
procedure Check (Condition : Boolean) is
begin
if not Condition then Finish (False); end if;
end Check;
begin
Out_Byte (16#3F9#, 0); Out_Byte (16#3FB#, 16#80#);
Out_Byte (16#3F8#, 3); Out_Byte (16#3F9#, 0);
Out_Byte (16#3FB#, 3); Out_Byte (16#3FA#, 16#C7#);
Out_Byte (16#3FC#, 16#0B#);
Line ("OPEN_AGILA_X86_64_ADA");
Check (Magic = 16#2BADB002#);
Create (State, 10, Handle, Result); Check (Result = Ok);
Send (State, Handle, 20, 42, Result); Check (Result = Permission_Denied);
Allow_Sender (State, Handle, 10, 20, Result); Check (Result = Ok);
for I in 1 .. Queue_Capacity loop
Send (State, Handle, 20, Word (I), Result); Check (Result = Ok);
end loop;
Send (State, Handle, 20, 99, Result); Check (Result = Full);
for I in 1 .. Queue_Capacity loop
Receive (State, Handle, 10, Item, Result);
Check (Result = Ok and Item.Value = Word (I) and Item.Sender = 20);
end loop;
Receive (State, Handle, 10, Item, Result); Check (Result = Empty);
Close (State, Handle, 10, Result); Check (Result = Ok);
Create (State, 30, Replacement, Result); Check (Result = Ok and Replacement /= Handle);
Send (State, Handle, 10, 1, Result); Check (Result = Invalid_Handle);
Line ("ADA_PORTS_BOOT_TESTS_OK");
Line ("Boot milestone: one address space; no user services or desktop yet.");
Finish (True);
end Boot_Main;
+3
View File
@@ -0,0 +1,3 @@
with Interfaces;
procedure Boot_Main (Magic : Interfaces.Unsigned_32)
with Export, Convention => C, External_Name => "agila_boot_main", No_Return;
+8
View File
@@ -0,0 +1,8 @@
set timeout=0
set default=0
serial --unit=0 --speed=38400
terminal_output serial
menuentry "Open Agila Ada boot milestone" {
multiboot /boot/open-agila.elf
boot
}
+9
View File
@@ -0,0 +1,9 @@
ENTRY(_start)
SECTIONS {
. = 1M;
.text ALIGN(4K) : { KEEP(*(.multiboot)) *(.text.boot) *(.text*) }
.rodata ALIGN(4K) : { *(.rodata*) }
.data ALIGN(4K) : { *(.data*) }
.bss ALIGN(4K) : { *(COMMON) *(.bss*) }
/DISCARD/ : { *(.eh_frame*) *(.comment) *(.note*) }
}
+18
View File
@@ -0,0 +1,18 @@
/* Freestanding compiler support, not an allocator or a VM subsystem. */
#include <stddef.h>
void *memset(void *dst,int value,size_t count) {
unsigned char *d=dst;
for(size_t i=0;i<count;i++)d[i]=(unsigned char)value;
return dst;
}
void *memcpy(void *dst,const void *src,size_t count) {
unsigned char *d=dst;const unsigned char *s=src;
for(size_t i=0;i<count;i++)d[i]=s[i];
return dst;
}
void *memmove(void *dst,const void *src,size_t count) {
unsigned char *d=dst;const unsigned char *s=src;
if((size_t)d<(size_t)s){for(size_t i=0;i<count;i++)d[i]=s[i];}
else {while(count){count--;d[count]=s[count];}}
return dst;
}
+83
View File
@@ -0,0 +1,83 @@
/* Original Open Agila Multiboot v1 entry. QEMU x86-64/BIOS target only. */
.section .multiboot,"a"
.balign 4
.long 0x1badb002
.long 0x00000003
.long -(0x1badb002 + 0x00000003)
.section .text.boot,"ax"
.code32
.global _start
.type _start,@function
_start:
cli
cld
mov %eax, boot_magic
mov $stack_top, %esp
/* GRUB enters 32-bit protected mode. Map the first GiB with 2 MiB pages.
These writable executable boot mappings are NOT process isolation. */
mov $pdpt, %eax
or $3, %eax
mov %eax, pml4
mov $page_directory, %eax
or $3, %eax
mov %eax, pdpt
xor %ecx, %ecx
1:
mov %ecx, %eax
shl $21, %eax
or $0x83, %eax
mov %eax, page_directory(,%ecx,8)
inc %ecx
cmp $512, %ecx
jne 1b
mov %cr4, %eax
or $0x20, %eax
mov %eax, %cr4
mov $pml4, %eax
mov %eax, %cr3
mov $0xc0000080, %ecx
rdmsr
or $0x100, %eax
wrmsr
lgdt gdt_pointer
mov %cr0, %eax
or $0x80000000, %eax
mov %eax, %cr0
ljmp $0x08, $long_mode
.code64
long_mode:
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
xor %eax, %eax
mov %ax, %fs
mov %ax, %gs
mov $stack_top, %rsp
xor %rbp, %rbp
mov boot_magic(%rip), %edi
call agila_boot_main
2: cli
hlt
jmp 2b
.section .rodata,"a"
.balign 8
gdt:
.quad 0
.quad 0x00af9a000000ffff
.quad 0x00cf92000000ffff
gdt_end:
gdt_pointer:
.word gdt_end-gdt-1
.long gdt
.section .bss,"aw",@nobits
.balign 4
boot_magic: .skip 4
.balign 4096
pml4: .skip 4096
pdpt: .skip 4096
page_directory: .skip 4096
.balign 16
stack_bottom: .skip 65536
stack_top:
.section .note.GNU-stack,"",@progbits