ChibraxOS 2

Changes:
- kernel 6.0.2
- Broken init scripts
- Switch to bun for better peroformance an easier ffi
- Removed grup
- Efi support without graphics (at least graphics werent tested)
- Suppression de toutes les dépendance non libc
- new splash
- broken audio
- typescript support
- ls rewritten to be more reliable
This commit is contained in:
Marc
2022-10-22 13:47:33 +02:00
parent db49f8d205
commit 721c919c7b
76 changed files with 2485 additions and 2665 deletions
+9 -5
View File
@@ -1,9 +1,13 @@
const fs = require('fs')
import * as fs from 'fs'
const audiopath = '/dev/audio'
module.exports = (path) => {
if(fs.existsSync(path) && fs.existsSync(audiopath)) {
const data = fs.readFileSync(path)
fs.writeFileSync(audiopath, data)
export default function play(path) {
if(fs.existsSync(audiopath)) {
if(fs.existsSync(path)) {
const data = fs.readFileSync(path)
fs.writeFileSync(audiopath, data)
}
} else {
console.log('Kernel doesn\'t have snd_pcm_oss or snd_seq_oss or snd_mixer_oss')
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
//@ts-check
/** @type {{ [key: number]: string | undefined }} */
module.exports = {
export default {
1: "EPERM", //Operation not permitted
2: "ENOENT", //No such file or directory
3: "ESRCH", //No such process
@@ -82,7 +82,7 @@ module.exports = {
81: "ELIBSCN", //lib section in a.out corrupted
82: "ELIBMAX", //Attempting to link in too many shared libraries
83: "ELIBEXEC", //Cannot exec a shared library directly
84: "EILSEQ", //Illegal byte sequence
84: "EILSEQ", //Illegal byte sequencerequire
85: "ERESTART", //Interrupted system call should be restarted
86: "ESTRPIPE", //Streams pipe error
87: "EUSERS", //Too many users
@@ -130,4 +130,4 @@ module.exports = {
129: "EKEYREJECTED", //Key was rejected by service
130: "EOWNERDEAD", //Owner died
131: "ENOTRECOVERABLE",
}
}
+10 -12
View File
@@ -1,6 +1,6 @@
//@ts-check
const fs = require('fs')
const jimp = require('jimp')
import * as fs from 'fs'
import * as jimp from 'jimp'
const screen = getScreenDimensions()
const buffer = Buffer.alloc(screen.width * screen.height * screen.byteDepth)
@@ -24,7 +24,7 @@ function getScreenDimensions() {
/**
* @param { Buffer } data
*/
function flip(data = buffer) {
export function flip(data = buffer) {
try {
fs.writeFileSync('/dev/fb0', data, { encoding: 'binary' })
} catch(e) {
@@ -33,14 +33,14 @@ function flip(data = buffer) {
}
}
function clear() {
export function clear() {
buffer.fill(0)
}
/**
* @param {string} filepath
*/
function removeFromCache(filepath) {
export function removeFromCache(filepath) {
delete imageCache[filepath]
}
@@ -48,7 +48,7 @@ function removeFromCache(filepath) {
* @param {string} filepath
* @returns { Promise<import('@jimp/core').Bitmap> } BGRA buffer
*/
async function readImgFile(filepath) {
export async function readImgFile(filepath) {
const img = await jimp.read(filepath)
const bitmap = img.bitmap
bitmap.data = rgbaTObgra(bitmap.data)
@@ -60,7 +60,7 @@ async function readImgFile(filepath) {
* @param { number } y
* @param { import('@jimp/core').Bitmap | Pencil } bitmap
*/
function drawBitmap(x, y, bitmap, handleTransparency = true) {
export function drawBitmap(x, y, bitmap, handleTransparency = true) {
for(let dy = 0; dy < bitmap.height; dy++) {
let bitmapLineEnd = bitmap.width * screen.byteDepth * (dy + 1)
let bitmapLineStart = bitmap.width * screen.byteDepth * dy
@@ -123,7 +123,7 @@ function drawBitmap(x, y, bitmap, handleTransparency = true) {
* @description this function work fine but will use caching. to clear the cache you can use removeFromCache(filepath) or you can keep the cache on the
* client side and use readImgFile and drawBitmap methods instead
*/
async function drawImgFile(x, y, filepath) {
export async function drawImgFile(x, y, filepath) {
//not caching would imply reading the image each time we want to write it to the screen even for small movement
let bitmap;
if(!imageCache[filepath]) {
@@ -153,7 +153,7 @@ function rgbaTObgra(buff) {
* @param { string } color
* @returns { number[] }
*/
function parseHexColor(color) {
export function parseHexColor(color) {
if(!color.startsWith('#') || color.length !== 7) {
throw new Error('invalid hex color code')
}
@@ -169,7 +169,7 @@ function parseHexColor(color) {
* @param { number } y
* @param { string | number[] } colorCode
*/
function setPixel(x, y, colorCode) {
export function setPixel(x, y, colorCode) {
if (screen.byteDepth !== 4) {
throw new Error('Depth not supported yet')
}
@@ -179,5 +179,3 @@ function setPixel(x, y, colorCode) {
}
buffer.set(colorCode, (x + y * screen.width) * screen.byteDepth)
}
module.exports = { flip, clear, getScreenDimensions, drawImgFile, readImgFile, drawBitmap, parseHexColor, setPixel, removeFromCache }
+21 -34
View File
@@ -1,52 +1,39 @@
//@ts-check
const { exec, fork, spawn } = require('child_process');
/**
* @param {string} path
* @deprecated
*/
function hookTo(path) {
exec(`node ${path}`)
}
import { spawnSync, spawn } from 'bun'
/**
* @param {string} path
*/
async function fHook(path) {
const child = fork(path)
return new Promise((res, rej) => {
child.on('exit', () => {
res()
})
})
export async function fHook(path) {
return await spawnAndWait([ '/usr/bin/bun', 'run', path ])
}
/**
* @param { string } cmd
* @param { import('child_process').SpawnOptionsWithoutStdio } [option]
* @param { [string, ...string[]] } cmd
* @param { import('bun').SpawnOptions.OptionsObject } [option]
*/
async function spawnAndWait(cmd, option) {
const child = spawn(cmd, option)
export async function spawnAndWait(cmd, option) {
console.log('spawning ' + cmd.join(' '))
return spawnSync(cmd, {
...option,
env: {
PATH: "/bin:/sbin:/usr/bin:/usr/sbin",
...process.env,
...(option?.env || {})
},
child.stdout.pipe(process.stdout)
child.stderr.pipe(process.stderr)
process.stdin.pipe(child.stdin)
await new Promise((res, rej) => {
child.on('exit', () => {
res()
})
stdout: "inherit",
stdin: "inherit",
stderr: "inherit"
})
process.stdin.unpipe(child.stdin)
}
/**
* @param { string } path
* @param { string[] } [args]
* @param { import('child_process').SpawnOptionsWithoutStdio } [options]
* @param { import('bun').SpawnOptions.OptionsObject } [options]
*/
async function startjs(path, args = [], options = {}) {
const arguments = args.map(arg => {return arg.includes(' ') ? `"${arg}"` : arg}).join(' ')
return spawnAndWait(`/usr/local/bin/node ${path} ${arguments}`, options)
export async function startjs(path, args = [], options = {}) {
const SpawnArguments = args.map(arg => {return arg.includes(' ') ? `"${arg}"` : arg})
return spawnAndWait(['/usr/bin/bun', path, ...SpawnArguments ], options)
}
module.exports = { hookTo, fHook, spawnAndWait, startjs }
+5 -6
View File
@@ -1,5 +1,8 @@
//@ts-check
const fs = require('fs')
import * as fs from 'fs'
import { init } from './initd.js'
import * as reboot from './reboot.js'
import { fHook } from './hook.js'
function panic() {
console.log("/!\\ INIT PANIK /!\\ LOSE CHIBRE")
@@ -8,13 +11,9 @@ function panic() {
async function main() {
try {
const initd = require('./initd.js')
const reboot = require('./reboot.js')
const { fHook } = require("./hook.js")
console.clear()
await initd()
await init()
//chainload into sheebr
if(fs.existsSync("/usr/bin/sheebr.js")) {
+3 -6
View File
@@ -1,11 +1,11 @@
//@ts-check
const fs = require('fs')
const path = require('path')
import * as fs from 'fs'
import * as path from 'path'
/**
* @typedef {{ name: string, before: string[], after: string[], init(): undefined | Promise<undefined> }} InitScript
*/
async function init() {
export async function init() {
const initdFiles = fs.readdirSync('/etc/init.d/')
const initdScripts = initdFiles.filter( (v) => v.endsWith('.js'))
@@ -78,6 +78,3 @@ function processBefores(scripts) {
}
return result
}
module.exports = init
+2 -19
View File
@@ -5,23 +5,6 @@
* @param {string} str
* @returns
*/
async function input(str) {
console.log(str)
process.stdin.resume();
process.stdin.setEncoding('utf8');
let line = "";
return new Promise((res, rej) => {
process.stdin.on('data', function(chunk) {
line += chunk
if (chunk.toString('utf-8').endsWith('\n')) {
process.stdin.pause()
res(line.substring(0, line.length -1))
}
});
process.stdin.on('error', function(err) {
rej(err)
})
})
export default async function input(str) {
return await Bun.stdin.text()
}
module.exports = input
-6
View File
@@ -1,6 +0,0 @@
//@ts-check
//@ts-expect-error
const { ioctl } = require('./ioctl.node')
module.exports = { ioctl }
@@ -1,7 +1,5 @@
//@ts-check
//@ts-expect-error
const ip = require('./ip.node')
const flags = {
IFF_UP: 0x1, /* Interface is up. */
@@ -51,4 +49,4 @@ function setIpv4(interface, address) {
ip.setIpv4(interface, address.join('.'));
}
module.exports = { setFlags, getFlags, setIpv4, flags }
module.exports = { setFlags, getFlags, setIpv4, flags }
+23 -16
View File
@@ -1,26 +1,34 @@
//@ts-check
//@ts-expect-error
const { syscall } = require('./syscall.node')
const errno = require('./errno')
const fs = require('fs')
const path = require('path')
import { dlopen, FFIType } from 'bun:ffi';
import errno from './errno.js'
import * as fs from 'fs'
import * as path from 'path'
const {
symbols: {
syscall,
},
} = dlopen('/usr/lib/libc.so.6', {
syscall: {
args: [ FFIType.int, FFIType.int, FFIType.cstring, FFIType.int ],
returns: FFIType.int,
},
});
// TBD
const SYSCALL_INIT_MODULE = 105
const SYSCALL_FINIT_MODULE = 273
const doProcExists = () => fs.existsSync('/proc')
export const doProcExists = () => fs.existsSync('/proc')
/**
*
* @param {string} path
* @param {string} params
* @param {number} flags
* @deprecated un tested dangerous
* @deprecated untested very dangerous
*/
function finit_module(path, params = "", flags = 0) {
export function finit_module(path, params = "", flags = 0) {
const fileDescriptor = fs.openSync(path, 'r')
const result = syscall(SYSCALL_FINIT_MODULE, fileDescriptor, params, flags)
if(result > 0) {
@@ -34,8 +42,8 @@ function finit_module(path, params = "", flags = 0) {
}
}
function uname() {
if(!doProcExists) {
export function uname() {
if(!doProcExists()) {
throw "Proc don't exists exception"
}
const linuxVersionString = fs.readFileSync('/proc/version').toString()
@@ -44,8 +52,9 @@ function uname() {
/**
* @param {string} modulename
* @deprecated untested very dangerous
*/
function modprobe(modulename) {
export function modprobe(modulename) {
const name = uname()
if(fs.existsSync(path.join('/lib/modules', name, 'kernel', modulename))) {
finit_module(path.join('/lib/modules', name, 'kernel', modulename))
@@ -55,11 +64,9 @@ function modprobe(modulename) {
}
function lsmod() {
if(!doProcExists) {
export function lsmod() {
if(!doProcExists()) {
throw "Proc don't exists exception"
}
return fs.readFileSync('/proc/modules').toString('utf-8').split('\n')
}
module.exports = { modprobe, uname, finit_module, doProcExists, lsmod, syscall }
+20 -21
View File
@@ -1,18 +1,11 @@
//@ts-check
const fs =require('fs')
/**
* @type {{ mount: (device_path: string, mount_point: string, fs: string, flags: number, fsparams: string ) => number }}
*///@ts-expect-error
const nodemount = require("./mount.node")
/**
* @deprecated
*/
const cmount = nodemount.mount
import * as fs from 'fs'
import { dlopen, FFIType } from 'bun:ffi'
import { filesystems } from './suportedFilesystems'
/* These are the fs-independent mount-flags: up to 16 flags are
supported */
const flags = {
export const flags = {
MS_RDONLY: 1, /* Mount read-only. */
MS_NOSUID: 2, /* Ignore suid and sgid bits. */
MS_NODEV: 4, /* Disallow access to device special files. */
@@ -41,6 +34,19 @@ const flags = {
MS_NOUSER: 1 << 31
};
const {
symbols: {
mount,
},
} = dlopen('/usr/lib/libc.so.6', {
mount: {
args: [ FFIType.cstring, FFIType.cstring, FFIType.cstring, FFIType.u64, FFIType.cstring ],
returns: FFIType.int,
},
});
/**
* @param {string} devicePath
* @param {string} mountPoint
@@ -49,20 +55,13 @@ const flags = {
* @param {string} fsparams
* @returns {number}
*/
function mount(devicePath, mountPoint, fstype, flags, fsparams) {
const supportedFilesystems = require('./suportedFilesystems')
const filesystem = supportedFilesystems.find( v => v.name === fstype)
export function JSmount(devicePath, mountPoint, fstype, flags, fsparams) {
const filesystem = filesystems.find( v => v.name === fstype)
if(! filesystem) {
throw "Invalid filesystem"
}
if(! fs.existsSync(devicePath) && filesystem.hasdev)
throw "Device don't exist"
return cmount(devicePath, mountPoint, fstype, flags, fsparams)
return mount(Buffer.from(devicePath), Buffer.from(mountPoint), Buffer.from(fstype), flags, Buffer.from(fsparams))
}
module.exports = { mount, cmount, flags }
-3
View File
@@ -1,7 +1,4 @@
{
"devDependencies": {
"@types/node": "^16.11.21"
},
"dependencies": {
"jimp": "^0.16.1"
}
+27 -22
View File
@@ -1,4 +1,6 @@
//@ts-check
import { dlopen, FFIType } from 'bun:ffi';
/* Perform a hard reset now. */
const RB_AUTOBOOT = 0x01234567
@@ -20,37 +22,40 @@ const RB_SW_SUSPEND = 0xd000fce2
/* Reboot system into new kernel. */ //no idea how to use that but hey
const RB_KEXEC = 0x45584543
/**
@type {{
reboot: (rebootid: number) => void //https://unix.superglobalmegacorp.com/Net2/newsrc/sys/syscall.h.html
syscall: (syscallid: number) => void
}}
*///@ts-expect-error
const syscalls = require('./syscall.node')
function disableCtrlAltSupr() {
syscalls.reboot(RB_DISABLE_CAD)
const {
symbols: {
reboot,
},
} = dlopen('/usr/lib/libc.so.6', {
reboot: {
args: [ FFIType.int ],
returns: FFIType.int,
},
});
export function disableCtrlAltSupr() {
reboot(RB_DISABLE_CAD)
}
function enableCtrlAltSupr() {
syscalls.reboot(RB_ENABLE_CAD)
export function enableCtrlAltSupr() {
reboot(RB_ENABLE_CAD)
}
function halt() {
syscalls.reboot(RB_HALT_SYSTEM)
export function halt() {
reboot(RB_HALT_SYSTEM)
}
function reboot() {
syscalls.reboot(RB_AUTOBOOT)
export function classicReboot() {
reboot(RB_AUTOBOOT)
}
function powerOff() {
syscalls.reboot(RB_POWER_OFF)
export function powerOff() {
reboot(RB_POWER_OFF)
}
function suspend() {
syscalls.reboot(RB_SW_SUSPEND)
export function suspend() {
reboot(RB_SW_SUSPEND)
}
module.exports = { disableCtrlAltSupr, enableCtrlAltSupr, halt, reboot, powerOff, suspend }
+2 -4
View File
@@ -1,9 +1,7 @@
async function mSleep(ms) {
export async function mSleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function sleep(s) {
export async function sleep(s) {
return mSleep(s * 1000)
}
module.exports = { mSleep, sleep }
-28
View File
@@ -1,28 +0,0 @@
//@ts-check
//@ts-expect-error
const csocket = require('./socket.node')
/**
* @param { number } domain
* @param { number } type
* @param { number } protocol
* @return { number }
*/
function socket(domain, type, protocol) {
return csocket.socket(domain, type, protocol)
}
const socketTypes = {
SOCK_DGRAM : 1, /* Connectionless, unreliable datagrams of fixed maximum length. */
SOCK_STREAM : 2, /* Sequenced, reliable, connection-based byte streams. */
SOCK_RAW : 3, /* Raw protocol interface. */
SOCK_RDM : 4, /* Reliably-delivered messages. */
SOCK_SEQPACKET : 5, /* Sequenced, reliable, connection-based, datagrams of fixed maximum length. */
SOCK_DCCP : 6, /* Datagram Congestion Control Protocol. */
SOCK_PACKET : 10, /* Linux specific way of getting packets at the dev level. For writing rarp and other similar things on the user level. */
SOCK_CLOEXEC : 0o2000000, /* Atomically set close-on-exec flag for the new descriptor(s). */
SOCK_NONBLOCK : 0o0000200 /* Atomically mark descriptor(s) as non-blocking. */
}
module.exports = { socketTypes, socket }
+3 -5
View File
@@ -1,9 +1,7 @@
//@ts-check
const fs = require('fs')
import * as fs from 'fs'
const systems = fs.readFileSync('/proc/filesystems', { encoding: 'utf-8' }).split('\n')
const filesystems = systems.map(s => ({ hasdev: !s.includes('nodev'), name: s.includes('nodev') ? s.split('nodev')[1].trim() : s.trim() }))
module.exports = filesystems
Object.freeze(module.exports)
export const filesystems = systems.map(s => ({ hasdev: !s.includes('nodev'), name: s.includes('nodev') ? s.split('nodev')[1].trim() : s.trim() }))
Object.freeze(filesystems)