fixes and documenting all used ableos ecalls

This commit is contained in:
koniifer 2025-01-08 01:03:42 +00:00
parent 70a81a3dd9
commit e4d72a6352
5 changed files with 55 additions and 4 deletions

View file

@ -24,7 +24,7 @@ Vec := fn($T: type, $A: type): type return struct {
self.slice.ptr = new_alloc
} else {
self.cap *= 2
// ! (c_native) (compiler) bug: null check broken, so unwrapping (unsafe!)
// ! (libc) (compiler) bug: null check broken, so unwrapping (unsafe!)
new_alloc := @unwrap(self.allocator.realloc(T, self.slice.ptr, self.cap))
self.slice.ptr = new_alloc
}

View file

@ -2,7 +2,7 @@
$FP_TOLERANCE := 0.00000001
// ! (c_native) (compiler) bug: caused by: `lily.log.print(100)`
// ! (libc) (compiler) bug: caused by: `lily.log.print(100)`
fmt_int := fn(buf: []u8, v: @Any(), radix: @TypeOf(v)): uint {
is_negative := TypeOf(v).is_signed_int() & v < 0
prefix_len := 0

View file

@ -61,7 +61,7 @@ fmt := @use("fmt.hb");
.{Type, TypeOf} := @use("type.hb")
// ! (compiler) bug: inlining here crashes the parser. nice.
// ! (c_native) (compiler) bug: NOT inlining here makes it sometimes not work
// ! (libc) (compiler) bug: NOT inlining here makes it sometimes not work
$panic := fn(message: ?[]u8): never {
if message != null log.error(message) else log.error("The program called panic.")
exit(1)

View file

@ -0,0 +1,51 @@
# Documenting the used features of the AbleOS spec
> [!Important]
> this does not apply to all hbvm targets. it applies to AbleOS specifically. other hbvm targets will have different ecalls, or even no ecalls. for an example of another project using hbvm, see [depell](https://depell.mlokis.tech/) (dependency hell), a website created by mlokis, the main programmer of hblang, that runs hblang programs, in hbvm, in wasm.
## How do ecalls work?
ecalls are comprised of a series of values, with each consecutive one representing the value of a vm register from 1-255 (the 0 register is reserved). `ecall a b c` fills the first three registers with the values `a`, `b`, and `c` respectively. the ecall handler reads these values and performs a kernel operation based on them.
## How is this formatted?
all registers are followed by parethesis with their purpose. the `message` section is actually a pointer to a single location in memory, taking a single register. the following register is always the size of this message. this is omitted for brevity.<br>
`ecall register(purpose), ..., register(purpose), message_bytes:type, ..., message_bytes:type`
## More info?
read [here](https://git.ablecorp.us/AbleOS/ableos/src/branch/master/kernel/src/holeybytes/ecah.rs) for the full set of ecalls and buffer ids.
### `lily.log`:
log: `ecall 3(buf), 1(log), loglevel:u8, string:*const u8, strlen:u64`<br>
> formats and then copies `strlen` of `string` into the serial output
### `lily.Target.AbleOS`:
malloc: `ecall 3(buf), 2(mem), 0(alloc), page_count:u64, zeroed:bool=false`
> returns `Option<*mut u8>` to an available contiguous chunk of memory, sized in `4096` byte (align `8`) pages. it is undefined behaviour to use size zero.
calloc: `ecall 3(buf), 2(mem), 0(alloc), page_count:u64, zeroed:bool=true`<br>
> same as malloc, except filled with zeroes.
realloc: `ecall 3(buf), 2(mem), 7(realloc), page_count:u64, page_count_new:u64, ptr:*const u8, ptr_new:*const u8`<br>
> resizes an existing contiguous chunk of memory allocated via `malloc`, `calloc`, or `realloc`. contents remain the same. it is undefined behaviour to use size zero or a `null` pointer. returns a new `Option<*mut u8>` after resizing.
free: `ecall 3(buf), 2(mem), 1(free), page_count:u64, ptr:*const u8`<br>
> releases an existing contiguous chunk of memory allocated via `malloc`, `calloc`, or `realloc`. it is undefined behaviour to use size zero or a `null` pointer.
memcpy: `ecall 3(buf), 2(mem), 4(memcopy), size:u64, src:*const u8, dest:*const u8`<br>
> copies `size` of `src` into `dest`. `src` and `dest` must not be overlapping. it is undefined behaviour to use size zero or a `null` pointer.
memset: `ecall 3(buf), 2(mem), 5(memset), count:u64, size:u64, src:*const u8, dest:*mut u8`<br>
> consecutively copies `size` of `src` into `dest` a total of `count` times. `src` and `dest` must not be overlapping. it is undefined behaviour to use size zero or a `null` pointer.
memmove: `ecall 3(buf), 2(mem), 6(memmove), size:u64, src:*const u8, dest:*mut u8`<br>
> copies `size` of `src` into a buffer, then from the buffer into `dest`. `src` and `dest` can be overlapping. it is undefined behaviour to use size zero or a `null` pointer.
getrandom: `ecall 3(buf) 4(rand) dest:*mut u8, size:u64`
> fills `dest` with `size` bytes of random cpu entropy.
## ecall numbers (u8)
3. send a message to a buffer
## buffer ids (uint)
1. logging service
2. memory service
4. random service

View file

@ -1,4 +1,4 @@
.{LogLevel} := @use("../lib.hb").std.log
.{LogLevel} := @use("../lib.hb").log
$PAGE_SIZE := 4096