logo

live-bootstrap

Mirror of <https://github.com/fosslinux/live-bootstrap>
commit: 87e9d7db9d22b400d1c05247254ac39ee2577e80
parent 26552a928f3bc10b8bfeb2c7ac1daf801ea15b38
Author: Andrius Štikonas <andrius@stikonas.eu>
Date:   Sun, 21 May 2023 01:26:04 +0100

Merge pull request #295 from rick-masters/kernel-bootstrap-phase2-v1

Kernel bootstrap phase2 v1

Diffstat:

Akernel-bootstrap/builder-hex0-x86-stage2.hex02442++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dkernel-bootstrap/builder-hex0-x86.hex02439-------------------------------------------------------------------------------
Mparts.rst39+++++++++++++++++++++++++++------------
Mrootfs.py3++-
Msysa.py21+++++++++++++++------
Msysa/SHA256SUMS.pkgs3++-
Msysa/e2fsprogs-1.45.7/e2fsprogs-1.45.7.sh1+
Dsysa/fiwix-1.4.0-lb1/fiwix-1.4.0-lb1.checksums1-
Dsysa/fiwix-1.4.0-lb1/fiwix-1.4.0-lb1.kaem556-------------------------------------------------------------------------------
Dsysa/fiwix-1.4.0-lb1/sources1-
Asysa/fiwix-1.4.0-lb2/fiwix-1.4.0-lb2.checksums1+
Asysa/fiwix-1.4.0-lb2/fiwix-1.4.0-lb2.kaem560+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asysa/fiwix-1.4.0-lb2/sources1+
Msysa/kexec-fiwix/kexec-fiwix.checksums2+-
Msysa/kexec-fiwix/src/kexec-fiwix.c4++--
Asysa/kexec-linux-1.0.0/files/kexec-linux.c82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asysa/kexec-linux-1.0.0/kexec-linux-1.0.0.sh15+++++++++++++++
Asysa/kexec-linux-1.0.0/mk/main.mk4++++
Msysa/lwext4-1.0.0-lb1/files/early-artifacts-needed-after-fiwix.txt1+
Msysa/lwext4-1.0.0-lb1/files/make_fiwix_initrd.c40++++++++++++++++++++++++++--------------
Msysa/lwext4-1.0.0-lb1/lwext4-1.0.0-lb1.checksums2+-
Msysa/run.kaem2+-
Msysa/run2.sh33+++++++++++++++++----------------
Msysb/run.sh14+++++++-------
24 files changed, 3208 insertions(+), 3059 deletions(-)

diff --git a/kernel-bootstrap/builder-hex0-x86-stage2.hex0 b/kernel-bootstrap/builder-hex0-x86-stage2.hex0 @@ -0,0 +1,2442 @@ +# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> +# SPDX-License-Identifier: MIT +# +# Builder-Hex0 is a small bootable machine image which has +# the ability to compile hex0 code. It is also written in hex0 +# and so it can build itself if provided with its own source code. +# +# hex0 is a "language" for binary encoding in hexadecimal +# with support for comments. + +# 16 bit Functions +# ---------------- +# stage2_entry +# console_putc_16 +# console_put_hex_16 +# +# get_drive_geometry +# next_sector +# read_sectors_16 +# write_sectors_16 +# +# [GDT data] +# stage2_main + +# 32 bit Functions +# ---------------- +# setup_interrupt_handlers +# stub_interrupt_handler +# enter_16bit_real +# resume_32bit_mode +# +# console_putc +# console_put_hex +# console_puts +# read_sectors +# write_sectors +# +# syscall_interrupt_handler +# handle_syscall_open +# handle_syscall_close +# absolute_path +# find_file +# fd_to_file_index +# handle_syscall_read +# handle_syscall_brk +# handle_syscall_write +# handle_syscall_fork +# handle_syscall_execve +# handle_syscall_chdir +# handle_syscall_exit +# handle_syscall_waitpid +# handle_syscall_lseek +# handle_syscall_access +# handle_syscall_mkdir +# handle_syscall_getcwd +# +# strcmp +# +# read +# write +# src +# hex0 +# internalshell + + +#------------------------------------------------------------ +# Memory: +# 54000000 - BFFFFFFF files (~1812MB) +# 30000000 - 53FFFFFF saved processes (~604MB) +# 08048000 - 2FFFFFFF current running process (~670MB) +# 01080000 - 08000000 32 bit stack (117MB) +# 01000010 - 0107FFFF file descriptors (16 bytes each * 32K) +# { unused, address, length, unused } +# 01000000 - 0100000F stdin disk locator +# { cylinder/sector (2 bytes), head (1 byte), unused byte, +# offset (2 bytes), unused } +# 201800 - FFFFFF file names 6..14335 +# 201400 - 2017FF file name 5 +# 201000 - 2013FF file name 4 +# 100000 - 200FF0 unused +# 9FC00 - FFFFF BIOS +# 40200 - 9FBFF scratch buffer +# 40000 - 401FF stdin device buffer +# 20000 - 3FFFF process descriptors ( 16 * 4096 bytes each) +# offset len description +# 0x000 0x004 process address +# 0x004 0x004 brk pointer +# 0x008 0x004 saved stack pointer (first process only) +# 0x00C 0x004 saved stack pointer +# 0x010 0x004 forked? +# 0x014 0x004 saved brk pointer +# 0x018 0x004 child exit code +# 0x01C 0x004 address of saved process memory +# 0x020 0x004 length of process memory +# 0x024 0x004 address of saved process stack +# 0x028 0x004 length of saved process stack +# 0x02C 0x01C unused +# 0x100 0x100 current directory +# 0x200 x0E00 file descriptors 448 * 8 bytes each +# { global_file_index, current_offset } +# 10800 - 1FFFF unused +# 10000 - 107FF interrupt table +# A000 - A1FF sector read buffer - 16bit +# 7C00 - 8600 code +# 7B00 - 7BFF Saved 32 bit registers while in 16 bit mode +# < 7B00 real mode stack +#------------------------------------------------------------ + + +#------------------------------------------------------------ +#[7E00] +#:stage2_entry +# inputs: +# dl: boot drive +# +# We cannot be sure the registers are initialized to zero so we +# do that first. We far jump to stage2_main in order to set CS. +31 C0 # xor ax, ax +8E D8 # mov ds, ax +8E C0 # mov es, ax +8E D0 # mov ss, ax +BC 00 7B # mov sp, 0x7B00 +FC # cld ; clear direction flag + +EA 26 7F 00 00 # jmp stage2_main + + +#------------------------ +#[7E11] +#:console_putc_16 +# input: +# al: char to print +# +# Note: with QEMU+Seabios this does not flush the last character or +# CRLF of a line until the first character is output on the next line +# and that character cannot be another CRLF. +53 # push bx +50 # push ax + +# Prepare to use BIOS tty output interrupt. +# Specify text page 00, 0 black background, 7 light grey text +BB 00 07 # mov bx, 0x0007 +# Specify the `write character` BIOS routine +B4 0E # mov ah, 0x0E + +3C 0A # cmp al, 0x0A +75 06 # jne regular + +# convert LF to CR LF for BIOS output +B0 0D # mov al, 0x0D +CD 10 # int 0x10 +B0 0A # mov al, 0x0A + +#:regular +CD 10 # int 0x10 + +58 # pop ax +5B # pop bx +CB # retf + + +#------------------------ +#[7E27] +#:console_put_hex_16 +# input: +# al: byte to print as hex +# +50 # push ax + +24 F0 # and al, 0xF0 +C0 E8 04 # shr al, 4 +3C 09 # cmp al, 9 +7F 04 # jg alpha1 + +# numeral +04 30 # add al, 0x30 +EB 02 # jmp print1 + +#:alpha1 +04 37 # add al, 0x37 + +#:print1 +9A 11 7E 00 00 # call console_putc_16 + +58 # pop ax ; restore original al +50 # push ax ; + +24 0F # and al, 0x0F +3C 09 # cmp al, 9 +7F 04 # jg alpha2 + +# numeral +04 30 # add al, 0x30 +EB 02 # jmp print2 + +#:alpha2 +04 37 # add al, 0x37 + +#:print2 +9A 11 7E 00 00 # call console_putc_16 + +58 # pop ax +CB # retf + + + +#------------- +#[7E51] +#:boot_drive +80 + +#------------- +#[7E52] +#:max_head +0F + +#------------- +#[7E53] +#:max_sector +3F + + +#------------------------ +#[7E54] +#:get_drive_geometry +# input: +# dl: drive +# +06 # push es +57 # push di + +# https://en.wikipedia.org/wiki/INT_13H#INT_13h_AH=08h:_Read_Drive_Parameters +31 FF # xor di, di +8E C7 # mov es, di +B4 08 # mov ah, 8 ; get drive parameters +CD 13 # int 0x13 + +88 36 52 7E # mov [max_head], dh ; max_head +80 E1 3F # and cl, 0x3f +88 0E 53 7E # mov [max_sector], cl ; num_sectors + +5F # pop di +07 # pop es +CB # retf + + +#------------------------ +#[7E6C] +#:next_sector +# inputs: +# cx: cylinder/sector +# dh: head +# +50 # PUSH_AX + +88 C8 # mov al, cl ; get sector number +24 3F # and al, 0x3f +3A 06 53 7E # cmp al, [max_sector]; if sector_num == max_sector +74 04 # je next_head ; goto next_head +FE C1 # inc cl ; else sector_num++; +EB 28 # jmp next_sector_finish + +#:next_head +3A 36 52 7E # cmp dh, [max_head] ; if head_num == max_head +74 09 # je next_cylinder ; goto next_cyclinder +FE C6 # inc dh ; else head_num++ +80 E1 C0 # and cl, 0xc0 ; sector_num = 1 +FE C1 # inc cl ; +EB 19 # jmp next_sector_finish + +#:next_cylinder +80 FD FF # cmp ch, 0xff ; if cylinder_low == 255 +74 0B # je next_cyl_high + +#:next_cyl_low +30 F6 # xor dh, dh ; head_num = 0 +80 E1 C0 # and cl, 0xc0 ; sector_num = 0 +81 C1 01 01 # add cx, 0x0101 ; cylinder_low++, sector_num++ +EB 09 # jmp next_sector_finish + +#:next_cyl_high +30 F6 # xor dh, dh ; head_num = 0 +81 E1 C0 00 # and cx, 0x00C0 ; cylinder_low = 0, sector_num = 0 +80 C1 41 # add cl, 0x41 ; cylinder_high++, sector_num++ + +#:next_sector_finish +58 # pop ax +CB # retf + + +#------------------------ +#[7EA5] +#:read_sectors_16 +# inputs: +# di: dest_addr +# cx: cylinder/sector +# dh: head +# ax: num_sectors +# +# outputs: +# di: next byte to write to +# cx,dh: next disk sector to read from +# +50 # push ax +53 # push bx +56 # push si + +89 C6 # mov si, ax ; si=num_sectors +89 FB # mov bx, di ; int 13 writes to bx + +#:read_one_loop +8A 16 51 7E # mov dl, [boot_drive] +B4 02 # mov ah, 2 ; rw mode = 02 (read) +B0 01 # mov al, 1 ; num_sectors +CD 13 # int 0x13 +72 F4 # jnc read_one_loop +3C 01 # cmp al, 1 +75 F0 # jnz read_one_loop + +# advance and maybe continue +9A 6C 7E 00 00 # call next_sector + +# we read one sector, advance +81 C3 00 02 # add bx, 0x200 + +4E # dec si ; num_sectors-- +75 E4 # jnz read_one_loop + +89 DF # mov di, bx + +5E # pop si +5B # pop bx +58 # pop ax +CB # retf + + +#------------------------ +#[7ECE] +#:write_sectors_16 +# inputs: +# si: source_addr +# cx: cylinder/sector +# dh: head +# ax: num_sectors +# +# outputs: +# si: next byte to read from +# cx,dh: next disk sector to read from +# +50 # push ax +53 # push bx +57 # push di + +89 C7 # mov di, ax ; di=num_sectors +89 F3 # mov bx, si ; int 13 reads from [bx] + +#:write_one_loop +8A 16 51 7E # mov dl, [boot_drive] +B4 03 # mov ah, 3 ; rw mode = 03 (write) +B0 01 # mov al, 1 ; num_sectors +CD 13 # int 0x13 +72 F4 # jnc write_one_loop +3C 01 # cmp al, 1 +75 F0 # jnz write_one_loop + +# advance and maybe continue +9A 6C 7E 00 00 # call next_sector + +# we write one sector, advance +81 C3 00 02 # add bx, 0x200 + +4F # dec di ; num_sectors-- +75 E4 # jnz write_one_loop + +89 DE # mov si, bx + +5F # pop di +5B # pop bx +58 # pop ax +CB # retf + + +#alignment only +00 + +#--------------------------------------------- +# The Global Descriptor Table for 32 bit mode. +#--------------------------------------------- +#[7EF8] +#:GDT_start +00 00 00 00 00 00 00 00 + +#:GDT_code32 +FF FF # limit 0:15 +00 00 # base 0:15 +00 # base 16:23 +9A # access byte 10011010b + # present=1 privilege=00 type=1 + # code=1 conforming=0 readable=1 accessed=0 +CF # 11001111b + # granularity=1 32-bit-default=1 64-bit seg=0 AVL=0 +00 # + +#:GDT_data32 +FF FF # limit 0:15 +00 00 # base 0:15 +00 # base 16:23 +92 # access byte 10010010b + # present=1 privilege=00 type=1 + # code=0 conforming=0 readable=1 accessed=0 +CF # flags, limit 16:19 11001111b + # granularity=1 32-bit-default=1 64-bit seg=0 AVL=0 +00 # base 24:31 + +#:GDT_code16 +FF FF # limit 0:15 +00 00 # base 0:15 +00 # base 16:23 +9A # access byte 10011010b + # present=1 privilege=00 type=1 + # code=1 conforming=0 readable=1 accessed=0 +8F # 10001111b + # granularity=1 32-bit-default=0 64-bit seg=0 AVL=0 +00 # + +#:GDT_data16 +FF FF # limit 0:15 +00 00 # base 0:15 +00 # base 16:23 +92 # access byte 10010010b + # present=1 privilege=00 type=1 + # code=0 conforming=0 readable=1 accessed=0 +8F # flags, limit 16:19 10001111b + # granularity=1 32-bit-default=0 64-bit seg=0 AVL=0 +00 # base 24:31 + +#------ +#[7F20] +#:GDT_locator +27 00 # length +F8 7E 00 00 # GDT_start + + +#------------------------ +#[7F26] +#:stage2_main +# inputs: +# dl: boot_drive +# +# Load the kernel and jump to it +88 16 51 7E # mov [boot_drive], dl +9A 54 7E 00 00 # call get_drive_geometry() +BF 00 80 # mov di, 0x8000 ; place remaining code after MBR in memory +B8 07 00 # mov ax, 0x0007 ; num_sectors = 7 +B9 02 00 # mov cx, 0x0002 ; cylinder = 0, sector_num = 0x02 +B6 00 # mov dh, 0 ; head = 0 + +# XXX disabled - stage1 compiles code +90 90 90 90 90 +#9A A5 7E 00 00 # call read_sectors_16 + +# start 32bit mode +B8 01 24 # mov ax,2401h # enable A20 line +CD 15 # int 15h + +FA # cli +0F 01 16 20 7F # lgdt GDT_locator +0F 20 C0 # mov eax, cr0 +66 83 C8 01 # or eax, 0x01 +0F 22 C0 # mov cr0, eax +EA 59 7F 08 00 # jmp setup_32bit ; sets CS + +#------ +#[7F59] +#:setup_32bit +66 B8 10 00 # mov ax, 0x0010 ; data descriptor +8E D8 # mov ds, ax +8E D0 # mov ss, ax +8E C0 # mov es, ax +8E E0 # mov fs, ax +8E E8 # mov gs, ax +BD 00 00 00 08 # mov ebp, 0x08000000 +89 EC # mov esp, ebp + +9A 7C 7F 00 00 08 00 # call setup_interrupt_handlers +EA A1 8A 00 00 08 00 # jmp internalshell + + +#---------------------------------------- +#[7F7C] +#:setup_interrupt_handlers +53 # push ebx + +# handle the timer interrupt 08 +BB 40 00 01 00 # mov ebx, &interrupt_table[08] +66 C7 03 BC 7F # mov word [ebx + 0], low_address stub_interrupt_handler +66 C7 43 06 00 00 # mov word [ebx + 6], high_address +66 C7 43 02 08 00 # mov word [ebx + 2], code_segment = 0x0800 +C6 43 05 8E # mov byte [ebx + 5], flags = 8E + +# handle int 80 +BB 00 04 01 00 # mov ebx, &interrupt_table[80] +66 C7 03 D8 80 # mov word [ebx + 0], low_address syscall_interrupt_handler +66 C7 43 06 00 00 # mov word [ebx + 6], high_address +66 C7 43 02 08 00 # mov word [ebx + 2], code_segment = 0x0800 +C6 43 05 8E # mov byte [ebx + 5], flags = 8E + +# load the interrupt table +FA # cli +0F 01 1D BD 7F 00 00 # lidt IDT_locator_32 +FB # sti +5B # pop ebx +CB # retf + + +#---------------------------------------- +#[7FBC] +#:stub_interrupt_handler +CF # iret + + +#---------------------------------------- +#[7FBD] +#:IDT_locator_32 +FF 07 # length +00 00 01 00 # IDT_start + +# unused +00 00 + + +#------------------------------------------------------------ +# 32 -> 16 -> 32 bit switching functions +#------------------------------------------------------------ +# When switching between real mode and +# protected, registers are stored here: +# +# 7B14 edx +# 7B10 +# 7B0C +# 7B08 eax +# 7B04 esp +# +# 7B00 <- top of real mode stack + +#---------------------------------------- +#[7FC5] +#:enter_16bit_real +FA # cli +A3 08 7B 00 00 # mov [0x7B08], eax ; preserve so we can use these locally +89 15 14 7B 00 00 # mov [0x7B14], edx ; +5A # pop edx ; capture return address +89 25 04 7B 00 00 # mov [0x7B04], esp ; capture stack + +# The following far jump sets CS to a 16-bit protected mode selector +# and the segment registers are also set to 16-bit protected mode selectors. +# This is done prior to entering real mode. +EA DF 7F 00 00 18 00 # jmp 0x18:setup_16bit +#------ +#[7FDF] +#:setup_16bit +B8 20 00 # mov eax, 0x0020 +8E D0 # mov ss, eax +8E D8 # mov ds, eax +8E C0 # mov es, eax +8E E8 # mov gs, eax +8E E0 # mov fs, eax +BC 00 7B # mov sp, 0x7B00 +0F 20 C0 # mov eax, cr0 +66 83 E0 FE # and eax, 0xfffffffe ; clear protected mode +0F 22 C0 # mov cr0, eax +# The following far jump sets CS to a 16-bit real mode segment +# and the segment registers are also set to real mode segments. +EA 00 80 00 00 # jmp 0000:XXXX real_mode + +# [7DFE] +# Unused +00 00 + +#------ +#[8000] +#:real_mode +B8 00 00 # mov ax, 0x0 +8E D8 # mov ds, ax +8E E0 # mov fs, ax +8E E8 # mov gs, ax +8E D0 # mov ss, ax +8E C0 # mov es, ax +BC 00 7B # mov sp, 0x7B00 +FA # cli +0F 01 1E 22 80 # lidt IDT_locator_16 +FB # sti +# Using retf to set CS comes from here: +# https://stackoverflow.com/questions/26448480/bios-interrupts-in-protected-mode +# This page recommends a far jump followed by sti: +# https://www.sudleyplace.com/pmtorm.html +6A 00 # push 0x0000 (2 bytes!) CS to return to +52 # push dx IP to return to +A1 08 7B # mov ax, [0x7B08] ; restore from above +8B 16 14 7b # mov dx, [0x7B14] +CB # retf + +#------ +#[8022] +#:IDT_locator_16 +FF 03 +00 00 00 00 + + +#---------------------------------------- +#[8028] +#:resume_32bit_mode +FA # cli +A3 08 7B # mov [0x7B08], ax ; preserve, they might be return values from 16 bit +89 16 14 7b # mov [0x7B14], dx +5A # pop dx ; carry the return IP in dx +58 # pop ax ; CS +0F 01 16 20 7F # lgdt GDT_locator +0F 20 C0 # mov eax, cr0 +66 83 C8 01 # or eax, 0x01 ; enable protected mode +0F 22 C0 # mov cr0, eax +EA 46 80 08 00 # jmp restore_32bit +#------ +#[8046] +#:restore_32bit +B8 10 00 00 00 # mov eax, 0x0010 ; data descriptor +8E D8 # mov ds, eax +8E D0 # mov ss, eax +8E C0 # mov es, eax +8E E0 # mov fs, eax +8E E8 # mov gs, eax +8B 25 04 7B 00 00 # mov esp, [0x7B04] ; restore, (saved in enter_16bit_mode) +9A 7C 7F 00 00 08 00 # call setup_interrupt_handlers +52 # push edx ; setup our return location +# These restore the 16 bit portion of these registers, which may be a +# return value from a 16 bit function, and they also restore any previous high +# bits that were stored by enter_16bit_mode so these registers need not be +# saved when going to 16 bit mode and back if you want them left alone. +A1 08 7B 00 00 # mov eax, [0x7B08] ; restore, (saved at top of this function) +8B 15 14 7B 00 00 # mov edx, [0x7B14] +C3 # ret + + +#------------------------ +#[806F] +#:console_putc +# +E8 51 FF FF FF # CALL enter_16bit_real, next=[8074] +9A 11 7E 00 00 # CALL console_putc_16(al) +9A 28 80 00 00 # CALL resume_32bit_mode +CB # RETF + + +#------------------------ +#[807F] +#:console_put_hex +E8 41 FF FF FF # CALL enter_16bit_real, next=[8084] +9A 27 7E 00 00 # CALL console_put_hex_16(al) +9A 28 80 00 00 # CALL resume_32bit_mode +CB # RETF + + +#------------------------ +#[808F] +#:console_puts +# inputs +# ds:si: string to print +#:puts_loop +50 # push eax +56 # push esi +8A 06 # mov al, [esi] +3C 00 # cmp al, 0 +74 0A # jz end_puts_loop +9A 6F 80 00 00 08 00 # call console_putc +46 # inc esi +EB F0 # jmp puts_loop +#:end_puts_loop +B0 0A # mov al, 0A +9A 6F 80 00 00 08 00 # call console_putc +5E # pop esi +58 # pop eax +CB # RETF + + +#------------------------ +#[80AD] +#:read_sectors +# inputs: +# di: dest_addr +# cx: cylinder/sector +# dh: head +# ax: num_sectors +# +E8 13 FF FF FF # CALL enter_16bit_real, next=[80B2] +9A A5 7E 00 00 # CALL read_sectors_16 +9A 28 80 00 00 # CALL resume_32bit_mode +CB # RETF + + +#------------------------ +#[80BD] +#:write_sectors +# inputs: +# si: source_addr +# cx: cylinder/sector +# dh: head +# ax: num_sectors +# +E8 03 FF FF FF # CALL enter_16bit_real, next=[80C2] +9A CE 7E 00 00 # CALL write_sectors_16 +9A 28 80 00 00 # CALL resume_32bit_mode +CB # RETF + +#------------------------ +#[80CD] +#:reboot +E8 F3 FE FF FF # call enter_16bit_real, next=[80D2] +FA # cli +EA F0 FF 00 F0 # ljmp $F000:FFF0 ; reboot + + +#------------------------ +#[80D8] +#:syscall_interrupt_handler +# +3C 01 # cmp al, 1 +75 08 # jne try next +9A B7 86 00 00 08 00 # call handle_syscall_exit +CF # iret + +3C 02 # cmp al, 2 +75 08 # jne try next +9A B0 84 00 00 08 00 # call handle_syscall_fork +CF # iret + +3C 03 # cmp al, 3 +75 08 # jne try next +9A 5B 83 00 00 08 00 # call handle_syscall_read +CF # iret + +3C 04 # cmp al, 4 +75 08 # jne try next +9A 3D 84 00 00 08 00 # call handle_syscall_write +CF # iret + +3C 05 # cmp al, 5 +75 08 # jne try next +9A 94 81 00 00 08 00 # call handle_syscall_open +CF # iret + +3C 06 # cmp al, 6 +75 08 # jne try next +9A 5E 82 00 00 08 00 # call handle_syscall_close +CF # iret + +3C 07 # cmp eax, 7 +75 08 # jne try next +9A 0B 87 00 00 08 00 # call handle_syscall_waitpid +CF # iret + +3C 0B # cmp eax, B +75 08 # jne try next +9A 1E 85 00 00 08 00 # call handle_syscall_execve +CF # iret + +3C 0C # cmp al, C +75 08 # jne try next +9A 60 86 00 00 08 00 # call handle_syscall_chdir +CF # iret + +3C 13 # cmp al, 0x13 +75 08 # jne try next +9A 25 87 00 00 08 00 # call handle_syscall_lseek +CF # iret + +3C 2D # cmp al, 2D +75 08 # jne try next +9A 0E 84 00 00 08 00 # call handle_syscall_brk +CF # iret + +3C 21 # cmp al, 0x21 +75 08 # jne try next +9A 6D 87 00 00 08 00 # call handle_syscall_access +CF # iret + +3C 27 # cmp al, 0x27 +75 08 # jne syscall_ok +9A 83 87 00 00 08 00 # call handle_syscall_mkdir +CF # iret + +# wait4 +3C 72 # cmp eax, 0x72 +75 05 # jne try next +31 C0 # xor eax, eax +89 01 # mov [ecx], eax +CF # iret + +3C B7 # cmp al, 0xB7 +75 08 # jne syscall_ok +9A 99 87 00 00 08 00 # call handle_syscall_getcwd +CF # iret + +#:syscall_ok +# return success for all unimplemented syscalls +31 C0 # xor eax, eax +CF # iret + + +#------ +#[818C] +#:next_filenum +04 00 00 00 + +#------ +#[8190] +#:next_file_address +00 00 00 54 + +#---------------------------------------- +#[8194] +#:handle_syscall_open +# inputs: +# ebx: filename +# ecx: flags +# +53 # push ebx +51 # push ecx +56 # push esi +57 # push edi + +9A 76 82 00 00 08 00 # call absolute_path + +F7 C1 40 00 00 00 # test ecx, 0x40 ; 0x40 is O_CREAT +74 72 # jz open_read + +# Create new file + +# Exit with error if directory does not exist + +# Go the end of filename +89 DE # mov esi, ebx +#:end_loop +AC # lodsb +3C 00 # cmp al, 0 +75 FB # jne end_loop +# Look in reverse for last slash +4E # dec esi +FD # std ; go backwards +#:find_slash_loop +AC # lodsb +3C 2F # cmp al, '/' +75 FB # jne find_slash_loop +# If first slash at start, its root, so it exists +FC # cld +46 # inc esi +39 DE # cmp esi, ebx +74 1C # je after_dir_lookup +# Zero out slash +31 C0 # xor eax, eax +89 F7 # mov edi, esi +AA # stosb +# Lookup directory +9A 13 83 00 00 08 00 # call find_file ; eax=find_file(ebx) +# Restore first char +C6 47 FF 2F # mov byte [edi - 1], 0x2f +83 F8 FF # cmp eax, -1 +75 07 # jne after_dir_lookup +EA 59 82 00 00 08 00 # jmp syscall_open_finish_fail + +#:after_dir_lookup + +# copy filename to new slot +89 DE # mov esi, ebx +BF 00 00 20 00 # mov edi, 0x0200000 +A1 8C 81 00 00 # mov eax, [&next_filenum] +C1 E0 0A # shl eax, 0a +01 C7 # add edi, eax +B9 00 04 00 00 # mov ecx, 0x0000400 +F3 A4 # rep movsb + +# set address of file +BF 00 00 00 01 # mov edi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] +A1 8C 81 00 00 # mov eax, [&next_filenum] +C1 E0 04 # shl eax, 04 +01 C7 # add edi, eax ; pfile_descriptor += sizeof(file_descriptor) * next_filenum +8B 0D 90 81 00 00 # mov ecx, [next_file_address] + +89 4F 04 # mov [edi+4], ecx ; pfile_descriptor->file_addr = ecx + +31 C0 # xor eax, eax +89 47 08 # mov [edi+8], eax ; pfile_descriptor->length = 0 + +A1 8C 81 00 00 # mov eax, [next_filenum] ; return next_filenum +FF 05 8C 81 00 00 # inc [next_filenum] +EB 18 # jmp syscall_open_finish + +#open_read +9A 13 83 00 00 08 00 # call find_file +83 F8 FF # cmp eax, -1 +74 34 # je syscall_open_finish_fail + +89 C1 # mov ecx, eax +# set read offset to start of file +BE 00 00 00 01 # mov esi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] +C1 E1 04 # shl ecx, 04 +01 CE # add esi, ecx ; pfile_descriptor += sizeof(file_descriptor) * filenum + +#:syscall_open_finish +8B 35 1A 85 00 00 # mov esi, [&next_process_num] +4E # dec esi = current process +C1 E6 0C # shl esi, 0x0C +81 C6 20 02 02 00 # add esi, 0x0020220 ; pproc_descriptor = &pproc_descriptor[current_process_num].open_files[4] + +6A 04 # push 0x04 ; start at fd=4 +59 # pop ecx +#:find_slot_loop +8B 1E # mov ebx, [esi] ; get file number of fd slot +85 DB # test ebx, ebx ; is this fd slot available? +74 06 # jz got_slot +41 # inc ecx ; no, go to next slot +83 C6 08 # add esi, 0x08 +EB F4 # jmp find_slot_loop +#:got_slot +89 06 # mov [esi], eax ; store file number in slot +89 C8 # mov eax, ecx ; return fd + +31 C9 # xor ecx, ecx ; set current file offset to zero +89 4E 04 # mov [esi+0x4], ecx + +#-------- +#[8259] +#:syscall_open_finish_fail + +5F # pop edi +5E # pop esi +59 # pop ecx +5B # pop ebx +CB # ret + + +#---------------------------------------- +#[825E] +#:handle_syscall_close +# inputs: +# ebx: fd + +57 # push edi +8B 3D 1A 85 00 00 # mov edi, [&next_process_num] +4F # dec edi = current process +C1 E7 0C # shl edi, 0x0C +81 C7 00 02 02 00 # add edi, 0x00020200 ; edi = all_procs[current_process_num].open_files +31 C0 # xor eax, eax +89 04 DF # mov [edi+ebx*8], eax ; open_files[fd].global_index = 0 +5F # pop edi +CB # ret + + +#---------------------------------------- +#[8276] +#:absolute_path +# inputs: +# ebx: path +# outputs: +# ebx: absolute path +# +50 # push eax +52 # push edx +56 # push esi +57 # push edi + +BF 00 02 04 00 # mov edi, 0x00040200 ; scratch buffer +57 # push edi + +# if absolute path, skip prefixing current directory +80 3B 2F # cmp [ebx], '/' +74 18 # je strcpy_path_arg + +# get cwd +8B 35 1A 85 00 00 # mov esi, [&next_process_num] +4E # dec esi = current process +C1 E6 0C # shl esi, 0x0C +81 C6 00 01 02 00 # add esi, 0x0020100 ; pproc_descriptor = &pproc_descriptor[current_process_num].current_dir + +#:strcpy_cwd_loop +AC # lodsb +84 C0 # test al, al +74 03 # jz strcpy_path_arg +AA # stosb +EB F8 # jmp strcpy_cwd_loop + +#:strcpy_path_arg +89 DE # mov esi, ebx +# skip leading ./ +66 81 3E 2E 2F # cmp word [esi], 0x2F2E +75 02 # jne strcpy_path +46 # inc esi +46 # inc esi + +#:strcpy_path +31 DB # xor ebx, ebx ; init last_char +#:strcpy_path_loop +AC # lodsb +3C 2F # cmp al, '/' +75 05 # jne ok_path_char +80 FB 2F # cmp bl, '/' +74 01 # je skip_extra_slash +#:ok_path_char +AA # stosb +#:skip_extra_slash +84 C0 # test al, al +74 04 # jz maybe_strip_ending_slash +88 C3 # mov bl, al ; save last_char +EB ED # jmp strcpy_path_loop + +#:maybe_strip_ending_slash +80 FB 2F # cmp bl, '/' +75 05 # jne handle_dots +31 C0 # xor eax, eax +4F # dec edi +4F # dec edi +AA # stosb + +# handle /. and /.. +#:handle_dots +5A # pop edx ; record first parent +52 # push edx + +#:handle_dots_loop +5E # pop esi ; get start location +56 # push esi ; save start location + +## find_slash +AC # lodsb +3C 00 # cmp al, 0 +74 33 # je absolute_path_finish +3C 2F # cmp al, '/' +75 F7 # jne find_slash + +#:found_slash +AC # lodsb +# check for /. or /.. +3C 00 # cmp al, 0 +74 2A # je absolute_path_finish +3C 2E # cmp al, '.' +74 06 # je dot_or_dotdot +89 F2 # mov edx, esi ; record start of parent +4A # dec edx ; go back to slash +4A # dec edx +EB E8 # jmp find_slash +#:dot_or_dotdot +AC # lodsb +3C 2E # cmp al, '.' +75 0A # jne remove_slashdot + +#:remove_parent +89 D7 # mov edi, edx +AC # lodsb +AA # stosb +3C 00 # cmp al, 0 +75 FA # jne copy +EB D7 # jmp handle_dots_loop + +#:remove_slashdot +3C 00 # cmp al, 0 +75 01 # jne not_ending_slashdot +4E # dec esi ; go back to null +#:not_ending_slashdot +89 F7 # mov edi, esi +4F # dec edi +4F # dec edi +#:copy_over_slashdot +AC # lodsb +AA # stosb +3C 00 # cmp al, 0 +75 FA # jne copy_over_slashdot +EB C6 # jmp handle_dots_loop + +#:absolute_path_finish +5B # pop ebx + +# restore / if necessary +80 3B 00 # cmp byte [ebx], 0 +75 05 # jne abs_path_done +66 C7 03 2F 00 # mov word [ebx], 0x002F + +#:abs_path_done +5F # pop edi +5E # pop esi +5A # pop edx +58 # pop eax +CB + + +#---------------------------------------- +#[8313] +#:find_file +# inputs: +# ebx: file_name +# outputs: +# eax: filenum +# +51 # push ecx +52 # push edx +56 # push esi +57 # push edi + +A1 8C 81 00 00 # mov eax, [next_filenum] +48 # dec eax +89 DE # mov esi, ebx + +#:checkfile +83 F8 03 # cmp eax, 3 +74 17 # je not_found +89 C7 # mov edi, eax +C1 E7 0A # shl edi, 0x0a +81 C7 00 00 20 00 # add edi, 0x0200000 +9A C6 87 00 00 08 00 # call strcmp +74 08 # je find_file_finish +48 # dec eax +EB E4 # jmp checkfile + +#:not_found +B8 FF FF FF FF # mov eax, 0xffffffff + +#:find_file_finish +5F # pop edi +5E # pop esi +5A # pop edx +59 # pop ecx +CB # ret + + +#------------------------------------------------------------ +#[8345] +#:fd_to_file_index +# inputs: +# ebx: file descriptor number +# outputs: +# ebx: global file index +57 # push edi +8B 3D 1A 85 00 00 # mov edi, [&next_process_num] +4F # dec edi = current process +C1 E7 0C # shl edi, 0x0C +81 C7 00 02 02 00 # add edi, 0x00020200 ; edi = all_procs[current_process_num].open_files +8B 1C DF # mov ebx, [edi+ebx*8] +5F # pop edi +CB # ret + + +#------------------------------------------------------------ +#[835B] +#:handle_syscall_read +# inputs: +# ecx: *return_char +# ebx: file +# edx: length +# +53 # push ebx +51 # push ecx +52 # push edx +56 # push esi +57 # push edi + +51 # push ecx ; we need this later to return char +83 FB 00 # cmp ebx, 0 +75 5F # jne read_memfile + +# stdin disk position is stored in fd 0 +# get current position +BB 00 00 00 01 # mov ebx, 0x01000000 +66 8B 0B # mov cx, [ebx] +8A 73 02 # mov dh, [ebx+2] +31 C0 # xor eax, eax +66 8B 43 04 # mov ax, [ebx+4] + +#end of sector? +66 3D FF 01 # cmp ax, 0x01ff +74 04 # je read_next_sector + +#:nextchar +66 40 # inc ax +EB 2A # jmp getchar + +#:read_next_sector +BF 00 A0 00 00 # mov edi, 0x000A000 +B8 01 00 00 00 # mov eax, 0x0001 ; num_sectors = 1 +9A AD 80 00 00 08 00 # call read_sectors +# save new location and offset +66 89 0b # mov [ebx], cx +88 73 02 # mov [ebx+2], dh +31 C0 # xor eax, eax + +# move block to device buffer +BE 00 A0 00 00 # mov esi, 0x000A000 +BF 00 00 04 00 # mov edi, 0x0040000 +B9 00 02 00 00 # mov ecx, 0x0000200 +F3 A4 # rep movsb + +#:getchar +66 A3 04 00 00 01 # mov [0x01000004], ax +59 # pop ecx +BB 00 00 04 00 # mov ebx, 0x40000 ; device buffer +89 C6 # mov esi, eax ; offset +8A 04 33 # mov al, [ebx+esi+0] +88 01 # mov [ecx], al +B8 01 00 00 00 # mov eax, 1 +EB 43 # jmp syscall_read_finish + +#:read_memfile +89 D8 # mov eax, ebx ; eax = fd +9A 45 83 00 00 08 00 # call fd_to_file_index ; ebx = global file index +# get pointer to global file +BE 00 00 00 01 # mov esi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] +C1 E3 04 # shl ebx, 04 +01 DE # add esi, ebx ; pfile_descriptor += sizeof(file_descriptor) * filenum + +# prepare to read +5F # pop edi ; edi = p_dst +8B 5E 04 # mov ebx, [esi+4] ; ebx = pfile_descriptor->file_address +89 D9 # mov ecx, ebx ; +03 4E 08 # add ecx, [esi+0x08] ; ecx = file_address + length +49 # dec ecx ; ecx = last address to read + +8B 35 1A 85 00 00 # mov esi, [&next_process_num] +4E # dec esi = current process +C1 E6 0C # shl esi, 0x0C +81 C6 04 02 02 00 # add esi, 0x0020204 +C1 E0 03 # shl eax, 3 +01 C6 # add esi, eax ; esi = &all_procs[current_proc_num].files[eax].current_offset + +03 1E # add ebx, [esi] ; ebx = file_addr + current_offset +87 F3 # xchg esi, ebx ; esi = p_src, ebx = &pproc_descriptor->offset +31 C0 # xor eax, eax ; bytes_read = 0 + +#:syscall_read_loop +39 CE # cmp esi, ecx ; past the end? +77 07 # ja syscall_read_finish + +A4 # movsb +40 # inc eax ; bytes_read++ +FF 03 # inc long [ebx] ; (*pcurrent_offset)++ +4A # dec edx ; length_to_read-- +75 F5 # jnz syscall_read_loop + +#:syscall_read_finish +5F # pop edi +5E # pop esi +5A # pop edx +59 # pop ecx +5B # pop ebx +CB # ret + + + +#------------------------------------------------------------ +#[840E] +#:handle_syscall_brk +56 # push esi + +A1 1A 85 00 00 # mov eax, [&next_process_num] +48 # dec eax = current process + +BE 00 00 02 00 # mov esi, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] +C1 E0 0C # shl eax, 0x0C +01 C6 # add esi, eax ; pproc_descriptor += sizeof(proc_descriptor) * procnum + +85 DB # test ebx, ebx ; if ebx == 0, just return the current brk +74 15 # jz get_brk + +# set +# initialize memory to zero +57 # push edi +8B 7E 04 # mov edi, [esi+4] +31 C0 # xor eax, eax +#:init_loop +39 DF # cmp edi, ebx +74 03 # je init_done +AA # stosb +EB F9 # jmp init_loop +#:init_done +5F # pop edi + +89 5E 04 # mov [esi+4], ebx +89 D8 # mov eax, ebx +5E # pop esi +CB # ret + +#:get_brk +8B 46 04 # mov eax, [esi+4] ; pproc_descriptor->brk +5E # pop esi +CB # ret + + +#------------------------------------------------------------ +#[843D] +#:handle_syscall_write +# inputs: +# ebx: file +# ecx: address of char to write +# edx: num bytes to write +51 # push ecx +52 # push edx +56 # push esi +57 # push edi + +31 C0 # xor eax, eax ; bytes_written = 0 + +83 FB 02 # cmp ebx, 02 ; std file? +7F 14 # jg write_memfile + +# stdout,stderr -> console_out +#:std_loop +85 D2 # test edx, edx +74 5B # jz syscall_write_finish +50 # push eax ; save num_written +8A 01 # mov al, [ecx] +9A 6F 80 00 00 08 00 # call console_putc +58 # pop eax ; restore num_written + +40 # inc eax ; num_written++ +41 # inc ecx ; p_dst++ +4A # dec edx ; count-- +EB EC # jmp std_loop + +#:write_memfile +89 CE # mov esi, ecx + +# use ecx as pointer to fd current offset +8B 0D 1A 85 00 00 # mov ecx, [&next_process_num] +49 # dec ecx = current process +C1 E1 0C # shl ecx, 0x0C +81 C1 04 02 02 00 # add ecx, 0x0020204 +53 # push ebx +C1 E3 03 # shl ebx, 3 +01 D9 # add ecx, ebx ; ecx = &all_procs[current_proc_num].files[ebx].current_offset +5B # pop ebx + +# lookup global file index from file descriptor +9A 45 83 00 00 08 00 # call fd_to_file_index +C1 E3 04 # shl ebx, 04 +81 C3 00 00 00 01 # add ebx, 0x01000000 ; pfile_descriptor += sizeof(file_descriptor) * filenum + +8B 7B 04 # mov edi, [ebx+4] ; edi = pfile_descriptor->file_address +03 39 # add edi, [ecx] ; edi = file_addr + current_offset +#:write_loop +85 D2 # test edx, edx +74 19 # jz syscall_write_finish +A4 # movsb +FF 01 # inc long [ecx] ; current_offset++ +# If current offset is past previous file length, then increase length +50 # push eax +8B 01 # mov eax, [ecx] +3B 43 08 # cmp eax, [ebx+0x8] +7E 09 # jle skip_lengthen +FF 43 08 # inc long [ebx+0x8] ; file_length++ +FF 05 90 81 00 00 # inc long [next_file_address] +#:skip_lengthen +58 # pop eax +40 # inc eax ; num_written++ +4A # dec edx +EB E3 # jmp write_loop + +#:syscall_write_finish +5F # pop edi +5E # pop esi +5A # pop edx +59 # pop ecx +CB # ret + + +#------ +#[84AC] +#:next_save_process_address +00 00 00 30 + +#---------------------------------------- +#[84B0] +#:handle_syscall_fork +53 # push ebx +51 # push ecx +52 # push edx +56 # push esi +57 # push edi +55 # push ebp + +A1 1A 85 00 00 # mov eax, [&next_process_num] +48 # dec eax = current process +89 C2 # mov edx, eax +BF 00 00 02 00 # mov edi, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] +C1 E0 0C # shl eax, 0x0C +01 C7 # add edi, eax ; pproc_descriptor += sizeof(proc_descriptor) * procnum + +8b 77 04 # mov esi, [edi+0x4] ; save brk pointer +89 77 14 # mov [edi+0x14], esi +89 E6 # mov esi, esp +89 77 0C # mov [edi+0xC], esi ; save stack pointer so we can return again later +FF 47 10 # inc [edi+0x10] ; fork = true + +A1 AC 84 00 00 # mov eax, [next_save_process_address] ; set save stack location +89 47 24 # mov [edi+0x24], eax + +B9 00 00 00 08 # mov ecx, 0x08000000 +29 F1 # sub ecx, esi ; compute save stack length +01 0D AC 84 00 00 # add [next_save_process_address], ecx +89 4F 28 # mov [edi+0x28], ecx +89 C7 # mov edi, eax +F3 A4 # rep movsb ; save stack + +# copy current process image to storage +89 D0 # mov eax, edx ; restore current process num +C1 E0 0C # shl eax, 0x0C +05 00 00 02 00 # add eax, 0x0020000 +8B 30 # mov esi, [eax] ; esi = pproc_descriptor->process_address + +8B 48 14 # mov ecx, [eax+0x14] ; process_length = brk - process_address +29 F1 # sub ecx, esi +89 78 1C # mov [eax+0x1C], edi ; save address of saved process memory +89 48 20 # mov [eax+0x20], ecx ; save length of process memory +01 0D AC 84 00 00 # add [next_save_process_address], ecx +F3 A4 # rep movsb ; copy current process image to storage + +31 C0 # xor eax, eax ; return as child, we'll return again as parent when child exits +5D # pop ebp +5F # pop edi +5E # pop esi +5A # pop edx +59 # pop ecx +5B # pop ebx +CB # ret + + +#------ +#[851A] +#:next_process_num +01 00 00 00 + +#---------------------------------------- +#[851E] +#:handle_syscall_execve +# inputs: +# ebx: program_name +# ecx: char **args +# edx: env +# + +A1 1A 85 00 00 # mov eax, [next_process_num] +3C 01 # cmp al, 1 +75 0A # jne not_first_process + +# first process +BD 00 10 02 00 # mov ebp, 0x00021000 ; ebp = &proc_descriptor[1] +89 65 08 # mov [ebp+0x8], esp ; save original stack pointer before pushing args +EB 23 # jmp prepare_stack + +# not_first_process +# check if current process forked or not. +# if so, create new process, if not overlay current +48 # dec eax ; eax = current_process +C1 E0 0C # shl eax, 0x0C +05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] +8B 68 10 # mov ebp, [eax+0x10] ; create_new_process = pproc->forked +85 ED # test ebp, ebp ; did current process fork? +75 0B # jnz forked + +#not_forked +8B 60 0C # mov esp, [eax+0xC] ; no fork so reset initial stack to same as current process +A1 1A 85 00 00 # mov eax, [next_process_num] +48 # dec eax +EB 08 # jump prepare_stack + +#:forked +FF 48 10 # dec [eax+0x10] ; fork handled so reset: fork = false +A1 1A 85 00 00 # mov eax, [next_process_num] + + +#:prepare_stack +# eax=process number to use +# --- env --- +8B 3D AC 84 00 00 # mov edi, [next_save_process_address] +6A 00 # push 0 ; push end of env +#:push_env_loop +# copy env arg to memory for this process +8B 32 # mov esi, [edx] +85 F6 # test esi, esi +74 0F # jz end_env_loop +57 # push edi ; push p_arg +51 # push ecx +B9 00 01 00 00 # mov ecx, 0x00000100 ; memory per arg +F3 A4 # rep movsb ; copy to new memory +59 # pop ecx +83 C2 04 # add edx, 4 +EB EB # jmp push_env_loop + + +#:end_env_loop +# --- args --- +6A 00 # push 0 ; push end of args +# count args +31 C0 # xor eax, eax ; passed_args = 0 +#:countloop +83 39 00 # cmp long [ecx], 0 +74 06 # jz push_args +40 # inc eax +83 C1 04 # add ecx, 4 +EB F5 # jmp countloop + +# push_args +89 C2 # mov edx, eax ; save eax (can't push) +#:push_args_loop +83 E9 04 # sub ecx, 4 + +# copy arg to memory for this process +8B 31 # mov esi, [ecx] + +57 # push edi ; push p_arg + +51 # push ecx +B9 00 01 00 00 # mov ecx, 0x00000100 ; memory per arg +F3 A4 # rep movsb +59 # pop ecx +48 # dec eax +75 EE # jnz push_args_loop + +# finish with argc +89 D0 # mov eax, edx ; restore eax +50 # push eax = argc + +# get current process descriptor +A1 1A 85 00 00 # mov eax, [next_process_num] +48 # dec eax +50 # push eax ; save current process num +C1 E0 0C # shl eax, 0x0C +05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &proc_descriptor[current_process_num] + +89 3D AC 84 00 00 # mov [next_save_process_address], edi + +# copy cwd from current process +05 00 01 00 00 # add eax, 0x100 +89 C6 # mov esi, eax +05 00 10 00 00 # add eax, 0x1000 +89 C7 # mov edi, eax +#loop +AC # lodsb +AA # stosb +3C 00 # cmp al, 0 +75 FA # jne loop + +58 # pop eax ; restore current process num +40 # inc eax ; eax = new process id + +# prepare process image in memory +50 # push eax ; save new process id +# get file address and length +9A 76 82 00 00 08 00 # call absolute_path +9A 13 83 00 00 08 00 # call find_file ; eax=find_file(ebx) + +# zero process memory. +# Do this after looking up file name because that may come from process memory. +50 # push eax +57 # push edi +31 C0 # xor eax, eax +BF 00 80 04 08 # mov edi, 0x08048000 +B9 00 80 FB 26 # mov ecx, 0x26FB8000 +F3 AA # rep stosb +5F # pop edi +58 # pop eax + +C1 E0 04 # shl eax, 04 ; pfile_descriptor = sizeof(file_descriptor) * filenum +05 00 00 00 01 # add eax, 0x01000000 ; pfile_descriptor += &file_descriptors[0] + +8B 40 04 # mov eax, [eax + 0x4] ; eax = pfile_descriptor->file_address +89 C3 # mov ebx, eax ; save file address +31 C9 # xor ecx, ecx +66 8B 48 2C # mov cx, [eax + 0x2C] ; get number of program headers +8B 50 18 # mov edx, [eax + 0x18] ; get process entry address +03 40 1C # add eax, [eax + 0x1C] ; calc first program header address + +#:program_header_loop +51 # push ecx ; save program header count +8B 70 04 # mov esi, [eax + 4] ; get segment file source offset +01 DE # add esi, ebx ; calc segment file address +8B 78 08 # mov edi, [eax + 8] ; get segment memory destination address +8B 48 10 # mov ecx, [eax + 0x10] ; get segment length +F3 A4 # rep movsb + +83 C0 20 # add eax, 0x20 ; go to next program header +59 # pop ecx ; restore program header count +49 # dec ecx +75 EB # jnz program_header_loop + +58 # pop eax ; restore new process num + +85 ED # test ebp, ebp ; new process (vs overlay)? +75 01 # jnz record_process_address +48 # dec eax ; overlay + +#:record_process_address +C1 E0 0C # shl eax, 0x0C +05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &pproc_descriptor[current_process_num] + +03 5B 1C # add ebx, [ebx + 0x1C] ; calc first program header address +8B 5B 08 # mov ebx, [ebx + 0x8] ; get first segment memory address +89 18 # mov [eax], ebx ; pproc_descriptor->process_address = first segment address + +# setup brk +81 C7 00 00 02 00 # add edi, 0x00020000 ; brk after last segment plus 0x20000 +89 78 04 # mov [eax + 4], edi ; pproc_descriptor->brk +31 FF # xor edi, edi +89 78 10 # mov [eax + 0x10], edi ; pproc->forked = false + +# clear open file descriptors +89 C7 # mov edi, eax +81 C7 00 02 00 00 # add edi, 0x0000200 +31 C0 # xor eax, eax +B9 00 0E 00 00 # mov ecx, 0x00000E00 +F3 AA # rep stosb + +85 ED # test ebp, ebp ; new process (vs overlay)? +74 06 # jz after_new_process + +# prepare for next process +FF 05 1A 85 00 00 # inc [next_process_num] + +#:after_new_process +# get entry point and jump +52 # push edx +31 C0 # xor eax, eax +31 DB # xor ebx, ebx +31 C9 # xor ecx, ecx +31 D2 # xor edx, edx +31 F6 # xor esi, esi +31 FF # xor edi, edi +31 ED # xor ebp, ebp +C3 # ret + + +#---------------------------------------- +#[8660] +#:handle_syscall_chdir +56 # push esi +57 # push edi + +9A 76 82 00 00 08 00 # call absolute_path +9A 13 83 00 00 08 00 # call find_file +83 F8 FF # cmp eax, -1 +74 3F # je chdir_finish + +C1 E0 04 # shl eax, 04 +05 08 00 00 01 # add eax, 0x01000008 ; eax = &file_descriptor[filenum].file_length +83 38 00 # cmp long [eax], 0 +74 07 # je chdir_ok + +# can't chdir to a file +B8 FF FF FF FF # mov eax, -1 +EB 2B # jmp chdir_finish + +#:chdir_ok +89 DE # mov esi, ebx +8B 3D 1A 85 00 00 # mov edi, [&next_process_num] +4F # dec edi = current process +C1 E7 0C # shl edi, 0x0C +81 C7 00 01 02 00 # add edi, 0x0020100 ; pproc_descriptor = &pproc_descriptor[current_process_num].current_dir + +AC # lodsb ; first slash +AA # stosb +AC # lodsb +AA # stosb +3C 00 # cmp al, 0 +75 04 # jne chdir_loop +31 C0 # xor eax, eax +74 0D # je chdir_finish ; if "/" don't add slash + +#chdir_loop +AC # lodsb +AA # stosb +3C 00 # cmp al, 0 +75 FA # jne chdir_loop +4F # dec edi + +#:add_slash +B0 2F # mov al, '/' +AA # stosb +31 C0 # xor eax, eax +AA # stosb + +#:chdir_finish +5F # pop edi +5E # pop esi +CB # retf + + +#---------------------------------------- +#[86B7] +#:handle_syscall_exit +A1 1A 85 00 00 # mov eax, [&next_process_num] +48 # dec eax = current process +A3 1A 85 00 00 # mov [&next_process_num], eax +48 # dec eax = parent process + +3C 00 # cmp al, 0 +75 07 # jne not_first +#first process +8B 25 08 10 02 00 # mov esp, [0x021008] +CB # ret + +#not_first +C1 E0 0C # shl eax, 0x0C +05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] +89 58 18 # mov [eax+0x18], ebx ; save child exit code + +8B 38 # mov edi, [eax] ; edi = pproc_descriptor->process_address +8B 70 1C # mov esi, [eax+0x1C] ; esi = pproc_descriptor->address_of_saved_process_memory +8B 48 20 # mov ecx, [eax+0x20] ; ecx = pproc_descriptor->length_of_process_memory +F3 A4 # rep movsb + +8B 70 24 # mov esi, [eax+0x24] ; deallocate memory for saved process +89 35 AC 84 00 00 # mov [next_save_process_address], esi + +8B 60 0C # mov esp, [eax+0xc] ; restore stack pointer +8B 70 14 # mov esi, [eax+0x14] ; restore brk pointer +89 70 04 # mov [eax+0x4], esi + +8B 70 24 # mov esi, [eax+0x24] ; restore stack +89 E7 # mov edi, esp +8B 48 28 # mov ecx, [eax+0x28] +F3 A4 # rep movsb + +# mimic syscall_fork's finish +B8 01 00 00 00 # mov eax, 0x1 ; process number for fork +5D # pop ebp +5F # pop edi +5E # pop esi +5A # pop edx +59 # pop ecx +5B # pop ebx +CB # ret ; go back to parent + + +#---------------------------------------- +#[870B] +#:handle_syscall_waitpid +8B 35 1A 85 00 00 # mov esi, [&next_process_num] +4E # dec esi = current process +C1 E6 0C # shl esi, 0x0C +81 C6 18 00 02 00 # add esi, 0x00020018 ; pchild_code = &pproc_descriptor[current_process_num].child_exit_code +8B 06 # mov eax, [esi] ; get exit code +C1 E0 08 # shl eax, 0x08 ; +89 01 # mov [ecx], eax ; waitval = ret << 8 +31 C0 # xor eax, eax +CB # ret + + +#---------------------------------------- +#[8725] +#:handle_syscall_lseek +# inputs: +# ebx: fd +# ecx: value +# edx: method (0=SEEK_SET, 1=SEEK_CUR, 2=SEEK_END) +# outputs: +# eax: offset +# +56 # push esi + +8B 35 1A 85 00 00 # mov esi, [&next_process_num] +4E # dec esi = current process +C1 E6 0C # shl esi, 0x0C +81 C6 04 02 02 00 # add esi, 0x0020204 ; pproc_descriptor = &pproc_descriptor[current_process_num].files[0].offset + +83 FA 01 # cmp edx, 1 +7F 13 # jg seek_end +7C 0A # jl seek_set + +#:seek_cur +8B 04 DE # mov eax, [esi+ebx*8] ; get current_offset +01 C8 # add eax, ecx ; current_pos += offset +89 04 DE # mov [esi+ebx*8], eax ; set current_pos +5E # pop esi +CB # ret + +#:seek_set +89 0C DE # mov [esi+ebx*8], ecx ; set current_pos +89 C8 # mov eax, ecx +5E # pop esi +CB # ret + +#:seek_end +56 # push esi +53 # push ebx +9A 45 83 00 00 08 00 # call fd_to_file_index +BE 00 00 00 01 # mov esi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] +C1 E3 04 # shl ebx, 04 +01 DE # add esi, ebx +8B 46 08 # mov eax, [esi+0x8] ; get current_length +01 C8 # add eax, ecx ; current_length += offset +5B # pop ebx +5E # pop esi + +89 04 DE # mov [esi+ebx*8], eax ; set current_offset + +5E # pop esi +CB # ret + + +#---------------------------------------- +#[876D] +#:handle_syscall_access +#inputs: +# ebx: path +# ecx: mode +9A 76 82 00 00 08 00 # call absolute_path +9A 13 83 00 00 08 00 # call find_file +83 F8 FF # cmp eax, -1 +74 02 # je access_error_exit +31 C0 # xor eax, eax +#:access_error_exit +CB # ret + + +#---------------------------------------- +#[8783] +#:handle_syscall_mkdir +#inputs: +# ebx: path +# ecx: mode +51 # push ecx +B9 41 00 00 00 # mov ecx, 0x41 (O_CREAT | O_WRONLY) +9A 94 81 00 00 08 00 # call handle_syscall_open +83 F8 FF # cmp eax, -1 +74 02 # je open_error_exit +31 C0 # xor eax, eax +#:open_error_exit +59 # pop ecx +CB # ret + + +#---------------------------------------- +#[8799] +#:handle_syscall_getcwd +#inputs: +# ebx: buf +# ecx: buf size +#outputs: +# eax: buf +56 # push esi +57 # push edi + +89 DF # mov edi, ebx +8B 35 1A 85 00 00 # mov esi, [&next_process_num] +4E # dec esi = current process +C1 E6 0C # shl esi, 0x0C +81 C6 00 01 02 00 # add esi, 0x0020100 ; pproc_descriptor = &pproc_descriptor[current_process_num].current_dir + +# Handle root differently because we don't strip trailing slash +66 83 3E 2F # cmp word [esi], $002f ; is cwd == "/" ? +75 04 # jne copy_cwd +66 A5 # movsw ; copy "/" to buffer +EB 0A # jmp cleanup + +# copy_cwd +AC # lodsb +AA # stosb +3C 00 # cmp al, 0 +75 FA # jne copy_cwd +83 EF 02 # sub edi, 2 ; strip trailing slash +AA # stosb + +# cleanup +89 D8 # mov eax, ebx +5F # pop edi +5E # pop esi +CB # ret + + +#------------------------------------------------------------ +#[87C6] +#:strcmp +# inputs: +# esi: string1 +# edi: string2 +# outputs: +# zero flag +# +50 # push eax +53 # push ebx +56 # push esi +57 # push edi + +#:check_byte +8A 06 # mov al, [esi] +8A 1F # mov bl, [edi] +38 D8 # cmp al, bl +75 0A # jne strcmp_finish +46 # inc esi +47 # inc edi +84 C0 # test al, al +75 F2 # jnz check_byte +84 DB # test bl, bl +75 EE # jnz check_byte + +#:strcmp_finish +5F # pop edi +5E # pop esi +5B # pop ebx +58 # pop eax +CB # ret + + +#------ +#[87E1] +#:io_char +00 +00 # free + +#---------------------------------------- +#[87E3] +#:read +53 # push ebx +51 # push ecx +52 # push edx +B8 03 00 00 00 # mov eax, 3 ; syscall=read +B9 E1 87 00 00 # mov ecx, &io_char +BA 01 00 00 00 # mov edx, 1 + +CD 80 # int 80 syscall + +3C 00 # cmp al, 0 +74 07 # je read_finish + +B4 01 # mov ah, 1 +A0 E1 87 00 00 # mov al, &io_char + +#:read_finish +5A # pop edx +59 # pop ecx +5B # pop ebx +CB # ret + + +#---------------------------------------- +#[8806] +#:write +50 # push eax +53 # push ebx +51 # push ecx +52 # push edx + +A2 E1 87 00 00 # mov &io_char, al +B8 04 00 00 00 # mov eax, 4 ; syscall=write +B9 E1 87 00 00 # mov ecx, &io_char +BA 01 00 00 00 # mov edx, 1 1 byte characters +CD 80 # int 80 syscall + +5A # pop edx +59 # pop ecx +5B # pop ebx +58 # pop eax +CB # ret + + +#------ +#[8825] +#:string_src +#s r c \0 +73 72 63 00 + +#---------------------------------------- +# src: create file from stdin +# +# Read an integer, N, in decimal from stdin. +# Read a space. +# Then, read a file name to create. +# Read a newline. +# Then, read N bytes from stdin and write to the new file. +#---------------------------------------- +#[8829] +#:src +50 # push eax +53 # push ebx +51 # push ecx +52 # push edx +56 # push esi +57 # push edi + +BE 25 88 00 00 # mov esi, string_src +9A 8F 80 00 00 08 00 # call console_puts + +9A E3 87 00 00 08 00 # call read 'r' +9A E3 87 00 00 08 00 # call read 'c' +9A E3 87 00 00 08 00 # call read ' ' + +31 C9 # xor ecx, ecx ; line count=0 +#parse_line_count_loop: +9A E3 87 00 00 08 00 # call read +3C 20 # cmp al, ' ' +74 0C # je got_count + +6B C9 0A # imul ecx, ecx, 10 ; count = count * 10 +2C 30 # sub al, 30 +0F B6 C0 # movzx eax, al +01 C1 # add ecx, eax ; count += digit + +EB E9 # jmp parse_line_count_loop + +#:got_count +# clear arguments +51 # push ecx +31 C0 # xor eax, eax +BA 00 00 D0 04 # mov edx, 0x04D00000 +B9 00 08 00 00 # mov ecx, 0x00000800 + +#:src_args_zeroloop +88 02 # mov [edx], al +42 # inc edx +49 # dec ecx +75 FA # jnz src_args_zeroloop +59 # pop ecx + +51 # push ecx +B9 00 00 D0 04 # mov ecx, 0x04D00000 +#:get_filename_loop +9A E3 87 00 00 08 00 # call read + +3C 0A # cmp al, '\n' +74 05 # je got_filename +88 01 # mov [ecx], al +41 # inc ecx +EB F0 # jmp get_file_name_loop +59 # pop ecx + +#:got_filename +BE 00 00 D0 04 # mov esi, 0x04D00000 +9A 8F 80 00 00 08 00 # call console_puts + +# open filename for write +51 # push ecx +BB 00 00 D0 04 # mov ebx, 0x04D00000 +B8 05 00 00 00 # mov eax, 5 ; syscall_open +B9 41 02 00 00 # mov ecx, 0x00000241 O_TRUNC (0x200) | O_CREAT (0x40) | O_WRONLY (0x1) +BA 80 01 00 00 # mov edx, 0x00000180 S_IRUSR (0x100) | S_IWUSR (0x80) +CD 80 # int 80 +59 # pop ecx +89 C2 # mov edx, eax + +# edx has the open file number + +#:readwrite_loop +85 C9 # test ecx, ecx +74 1C # jz src_finish +BF 00 02 04 00 # mov edi, 0x00040200 ; scratch buffer +57 # push edi ; save buffer address +31 DB # xor ebx, ebx ; ebx=0=stdin +9A E3 87 00 00 08 00 # call read +89 D3 # mov ebx, edx ; prepare to write +5E # pop esi ; restore buffer address to esi +9A 06 88 00 00 08 00 # call write +49 # dec ecx ; count-- +EB E0 # jmp read_write_loop + +#:src_finish +5F # pop edi +5E # pop esi +5A # pop edx +59 # pop ecx +5B # pop ebx +58 # pop eax +CB # ret + + + +#------ +#[88E1] +#:hex0_str +#h e x 0 \0 +68 65 78 30 00 + +#------------------------------------------------------------ +#[88E6] +#:hex0 +53 # push ebx +56 # push esi +57 # push edi + +BE E1 88 00 00 # mov esi, hex0_str +9A 8F 80 00 00 08 00 # call console_puts + +# read "ex0 ' +B1 04 # mov cl, 4 +#:ex0_loop +9A E3 87 00 00 08 00 # call read +FE C9 # dec cl +75 F5 # jnz ex0_loop + +# clear arguments +31 C0 # xor eax, eax +BA 00 00 D0 04 # mov edx, 0x04D00000 +B9 00 08 00 00 # mov ecx, 0x00000800 +#:hex0_args_zeroloop +88 02 # mov [edx], al +42 # inc edx +49 # dec ecx +75 FA # jnz hex0_args_zeroloop + +BA 00 00 D0 04 # mov edx, 0x04D00000 +#:get_file_name1_loop +9A E3 87 00 00 08 00 # call read +9A 6F 80 00 00 08 00 # call console_putc +3C 20 # cmp al, ' ' +74 05 # je got_filename1 +88 02 # mov [edx], al +42 # inc edx +EB E9 # jmp get_file_name1_loop + +#:got_filename1 +BA 00 04 D0 04 # mov edx, 0x04D00400 +#:get_file_name2_loop +9A E3 87 00 00 08 00 # call read +9A 6F 80 00 00 08 00 # call console_putc +3C 0A # cmp al, '\n' +74 05 # je got_filename2 +88 02 # mov [edx], al +42 # inc edx +EB E9 # jmp get_file_name2_loop + +# open filename1 for read +BB 00 00 D0 04 # mov ebx, 0x04D00000 +B8 05 00 00 00 # mov eax, 5 ; syscall_open +B9 00 00 00 00 # mov ecx, 0x00000000 +CD 80 # int 80 + +50 # push eax ; save read filenum + +# open filename2 for write +BB 00 04 D0 04 # mov ebx, 0x04D00400 +B8 05 00 00 00 # mov eax, 5 ; syscall_open +B9 41 02 00 00 # mov ecx, 0x00000241 O_TRUNC (0x200) | O_CREAT (0x40) | O_WRONLY (0x1) +BA 80 01 00 00 # mov edx, 0x00000180 S_IRUSR (0x100) | S_IWUSR (0x80) +CD 80 # int 80 +89 C2 # mov edx, eax + +59 # pop ecx ; restore read filenum + +# this flag is set after the first digit is seen +31 DB # xor ebx, ebx + + +#------ +#[8979] +#:hex0_read_loop +53 # push ebx +89 CB # mov ebx, ecx +9A E3 87 00 00 08 00 # call read +5B # pop ebx + +84 E4 # test ah, ah +75 04 # jnz check_command +5F # POP_DI +5E # POP_SI +5B # POP_BX +CB # RETF + +#:check_command +3C 23 # cmp al, '#' + +74 28 # jz skip_comment + +3C 3B # cmp ';' +74 24 # jz skip_comment + +3C 66 # cmp al, 'f' +7F D1 # jg hex0_read_loop + +3C 61 # cmp al, 'a' +7C 04 # jl maybe_upper + +# Handle a to f +2C 57 # sub al, 'a'-10 == 87 = 0x57 +EB 29 # jmp maybe_store + +#:maybe_upper +3C 46 # cmp al, 'F' +7F D5 # jg hex0_read_loop + +3C 41 # cmp al, 'A' +7C 04 # jl maybe_digit + +# Handle A to F +2C 37 # sub al, 'A'-10 == 55 = x37 +EB 1D # jmp maybe_store + +#:maybe_digit +3C 39 # cmp al, '9' +7F C9 # jg hex0_read_loop + +3C 30 # cmp al, '0' +7C C5 # jl hex0_read_loop + +# Handle 0 to 9 +2C 30 # sub al, '0' == x30 +EB 11 # jmp maybe_store + +#:skip_comment +53 # push ebx +89 CB # mov ebx, ecx +9A E3 87 00 00 08 00 # call read +5B # pop ebx +3C 0A # cmp al, '\n' +75 F1 # jnz skip_comment +EB B0 # jmp hex0_read_loop + +# only store on second digit +#:maybe_store +84 DB # test bl, bl +75 09 # jnz second_digit + +# If on first digit, record and keep going +#:first_digit +C0 E0 04 # shl al, 4 +88 C7 # mov bh, al +FE C3 # inc bl +EB A3 # jmp hex0_read_loop + +# If on second digit, store and clear state +#:second_digit +08 C7 # or bh, al +88 F8 # mov al, bh + +53 # push ebx +89 D3 # mov ebx, edx +9A 06 88 00 00 08 00 # call write +5B # pop ebx + +31 DB # xor bx, bx +EA 79 89 00 00 08 00 # jmp hex0_read_loop + + +#------ +#[89EE] +#:cmd_args +00 00 D0 04 +00 04 D0 04 + +#------ +#[89F6] +#:cmd_env +00 00 00 00 + +#------------------------------------------------------------ +#[89FA] +#:handle_other_command +50 # push eax +53 # push ebx +51 # push ecx +52 # push edx +56 # push esi + +# clear arguments +BA 00 00 D0 04 # mov edx, 0x04D00000 +88 02 # mov [edx], al +42 # inc edx +31 C0 # xor eax, eax +B9 FF 07 00 00 # mov ecx, 0x000007FF +#other_args_zeroloop +88 02 # mov [edx], al +42 # inc edx +49 # dec ecx +75 FA # jnz other_args_zeroloop + +BA 01 00 D0 04 # mov edx, 0x04D00001 +#:get_program_name +9A E3 87 00 00 08 00 # call read +3C 20 # cmp al, ' ' +74 05 # je got_program_name +88 02 # mov [edx], al +42 # inc edx +EB F0 # jmp get_program_name + +#got_program_name +BA 00 04 D0 04 # mov edx, 0x04D00400 +#get_argument1_loop +9A E3 87 00 00 08 00 # call read +3C 0A # cmp al, '\n' +74 05 # je got_argument1 +88 02 # mov [edx], al +42 # inc edx +EB F0 # jmp get_argument1_loop + +#:got_argument1 +BE 00 00 D0 04 # mov esi, program +9A 8F 80 00 00 08 00 # call console_puts + +BE 00 04 D0 04 # mov esi, arg1 +9A 8F 80 00 00 08 00 # call console_puts + +BB 00 00 D0 04 # mov ebx, program_name +B9 EE 89 00 00 # mov ecx, cmd_args +BA F6 89 00 00 # mov edx, cmd_env +9A 1E 85 00 00 08 00 # call handle_syscall_execve + +5E # pop esi +5A # pop edx +59 # pop ecx +5B # pop ebx +58 # pop eax +CB + + +#------ +#[8A72] +#:str_build_finished +#B u i l d f i n i s h e d . \0 +42 75 69 6C 64 20 66 69 6E 69 73 68 65 64 2E 00 + +#------ +#[8A82] +#:str_error_no_writes +#E R R O R : n o h d a w r i t e s ! \0 +45 52 52 4F 52 3A 20 6E 6F 20 68 64 61 20 77 72 69 74 65 73 21 00 + +#------ +#[8A98] +#:str_dev_hda +#/ d e v / h d a \0 +2F 64 65 76 2F 68 64 61 00 + + +#------------------------------------------------------------ +#[8AA1] +#:internalshell +# Start reading stdin from sector 22, cyl 0, head 2 (i.e. sector 148) +C7 05 00 00 00 01 16 00 02 00 # mov word [0x01000000], 0x00000008 +# start at "end of sector" to trigger an initial sector read +66 C7 05 04 00 00 01 FF 01 # mov word [0x01000004], 0x01FF +66 C7 05 00 01 02 00 2F 00 # mov [0x00020100], 0x002F ; proc[0].cwd = "/" +66 C7 05 00 11 02 00 2F 00 # mov [0x00021100], 0x002F ; proc[1].cwd = "/" + +# clear file descriptors for process 0 +BF 00 02 02 00 # mov edi, 0x00020200 +B9 00 0E 00 00 # mov ecx, 0x00000E00 +31 C0 # xor eax, eax +F3 AA # rep stosb + +# read from stdin +31 DB # xor ebx, ebx + +#:process_command +9A E3 87 00 00 08 00 # call read +3C 00 # cmp al, 0 +74 23 # je build_finished + +#:check_src_command +3C 73 # cmp al, 's' +75 09 # jne check_hex0_command + +#:handle_src_command +9A 29 88 00 00 08 00 # call src +EB E8 # jmp process_command + +#:check_hex0_command +3C 68 # cmp al, 'h' +75 09 # jne call_handle_other_command + +#:handle_hex0_command +9A E6 88 00 00 08 00 # call hex0 +EB DB # jmp process_command + +#:call_handle_other_command +9A FA 89 00 00 08 00 # call handle_other_command +EB D2 # jmp process_command + +#:build_finished +BE 72 8A 00 00 # mov esi, str_build_finished +9A 8F 80 00 00 08 00 # call console_puts + +# copy memory file /dev/hda to the boot disk +BB 98 8A 00 00 # mov ebx, str_dev_hda +9A 13 83 00 00 08 00 # call find_file +83 F8 FF # cmp eax, -1 +75 17 # jne ok_exit + +#:error_exit +BE 82 8A 00 00 # mov esi, str_error_no_write +9A 8F 80 00 00 08 00 # call console_puts + +# one space to flush last line +B0 20 # mov al, 20 +9A 6F 80 00 00 08 00 # call console_putc +EB 62 # jmp shell_reboot + +#:ok_exit +# get file address to read +C1 E0 04 # shl eax, 04 +05 00 00 00 01 # add eax, 0x01000000 +8B 70 04 # mov esi, [eax+4] ; file_address +8B 58 08 # mov ebx, [eax+8] ; bytes_to_write = file_length + +# print length +89 D8 # mov eax, ebx +B9 04 00 00 00 # mov ecx, 4 +#:shift_loop +C1 C8 18 # ror eax, 24 +9A 7F 80 00 00 08 00 # call console_put_hex +49 # dec ecx +75 F3 # jnz shift_loop +B0 0A # mov al, 0A +9A 6F 80 00 00 08 00 # call console_putc + +# set starting disk location to write +31 C9 # xor ecx, ecx +41 # inc ecx +B6 00 # mov dh, 0 + +#:sector_loop +# copy 512 bytes from file to 16 bit buffer +51 # push ecx ; save disk location +BF 00 A0 00 00 # mov edi, 0x000A000 +B9 00 02 00 00 # mov ecx, 0x200 +F3 A4 # rep movsb +59 # pop ecx + +# now write from 16 bit buffer +56 # push esi ; save our location in the file +BE 00 A0 00 00 # mov esi, 0x000A000 +B8 01 00 00 00 # mov eax, 0x0001 ; num_sectors = 1 +9A BD 80 00 00 08 00 # call write_sectors +5E # pop esi +81 EB 00 02 00 00 # sub ebx, 0x200 ; bytes_to_write -= 512 +7F D7 # jg sector_loop + +B0 20 # mov al, 20 +9A 6F 80 00 00 08 00 # call console_putc + +#:shell_reboot +EA CD 80 00 00 08 00 # jmp reboot + +# sector padding +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/kernel-bootstrap/builder-hex0-x86.hex0 b/kernel-bootstrap/builder-hex0-x86.hex0 @@ -1,2439 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> -# SPDX-License-Identifier: MIT -# -# Builder-Hex0 is a small bootable machine image which has -# the ability to compile hex0 code. It is also written in hex0 -# and so it can build itself if provided with its own source code. -# -# hex0 is a "language" for binary encoding in hexadecimal -# with support for comments. - -# 16 bit Functions -# ---------------- -# MBR_entry -# console_putc_16 -# console_put_hex_16 -# -# get_drive_geometry -# next_sector -# read_sectors_16 -# write_sectors_16 -# -# [GDT data] -# MBR_main - -# 32 bit Functions -# ---------------- -# setup_interrupt_handlers -# stub_interrupt_handler -# enter_16bit_real -# resume_32bit_mode -# -# console_putc -# console_put_hex -# console_puts -# read_sectors -# write_sectors -# -# syscall_interrupt_handler -# handle_syscall_open -# handle_syscall_close -# absolute_path -# find_file -# fd_to_file_index -# handle_syscall_read -# handle_syscall_brk -# handle_syscall_write -# handle_syscall_fork -# handle_syscall_execve -# handle_syscall_chdir -# handle_syscall_exit -# handle_syscall_waitpid -# handle_syscall_lseek -# handle_syscall_access -# handle_syscall_mkdir -# handle_syscall_getcwd -# -# strcmp -# -# read -# write -# src -# hex0 -# internalshell - - -#------------------------------------------------------------ -# Memory: -# 54000000 - BFFFFFFF files (~1812MB) -# 30000000 - 53FFFFFF saved processes (~604MB) -# 08048000 - 2FFFFFFF current running process (~670MB) -# 01080000 - 08000000 32 bit stack (117MB) -# 01000010 - 0107FFFF file descriptors (16 bytes each * 32K) -# { unused, address, length, unused } -# 01000000 - 0100000F stdin disk locator -# { cylinder/sector (2 bytes), head (1 byte), unused byte, -# offset (2 bytes), unused } -# 201800 - FFFFFF file names 6..14335 -# 201400 - 2017FF file name 5 -# 201000 - 2013FF file name 4 -# 100000 - 200FF0 unused -# 9FC00 - FFFFF BIOS -# 40200 - 9FBFF scratch buffer -# 40000 - 401FF stdin device buffer -# 20000 - 3FFFF process descriptors ( 16 * 4096 bytes each) -# offset len description -# 0x000 0x004 process address -# 0x004 0x004 brk pointer -# 0x008 0x004 saved stack pointer (first process only) -# 0x00C 0x004 saved stack pointer -# 0x010 0x004 forked? -# 0x014 0x004 saved brk pointer -# 0x018 0x004 child exit code -# 0x01C 0x004 address of saved process memory -# 0x020 0x004 length of process memory -# 0x024 0x004 address of saved process stack -# 0x028 0x004 length of saved process stack -# 0x02C 0x01C unused -# 0x100 0x100 current directory -# 0x200 x0E00 file descriptors 448 * 8 bytes each -# { global_file_index, current_offset } -# 10800 - 1FFFF unused -# 10000 - 107FF interrupt table -# A000 - A1FF sector read buffer - 16bit -# 7C00 - 8600 code -# 7B00 - 7BFF Saved 32 bit registers while in 16 bit mode -# < 7B00 real mode stack -#------------------------------------------------------------ - - -#------------------------------------------------------------ -#[7C00] -#:MBR_entry -# inputs: -# dl: boot drive -# -# We cannot be sure the registers are initialized to zero so we -# do that first. We far jump to MBR_main in order to set CS. -31 C0 # xor ax, ax -8E D8 # mov ds, ax -8E C0 # mov es, ax -8E D0 # mov ss, ax -BC 00 7B # mov sp, 0x7B00 -FC # cld ; clear direction flag - -EA 26 7D 00 00 # jmp MBR_main - - -#------------------------ -#[7C11] -#:console_putc_16 -# input: -# al: char to print -# -# Note: with QEMU+Seabios this does not flush the last character or -# CRLF of a line until the first character is output on the next line -# and that character cannot be another CRLF. -53 # push bx -50 # push ax - -# Prepare to use BIOS tty output interrupt. -# Specify text page 00, 0 black background, 7 light grey text -BB 00 07 # mov bx, 0x0007 -# Specify the `write character` BIOS routine -B4 0E # mov ah, 0x0E - -3C 0A # cmp al, 0x0A -75 06 # jne regular - -# convert LF to CR LF for BIOS output -B0 0D # mov al, 0x0D -CD 10 # int 0x10 -B0 0A # mov al, 0x0A - -#:regular -CD 10 # int 0x10 - -58 # pop ax -5B # pop bx -CB # retf - - -#------------------------ -#[7C27] -#:console_put_hex_16 -# input: -# al: byte to print as hex -# -50 # push ax - -24 F0 # and al, 0xF0 -C0 E8 04 # shr al, 4 -3C 09 # cmp al, 9 -7F 04 # jg alpha1 - -# numeral -04 30 # add al, 0x30 -EB 02 # jmp print1 - -#:alpha1 -04 37 # add al, 0x37 - -#:print1 -9A 11 7C 00 00 # call console_putc_16 - -58 # pop ax ; restore original al -50 # push ax ; - -24 0F # and al, 0x0F -3C 09 # cmp al, 9 -7F 04 # jg alpha2 - -# numeral -04 30 # add al, 0x30 -EB 02 # jmp print2 - -#:alpha2 -04 37 # add al, 0x37 - -#:print2 -9A 11 7C 00 00 # call console_putc_16 - -58 # pop ax -CB # retf - - - -#------------- -#[7C51] -#:boot_drive -80 - -#------------- -#[7C52] -#:max_head -0F - -#------------- -#[7C53] -#:max_sector -3F - - -#------------------------ -#[7C54] -#:get_drive_geometry -# input: -# dl: drive -# -06 # push es -57 # push di - -# https://en.wikipedia.org/wiki/INT_13H#INT_13h_AH=08h:_Read_Drive_Parameters -31 FF # xor di, di -8E C7 # mov es, di -B4 08 # mov ah, 8 ; get drive parameters -CD 13 # int 0x13 - -88 36 52 7C # mov [max_head], dh ; max_head -80 E1 3F # and cl, 0x3f -88 0E 53 7C # mov [max_sector], cl ; num_sectors - -5F # pop di -07 # pop es -CB # retf - - -#------------------------ -#[7C6C] -#:next_sector -# inputs: -# cx: cylinder/sector -# dh: head -# -50 # PUSH_AX - -88 C8 # mov al, cl ; get sector number -24 3F # and al, 0x3f -3A 06 53 7C # cmp al, [max_sector]; if sector_num == max_sector -74 04 # je next_head ; goto next_head -FE C1 # inc cl ; else sector_num++; -EB 28 # jmp next_sector_finish - -#:next_head -3A 36 52 7C # cmp dh, [max_head] ; if head_num == max_head -74 09 # je next_cylinder ; goto next_cyclinder -FE C6 # inc dh ; else head_num++ -80 E1 C0 # and cl, 0xc0 ; sector_num = 1 -FE C1 # inc cl ; -EB 19 # jmp next_sector_finish - -#:next_cylinder -80 FD FF # cmp ch, 0xff ; if cylinder_low == 255 -74 0B # je next_cyl_high - -#:next_cyl_low -30 F6 # xor dh, dh ; head_num = 0 -80 E1 C0 # and cl, 0xc0 ; sector_num = 0 -81 C1 01 01 # add cx, 0x0101 ; cylinder_low++, sector_num++ -EB 09 # jmp next_sector_finish - -#:next_cyl_high -30 F6 # xor dh, dh ; head_num = 0 -81 E1 C0 00 # and cx, 0x00C0 ; cylinder_low = 0, sector_num = 0 -80 C1 41 # add cl, 0x41 ; cylinder_high++, sector_num++ - -#:next_sector_finish -58 # pop ax -CB # retf - - -#------------------------ -#[7CA5] -#:read_sectors_16 -# inputs: -# di: dest_addr -# cx: cylinder/sector -# dh: head -# ax: num_sectors -# -# outputs: -# di: next byte to write to -# cx,dh: next disk sector to read from -# -50 # push ax -53 # push bx -56 # push si - -89 C6 # mov si, ax ; si=num_sectors -89 FB # mov bx, di ; int 13 writes to bx - -#:read_one_loop -8A 16 51 7C # mov dl, [boot_drive] -B4 02 # mov ah, 2 ; rw mode = 02 (read) -B0 01 # mov al, 1 ; num_sectors -CD 13 # int 0x13 -72 F4 # jnc read_one_loop -3C 01 # cmp al, 1 -75 F0 # jnz read_one_loop - -# advance and maybe continue -9A 6C 7C 00 00 # call next_sector - -# we read one sector, advance -81 C3 00 02 # add bx, 0x200 - -4E # dec si ; num_sectors-- -75 E4 # jnz read_one_loop - -89 DF # mov di, bx - -5E # pop si -5B # pop bx -58 # pop ax -CB # retf - - -#------------------------ -#[7CCE] -#:write_sectors_16 -# inputs: -# si: source_addr -# cx: cylinder/sector -# dh: head -# ax: num_sectors -# -# outputs: -# si: next byte to read from -# cx,dh: next disk sector to read from -# -50 # push ax -53 # push bx -57 # push di - -89 C7 # mov di, ax ; di=num_sectors -89 F3 # mov bx, si ; int 13 reads from [bx] - -#:write_one_loop -8A 16 51 7C # mov dl, [boot_drive] -B4 03 # mov ah, 3 ; rw mode = 03 (write) -B0 01 # mov al, 1 ; num_sectors -CD 13 # int 0x13 -72 F4 # jnc write_one_loop -3C 01 # cmp al, 1 -75 F0 # jnz write_one_loop - -# advance and maybe continue -9A 6C 7C 00 00 # call next_sector - -# we write one sector, advance -81 C3 00 02 # add bx, 0x200 - -4F # dec di ; num_sectors-- -75 E4 # jnz write_one_loop - -89 DE # mov si, bx - -5F # pop di -5B # pop bx -58 # pop ax -CB # retf - - -#alignment only -00 - -#--------------------------------------------- -# The Global Descriptor Table for 32 bit mode. -#--------------------------------------------- -#[7CF8] -#:GDT_start -00 00 00 00 00 00 00 00 - -#:GDT_code32 -FF FF # limit 0:15 -00 00 # base 0:15 -00 # base 16:23 -9A # access byte 10011010b - # present=1 privilege=00 type=1 - # code=1 conforming=0 readable=1 accessed=0 -CF # 11001111b - # granularity=1 32-bit-default=1 64-bit seg=0 AVL=0 -00 # - -#:GDT_data32 -FF FF # limit 0:15 -00 00 # base 0:15 -00 # base 16:23 -92 # access byte 10010010b - # present=1 privilege=00 type=1 - # code=0 conforming=0 readable=1 accessed=0 -CF # flags, limit 16:19 11001111b - # granularity=1 32-bit-default=1 64-bit seg=0 AVL=0 -00 # base 24:31 - -#:GDT_code16 -FF FF # limit 0:15 -00 00 # base 0:15 -00 # base 16:23 -9A # access byte 10011010b - # present=1 privilege=00 type=1 - # code=1 conforming=0 readable=1 accessed=0 -8F # 10001111b - # granularity=1 32-bit-default=0 64-bit seg=0 AVL=0 -00 # - -#:GDT_data16 -FF FF # limit 0:15 -00 00 # base 0:15 -00 # base 16:23 -92 # access byte 10010010b - # present=1 privilege=00 type=1 - # code=0 conforming=0 readable=1 accessed=0 -8F # flags, limit 16:19 10001111b - # granularity=1 32-bit-default=0 64-bit seg=0 AVL=0 -00 # base 24:31 - -#------ -#[7D20] -#:GDT_locator -27 00 # length -F8 7C 00 00 # GDT_start - - -#------------------------ -#[7D26] -#:MBR_main -# inputs: -# dl: boot_drive -# -# Load the kernel and jump to it -88 16 51 7C # mov [boot_drive], dl -9A 54 7C 00 00 # call get_drive_geometry() -BF 00 7E # mov di, 0x7E00 ; place remaining code after MBR in memory -B8 07 00 # mov ax, 0x0007 ; num_sectors = 7 -B9 02 00 # mov cx, 0x0002 ; cylinder = 0, sector_num = 0x02 -B6 00 # mov dh, 0 ; head = 0 -9A A5 7C 00 00 # call read_sectors_16 - -# start 32bit mode -B8 01 24 # mov ax,2401h # enable A20 line -CD 15 # int 15h - -FA # cli -0F 01 16 20 7D # lgdt GDT_locator -0F 20 C0 # mov eax, cr0 -66 83 C8 01 # or eax, 0x01 -0F 22 C0 # mov cr0, eax -EA 59 7D 08 00 # jmp setup_32bit ; sets CS - -#------ -#[7D59] -#:setup_32bit -66 B8 10 00 # mov ax, 0x0010 ; data descriptor -8E D8 # mov ds, ax -8E D0 # mov ss, ax -8E C0 # mov es, ax -8E E0 # mov fs, ax -8E E8 # mov gs, ax -BD 00 00 00 08 # mov ebp, 0x08000000 -89 EC # mov esp, ebp - -9A 7C 7D 00 00 08 00 # call setup_interrupt_handlers -EA A1 88 00 00 08 00 # jmp internalshell - - -#---------------------------------------- -#[7D7C] -#:setup_interrupt_handlers -53 # push ebx - -# handle the timer interrupt 08 -BB 40 00 01 00 # mov ebx, &interrupt_table[08] -66 C7 03 BC 7D # mov word [ebx + 0], low_address stub_interrupt_handler -66 C7 43 06 00 00 # mov word [ebx + 6], high_address -66 C7 43 02 08 00 # mov word [ebx + 2], code_segment = 0x0800 -C6 43 05 8E # mov byte [ebx + 5], flags = 8E - -# handle int 80 -BB 00 04 01 00 # mov ebx, &interrupt_table[80] -66 C7 03 D8 7E # mov word [ebx + 0], low_address syscall_interrupt_handler -66 C7 43 06 00 00 # mov word [ebx + 6], high_address -66 C7 43 02 08 00 # mov word [ebx + 2], code_segment = 0x0800 -C6 43 05 8E # mov byte [ebx + 5], flags = 8E - -# load the interrupt table -FA # cli -0F 01 1D BD 7D 00 00 # lidt IDT_locator_32 -FB # sti -5B # pop ebx -CB # retf - - -#---------------------------------------- -#[7DBC] -#:stub_interrupt_handler -CF # iret - - -#---------------------------------------- -#[7DBD] -#:IDT_locator_32 -FF 07 # length -00 00 01 00 # IDT_start - -# unused -00 00 - - -#------------------------------------------------------------ -# 32 -> 16 -> 32 bit switching functions -#------------------------------------------------------------ -# When switching between real mode and -# protected, registers are stored here: -# -# 7B14 edx -# 7B10 -# 7B0C -# 7B08 eax -# 7B04 esp -# -# 7B00 <- top of real mode stack - -#---------------------------------------- -#[7DC5] -#:enter_16bit_real -FA # cli -A3 08 7B 00 00 # mov [0x7B08], eax ; preserve so we can use these locally -89 15 14 7B 00 00 # mov [0x7B14], edx ; -5A # pop edx ; capture return address -89 25 04 7B 00 00 # mov [0x7B04], esp ; capture stack - -# The following far jump sets CS to a 16-bit protected mode selector -# and the segment registers are also set to 16-bit protected mode selectors. -# This is done prior to entering real mode. -EA DF 7D 00 00 18 00 # jmp 0x18:setup_16bit -#------ -#[7DDF] -#:setup_16bit -B8 20 00 # mov eax, 0x0020 -8E D0 # mov ss, eax -8E D8 # mov ds, eax -8E C0 # mov es, eax -8E E8 # mov gs, eax -8E E0 # mov fs, eax -BC 00 7B # mov sp, 0x7B00 -0F 20 C0 # mov eax, cr0 -66 83 E0 FE # and eax, 0xfffffffe ; clear protected mode -0F 22 C0 # mov cr0, eax -# The following far jump sets CS to a 16-bit real mode segment -# and the segment registers are also set to real mode segments. -EA 00 7E 00 00 # jmp 0000:XXXX real_mode - -# [7DFE] -# This is the DOS/MBR identifier at offset 510: -55 AA - -#------ -#[7E00] -#:real_mode -B8 00 00 # mov ax, 0x0 -8E D8 # mov ds, ax -8E E0 # mov fs, ax -8E E8 # mov gs, ax -8E D0 # mov ss, ax -8E C0 # mov es, ax -BC 00 7B # mov sp, 0x7B00 -FA # cli -0F 01 1E 22 7E # lidt IDT_locator_16 -FB # sti -# Using retf to set CS comes from here: -# https://stackoverflow.com/questions/26448480/bios-interrupts-in-protected-mode -# This page recommends a far jump followed by sti: -# https://www.sudleyplace.com/pmtorm.html -6A 00 # push 0x0000 (2 bytes!) CS to return to -52 # push dx IP to return to -A1 08 7B # mov ax, [0x7B08] ; restore from above -8B 16 14 7b # mov dx, [0x7B14] -CB # retf - -#------ -#[7E22] -#:IDT_locator_16 -FF FF -00 00 00 00 - - -#---------------------------------------- -#[7E28] -#:resume_32bit_mode -FA # cli -A3 08 7B # mov [0x7B08], ax ; preserve, they might be return values from 16 bit -89 16 14 7b # mov [0x7B14], dx -5A # pop dx ; carry the return IP in dx -58 # pop ax ; CS -0F 01 16 20 7D # lgdt GDT_locator -0F 20 C0 # mov eax, cr0 -66 83 C8 01 # or eax, 0x01 ; enable protected mode -0F 22 C0 # mov cr0, eax -EA 46 7E 08 00 # jmp restore_32bit -#------ -#[7E46] -#:restore_32bit -B8 10 00 00 00 # mov eax, 0x0010 ; data descriptor -8E D8 # mov ds, eax -8E D0 # mov ss, eax -8E C0 # mov es, eax -8E E0 # mov fs, eax -8E E8 # mov gs, eax -8B 25 04 7B 00 00 # mov esp, [0x7B04] ; restore, (saved in enter_16bit_mode) -9A 7C 7D 00 00 08 00 # call setup_interrupt_handlers -52 # push edx ; setup our return location -# These restore the 16 bit portion of these registers, which may be a -# return value from a 16 bit function, and they also restore any previous high -# bits that were stored by enter_16bit_mode so these registers need not be -# saved when going to 16 bit mode and back if you want them left alone. -A1 08 7B 00 00 # mov eax, [0x7B08] ; restore, (saved at top of this function) -8B 15 14 7B 00 00 # mov edx, [0x7B14] -C3 # ret - - -#------------------------ -#[7E6F] -#:console_putc -# -E8 51 FF FF FF # CALL enter_16bit_real, next=[7E74] -9A 11 7C 00 00 # CALL console_putc_16(al) -9A 28 7E 00 00 # CALL resume_32bit_mode -CB # RETF - - -#------------------------ -#[7E7F] -#:console_put_hex -E8 41 FF FF FF # CALL enter_16bit_real, next=[7E84] -9A 27 7C 00 00 # CALL console_put_hex_16(al) -9A 28 7E 00 00 # CALL resume_32bit_mode -CB # RETF - - -#------------------------ -#[7E8F] -#:console_puts -# inputs -# ds:si: string to print -#:puts_loop -50 # push eax -56 # push esi -8A 06 # mov al, [esi] -3C 00 # cmp al, 0 -74 0A # jz end_puts_loop -9A 6F 7E 00 00 08 00 # call console_putc -46 # inc esi -EB F0 # jmp puts_loop -#:end_puts_loop -B0 0A # mov al, 0A -9A 6F 7E 00 00 08 00 # call console_putc -5E # pop esi -58 # pop eax -CB # RETF - - -#------------------------ -#[7EAD] -#:read_sectors -# inputs: -# di: dest_addr -# cx: cylinder/sector -# dh: head -# ax: num_sectors -# -E8 13 FF FF FF # CALL enter_16bit_real, next=[7EB2] -9A A5 7C 00 00 # CALL read_sectors_16 -9A 28 7E 00 00 # CALL resume_32bit_mode -CB # RETF - - -#------------------------ -#[7EBD] -#:write_sectors -# inputs: -# si: source_addr -# cx: cylinder/sector -# dh: head -# ax: num_sectors -# -E8 03 FF FF FF # CALL enter_16bit_real, next=[7EC2] -9A CE 7C 00 00 # CALL write_sectors_16 -9A 28 7E 00 00 # CALL resume_32bit_mode -CB # RETF - -#------------------------ -#[7ECD] -#:reboot -E8 F3 FE FF FF # call enter_16bit_real, next=[7ED2] -FA # cli -EA F0 FF 00 F0 # ljmp $F000:FFF0 ; reboot - - -#------------------------ -#[7ED8] -#:syscall_interrupt_handler -# -3C 01 # cmp al, 1 -75 08 # jne try next -9A B7 84 00 00 08 00 # call handle_syscall_exit -CF # iret - -3C 02 # cmp al, 2 -75 08 # jne try next -9A B0 82 00 00 08 00 # call handle_syscall_fork -CF # iret - -3C 03 # cmp al, 3 -75 08 # jne try next -9A 5B 81 00 00 08 00 # call handle_syscall_read -CF # iret - -3C 04 # cmp al, 4 -75 08 # jne try next -9A 3D 82 00 00 08 00 # call handle_syscall_write -CF # iret - -3C 05 # cmp al, 5 -75 08 # jne try next -9A 94 7F 00 00 08 00 # call handle_syscall_open -CF # iret - -3C 06 # cmp al, 6 -75 08 # jne try next -9A 5E 80 00 00 08 00 # call handle_syscall_close -CF # iret - -3C 07 # cmp eax, 7 -75 08 # jne try next -9A 0B 85 00 00 08 00 # call handle_syscall_waitpid -CF # iret - -3C 0B # cmp eax, B -75 08 # jne try next -9A 1E 83 00 00 08 00 # call handle_syscall_execve -CF # iret - -3C 0C # cmp al, C -75 08 # jne try next -9A 60 84 00 00 08 00 # call handle_syscall_chdir -CF # iret - -3C 13 # cmp al, 0x13 -75 08 # jne try next -9A 25 85 00 00 08 00 # call handle_syscall_lseek -CF # iret - -3C 2D # cmp al, 2D -75 08 # jne try next -9A 0E 82 00 00 08 00 # call handle_syscall_brk -CF # iret - -3C 21 # cmp al, 0x21 -75 08 # jne try next -9A 6D 85 00 00 08 00 # call handle_syscall_access -CF # iret - -3C 27 # cmp al, 0x27 -75 08 # jne syscall_ok -9A 83 85 00 00 08 00 # call handle_syscall_mkdir -CF # iret - -# wait4 -3C 72 # cmp eax, 0x72 -75 05 # jne try next -31 C0 # xor eax, eax -89 01 # mov [ecx], eax -CF # iret - -3C B7 # cmp al, 0xB7 -75 08 # jne syscall_ok -9A 99 85 00 00 08 00 # call handle_syscall_getcwd -CF # iret - -#:syscall_ok -# return success for all unimplemented syscalls -31 C0 # xor eax, eax -CF # iret - - -#------ -#[7F8C] -#:next_filenum -04 00 00 00 - -#------ -#[7F90] -#:next_file_address -00 00 00 54 - -#---------------------------------------- -#[7F94] -#:handle_syscall_open -# inputs: -# ebx: filename -# ecx: flags -# -53 # push ebx -51 # push ecx -56 # push esi -57 # push edi - -9A 76 80 00 00 08 00 # call absolute_path - -F7 C1 40 00 00 00 # test ecx, 0x40 ; 0x40 is O_CREAT -74 72 # jz open_read - -# Create new file - -# Exit with error if directory does not exist - -# Go the end of filename -89 DE # mov esi, ebx -#:end_loop -AC # lodsb -3C 00 # cmp al, 0 -75 FB # jne end_loop -# Look in reverse for last slash -4E # dec esi -FD # std ; go backwards -#:find_slash_loop -AC # lodsb -3C 2F # cmp al, '/' -75 FB # jne find_slash_loop -# If first slash at start, its root, so it exists -FC # cld -46 # inc esi -39 DE # cmp esi, ebx -74 1C # je after_dir_lookup -# Zero out slash -31 C0 # xor eax, eax -89 F7 # mov edi, esi -AA # stosb -# Lookup directory -9A 13 81 00 00 08 00 # call find_file ; eax=find_file(ebx) -# Restore first char -C6 47 FF 2F # mov byte [edi - 1], 0x2f -83 F8 FF # cmp eax, -1 -75 07 # jne after_dir_lookup -EA 59 80 00 00 08 00 # jmp syscall_open_finish_fail - -#:after_dir_lookup - -# copy filename to new slot -89 DE # mov esi, ebx -BF 00 00 20 00 # mov edi, 0x0200000 -A1 8C 7F 00 00 # mov eax, [&next_filenum] -C1 E0 0A # shl eax, 0a -01 C7 # add edi, eax -B9 00 04 00 00 # mov ecx, 0x0000400 -F3 A4 # rep movsb - -# set address of file -BF 00 00 00 01 # mov edi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] -A1 8C 7F 00 00 # mov eax, [&next_filenum] -C1 E0 04 # shl eax, 04 -01 C7 # add edi, eax ; pfile_descriptor += sizeof(file_descriptor) * next_filenum -8B 0D 90 7F 00 00 # mov ecx, [next_file_address] - -89 4F 04 # mov [edi+4], ecx ; pfile_descriptor->file_addr = ecx - -31 C0 # xor eax, eax -89 47 08 # mov [edi+8], eax ; pfile_descriptor->length = 0 - -A1 8C 7F 00 00 # mov eax, [next_filenum] ; return next_filenum -FF 05 8C 7F 00 00 # inc [next_filenum] -EB 18 # jmp syscall_open_finish - -#open_read -9A 13 81 00 00 08 00 # call find_file -83 F8 FF # cmp eax, -1 -74 34 # je syscall_open_finish_fail - -89 C1 # mov ecx, eax -# set read offset to start of file -BE 00 00 00 01 # mov esi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] -C1 E1 04 # shl ecx, 04 -01 CE # add esi, ecx ; pfile_descriptor += sizeof(file_descriptor) * filenum - -#:syscall_open_finish -8B 35 1A 83 00 00 # mov esi, [&next_process_num] -4E # dec esi = current process -C1 E6 0C # shl esi, 0x0C -81 C6 20 02 02 00 # add esi, 0x0020220 ; pproc_descriptor = &pproc_descriptor[current_process_num].open_files[4] - -6A 04 # push 0x04 ; start at fd=4 -59 # pop ecx -#:find_slot_loop -8B 1E # mov ebx, [esi] ; get file number of fd slot -85 DB # test ebx, ebx ; is this fd slot available? -74 06 # jz got_slot -41 # inc ecx ; no, go to next slot -83 C6 08 # add esi, 0x08 -EB F4 # jmp find_slot_loop -#:got_slot -89 06 # mov [esi], eax ; store file number in slot -89 C8 # mov eax, ecx ; return fd - -31 C9 # xor ecx, ecx ; set current file offset to zero -89 4E 04 # mov [esi+0x4], ecx - -#-------- -#[8059] -#:syscall_open_finish_fail - -5F # pop edi -5E # pop esi -59 # pop ecx -5B # pop ebx -CB # ret - - -#---------------------------------------- -#[805E] -#:handle_syscall_close -# inputs: -# ebx: fd - -57 # push edi -8B 3D 1A 83 00 00 # mov edi, [&next_process_num] -4F # dec edi = current process -C1 E7 0C # shl edi, 0x0C -81 C7 00 02 02 00 # add edi, 0x00020200 ; edi = all_procs[current_process_num].open_files -31 C0 # xor eax, eax -89 04 DF # mov [edi+ebx*8], eax ; open_files[fd].global_index = 0 -5F # pop edi -CB # ret - - -#---------------------------------------- -#[8076] -#:absolute_path -# inputs: -# ebx: path -# outputs: -# ebx: absolute path -# -50 # push eax -52 # push edx -56 # push esi -57 # push edi - -BF 00 02 04 00 # mov edi, 0x00040200 ; scratch buffer -57 # push edi - -# if absolute path, skip prefixing current directory -80 3b 2f # cmp [ebx], '/' -74 18 # je strcpy_path_arg - -# get cwd -8B 35 1A 83 00 00 # mov esi, [&next_process_num] -4E # dec esi = current process -C1 E6 0C # shl esi, 0x0C -81 C6 00 01 02 00 # add esi, 0x0020100 ; pproc_descriptor = &pproc_descriptor[current_process_num].current_dir - -#:strcpy_cwd_loop -AC # lodsb -84 C0 # test al, al -74 03 # jz strcpy_path_arg -AA # stosb -EB F8 # jmp strcpy_cwd_loop - -#:strcpy_path_arg -89 DE # mov esi, ebx -# skip leading ./ -66 81 3E 2E 2F # cmp word [esi], 0x2F2E -75 02 # jne strcpy_path -46 # inc esi -46 # inc esi - -#:strcpy_path -31 DB # xor ebx, ebx ; init last_char -#:strcpy_path_loop -AC # lodsb -3C 2F # cmp al, '/' -75 05 # jne ok_path_char -80 FB 2F # cmp bl, '/' -74 01 # je skip_extra_slash -#:ok_path_char -AA # stosb -#:skip_extra_slash -84 C0 # test al, al -74 04 # jz maybe_strip_ending_slash -88 C3 # mov bl, al ; save last_char -EB ED # jmp strcpy_path_loop - -#:maybe_strip_ending_slash -80 FB 2F # cmp bl, '/' -75 05 # jne handle_dots -31 C0 # xor eax, eax -4F # dec edi -4F # dec edi -AA # stosb - -# handle /. and /.. -#:handle_dots -5A # pop edx ; record first parent -52 # push edx - -#:handle_dots_loop -5E # pop esi ; get start location -56 # push esi ; save start location - -## find_slash -AC # lodsb -3C 00 # cmp al, 0 -74 33 # je absolute_path_finish -3C 2F # cmp al, '/' -75 F7 # jne find_slash - -#:found_slash -AC # lodsb -# check for /. or /.. -3C 00 # cmp al, 0 -74 2A # je absolute_path_finish -3C 2E # cmp al, '.' -74 06 # je dot_or_dotdot -89 F2 # mov edx, esi ; record start of parent -4A # dec edx ; go back to slash -4A # dec edx -EB E8 # jmp find_slash -#:dot_or_dotdot -AC # lodsb -3C 2E # cmp al, '.' -75 0A # jne remove_slashdot - -#:remove_parent -89 D7 # mov edi, edx -AC # lodsb -AA # stosb -3C 00 # cmp al, 0 -75 FA # jne copy -EB D7 # jmp handle_dots_loop - -#:remove_slashdot -3C 00 # cmp al, 0 -75 01 # jne not_ending_slashdot -4E # dec esi ; go back to null -#:not_ending_slashdot -89 F7 # mov edi, esi -4F # dec edi -4F # dec edi -#:copy_over_slashdot -AC # lodsb -AA # stosb -3C 00 # cmp al, 0 -75 FA # jne copy_over_slashdot -EB C6 # jmp handle_dots_loop - -#:absolute_path_finish -5B # pop ebx - -# restore / if necessary -80 3B 00 # cmp byte [ebx], 0 -75 05 # jne abs_path_done -66 C7 03 2F 00 # mov word [ebx], 0x002F - -#:abs_path_done -5F # pop edi -5E # pop esi -5A # pop edx -58 # pop eax -CB - - -#---------------------------------------- -#[8113] -#:find_file -# inputs: -# ebx: file_name -# outputs: -# eax: filenum -# -51 # push ecx -52 # push edx -56 # push esi -57 # push edi - -A1 8C 7F 00 00 # mov eax, [next_filenum] -48 # dec eax -89 DE # mov esi, ebx - -#:checkfile -83 F8 03 # cmp eax, 3 -74 17 # je not_found -89 C7 # mov edi, eax -C1 E7 0A # shl edi, 0x0a -81 C7 00 00 20 00 # add edi, 0x0200000 -9A C6 85 00 00 08 00 # call strcmp -74 08 # je find_file_finish -48 # dec eax -EB E4 # jmp checkfile - -#:not_found -B8 FF FF FF FF # mov eax, 0xffffffff - -#:find_file_finish -5F # pop edi -5E # pop esi -5A # pop edx -59 # pop ecx -CB # ret - - -#------------------------------------------------------------ -#[8145] -#:fd_to_file_index -# inputs: -# ebx: file descriptor number -# outputs: -# ebx: global file index -57 # push edi -8B 3D 1A 83 00 00 # mov edi, [&next_process_num] -4F # dec edi = current process -C1 E7 0C # shl edi, 0x0C -81 C7 00 02 02 00 # add edi, 0x00020200 ; edi = all_procs[current_process_num].open_files -8B 1C DF # mov ebx, [edi+ebx*8] -5F # pop edi -CB # ret - - -#------------------------------------------------------------ -#[815B] -#:handle_syscall_read -# inputs: -# ecx: *return_char -# ebx: file -# edx: length -# -53 # push ebx -51 # push ecx -52 # push edx -56 # push esi -57 # push edi - -51 # push ecx ; we need this later to return char -83 FB 00 # cmp ebx, 0 -75 5F # jne read_memfile - -# stdin disk position is stored in fd 0 -# get current position -BB 00 00 00 01 # mov ebx, 0x01000000 -66 8B 0B # mov cx, [ebx] -8A 73 02 # mov dh, [ebx+2] -31 C0 # xor eax, eax -66 8B 43 04 # mov ax, [ebx+4] - -#end of sector? -66 3D ff 01 # cmp ax, 0x01ff -74 04 # je read_next_sector - -#:nextchar -66 40 # inc ax -EB 2A # jmp getchar - -#:read_next_sector -BF 00 A0 00 00 # mov edi, 0x000A000 -B8 01 00 00 00 # mov eax, 0x0001 ; num_sectors = 1 -9A AD 7E 00 00 08 00 # call read_sectors -# save new location and offset -66 89 0b # mov [ebx], cx -88 73 02 # mov [ebx+2], dh -31 C0 # xor eax, eax - -# move block to device buffer -BE 00 A0 00 00 # mov esi, 0x000A000 -BF 00 00 04 00 # mov edi, 0x0040000 -B9 00 02 00 00 # mov ecx, 0x0000200 -F3 A4 # rep movsb - -#:getchar -66 A3 04 00 00 01 # mov [0x01000004], ax -59 # pop ecx -BB 00 00 04 00 # mov ebx, 0x40000 ; device buffer -89 C6 # mov esi, eax ; offset -8A 04 33 # mov al, [ebx+esi+0] -88 01 # mov [ecx], al -B8 01 00 00 00 # mov eax, 1 -EB 43 # jmp syscall_read_finish - -#:read_memfile -89 D8 # mov eax, ebx ; eax = fd -9A 45 81 00 00 08 00 # call fd_to_file_index ; ebx = global file index -# get pointer to global file -BE 00 00 00 01 # mov esi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] -C1 E3 04 # shl ebx, 04 -01 DE # add esi, ebx ; pfile_descriptor += sizeof(file_descriptor) * filenum - -# prepare to read -5F # pop edi ; edi = p_dst -8B 5E 04 # mov ebx, [esi+4] ; ebx = pfile_descriptor->file_address -89 D9 # mov ecx, ebx ; -03 4E 08 # add ecx, [esi+0x08] ; ecx = file_address + length -49 # dec ecx ; ecx = last address to read - -8B 35 1A 83 00 00 # mov esi, [&next_process_num] -4E # dec esi = current process -C1 E6 0C # shl esi, 0x0C -81 C6 04 02 02 00 # add esi, 0x0020204 -C1 E0 03 # shl eax, 3 -01 C6 # add esi, eax ; esi = &all_procs[current_proc_num].files[eax].current_offset - -03 1E # add ebx, [esi] ; ebx = file_addr + current_offset -87 F3 # xchg esi, ebx ; esi = p_src, ebx = &pproc_descriptor->offset -31 C0 # xor eax, eax ; bytes_read = 0 - -#:syscall_read_loop -39 CE # cmp esi, ecx ; past the end? -77 07 # ja syscall_read_finish - -A4 # movsb -40 # inc eax ; bytes_read++ -FF 03 # inc long [ebx] ; (*pcurrent_offset)++ -4A # dec edx ; length_to_read-- -75 F5 # jnz syscall_read_loop - -#:syscall_read_finish -5F # pop edi -5E # pop esi -5A # pop edx -59 # pop ecx -5B # pop ebx -CB # ret - - - -#------------------------------------------------------------ -#[820E] -#:handle_syscall_brk -56 # push esi - -A1 1A 83 00 00 # mov eax, [&next_process_num] -48 # dec eax = current process - -BE 00 00 02 00 # mov esi, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] -C1 E0 0C # shl eax, 0x0C -01 C6 # add esi, eax ; pproc_descriptor += sizeof(proc_descriptor) * procnum - -85 DB # test ebx, ebx ; if ebx == 0, just return the current brk -74 15 # jz get_brk - -# set -# initialize memory to zero -57 # push edi -8B 7E 04 # mov edi, [esi+4] -31 C0 # xor eax, eax -#:init_loop -39 DF # cmp edi, ebx -74 03 # je init_done -AA # stosb -EB F9 # jmp init_loop -#:init_done -5F # pop edi - -89 5E 04 # mov [esi+4], ebx -89 D8 # mov eax, ebx -5E # pop esi -CB # ret - -#:get_brk -8B 46 04 # mov eax, [esi+4] ; pproc_descriptor->brk -5E # pop esi -CB # ret - - -#------------------------------------------------------------ -#[823D] -#:handle_syscall_write -# inputs: -# ebx: file -# ecx: address of char to write -# edx: num bytes to write -51 # push ecx -52 # push edx -56 # push esi -57 # push edi - -31 C0 # xor eax, eax ; bytes_written = 0 - -83 FB 02 # cmp ebx, 02 ; std file? -7F 14 # jg write_memfile - -# stdout,stderr -> console_out -#:std_loop -85 D2 # test edx, edx -74 5B # jz syscall_write_finish -50 # push eax ; save num_written -8A 01 # mov al, [ecx] -9A 6F 7E 00 00 08 00 # call console_putc -58 # pop eax ; restore num_written - -40 # inc eax ; num_written++ -41 # inc ecx ; p_dst++ -4A # dec edx ; count-- -EB EC # jmp std_loop - -#:write_memfile -89 CE # mov esi, ecx - -# use ecx as pointer to fd current offset -8B 0D 1A 83 00 00 # mov ecx, [&next_process_num] -49 # dec ecx = current process -C1 E1 0C # shl ecx, 0x0C -81 C1 04 02 02 00 # add ecx, 0x0020204 -53 # push ebx -C1 E3 03 # shl ebx, 3 -01 D9 # add ecx, ebx ; ecx = &all_procs[current_proc_num].files[ebx].current_offset -5B # pop ebx - -# lookup global file index from file descriptor -9A 45 81 00 00 08 00 # call fd_to_file_index -C1 E3 04 # shl ebx, 04 -81 C3 00 00 00 01 # add ebx, 0x01000000 ; pfile_descriptor += sizeof(file_descriptor) * filenum - -8B 7B 04 # mov edi, [ebx+4] ; edi = pfile_descriptor->file_address -03 39 # add edi, [ecx] ; edi = file_addr + current_offset -#:write_loop -85 D2 # test edx, edx -74 19 # jz syscall_write_finish -A4 # movsb -FF 01 # inc long [ecx] ; current_offset++ -# If current offset is past previous file length, then increase length -50 # push eax -8B 01 # mov eax, [ecx] -3B 43 08 # cmp eax, [ebx+0x8] -7E 09 # jle skip_lengthen -FF 43 08 # inc long [ebx+0x8] ; file_length++ -FF 05 90 7F 00 00 # inc long [next_file_address] -#:skip_lengthen -58 # pop eax -40 # inc eax ; num_written++ -4A # dec edx -EB E3 # jmp write_loop - -#:syscall_write_finish -5F # pop edi -5E # pop esi -5A # pop edx -59 # pop ecx -CB # ret - - -#------ -#[82AC] -#:next_save_process_address -00 00 00 30 - -#---------------------------------------- -#[82B0] -#:handle_syscall_fork -53 # push ebx -51 # push ecx -52 # push edx -56 # push esi -57 # push edi -55 # push ebp - -A1 1A 83 00 00 # mov eax, [&next_process_num] -48 # dec eax = current process -89 C2 # mov edx, eax -BF 00 00 02 00 # mov edi, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] -C1 E0 0C # shl eax, 0x0C -01 C7 # add edi, eax ; pproc_descriptor += sizeof(proc_descriptor) * procnum - -8b 77 04 # mov esi, [edi+0x4] ; save brk pointer -89 77 14 # mov [edi+0x14], esi -89 E6 # mov esi, esp -89 77 0c # mov [edi+0xC], esi ; save stack pointer so we can return again later -FF 47 10 # inc [edi+0x10] ; fork = true - -A1 AC 82 00 00 # mov eax, [next_save_process_address] ; set save stack location -89 47 24 # mov [edi+0x24], eax - -B9 00 00 00 08 # mov ecx, 0x08000000 -29 F1 # sub ecx, esi ; compute save stack length -01 0D AC 82 00 00 # add [next_save_process_address], ecx -89 4F 28 # mov [edi+0x28], ecx -89 C7 # mov edi, eax -F3 A4 # rep movsb ; save stack - -# copy current process image to storage -89 D0 # mov eax, edx ; restore current process num -C1 E0 0C # shl eax, 0x0C -05 00 00 02 00 # add eax, 0x0020000 -8B 30 # mov esi, [eax] ; esi = pproc_descriptor->process_address - -8B 48 14 # mov ecx, [eax+0x14] ; process_length = brk - process_address -29 F1 # sub ecx, esi -89 78 1C # mov [eax+0x1C], edi ; save address of saved process memory -89 48 20 # mov [eax+0x20], ecx ; save length of process memory -01 0D AC 82 00 00 # add [next_save_process_address], ecx -F3 A4 # rep movsb ; copy current process image to storage - -31 C0 # xor eax, eax ; return as child, we'll return again as parent when child exits -5D # pop ebp -5F # pop edi -5E # pop esi -5A # pop edx -59 # pop ecx -5B # pop ebx -CB # ret - - -#------ -#[831A] -#:next_process_num -01 00 00 00 - -#---------------------------------------- -#[831E] -#:handle_syscall_execve -# inputs: -# ebx: program_name -# ecx: char **args -# edx: env -# - -A1 1A 83 00 00 # mov eax, [next_process_num] -3C 01 # cmp al, 1 -75 0A # jne not_first_process - -# first process -BD 00 10 02 00 # mov ebp, 0x00021000 ; ebp = &proc_descriptor[1] -89 65 08 # mov [ebp+0x8], esp ; save original stack pointer before pushing args -EB 23 # jmp prepare_stack - -# not_first_process -# check if current process forked or not. -# if so, create new process, if not overlay current -48 # dec eax ; eax = current_process -C1 E0 0C # shl eax, 0x0C -05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] -8B 68 10 # mov ebp, [eax+0x10] ; create_new_process = pproc->forked -85 ED # test ebp, ebp ; did current process fork? -75 0B # jnz forked - -#not_forked -8B 60 0C # mov esp, [eax+0xC] ; no fork so reset initial stack to same as current process -A1 1A 83 00 00 # mov eax, [next_process_num] -48 # dec eax -EB 08 # jump prepare_stack - -#:forked -FF 48 10 # dec [eax+0x10] ; fork handled so reset: fork = false -A1 1A 83 00 00 # mov eax, [next_process_num] - - -#:prepare_stack -# eax=process number to use -# --- env --- -8B 3D AC 82 00 00 # mov edi, [next_save_process_address] -6A 00 # push 0 ; push end of env -#:push_env_loop -# copy env arg to memory for this process -8B 32 # mov esi, [edx] -85 F6 # test esi, esi -74 0F # jz end_env_loop -57 # push edi ; push p_arg -51 # push ecx -B9 00 01 00 00 # mov ecx, 0x00000100 ; memory per arg -F3 A4 # rep movsb ; copy to new memory -59 # pop ecx -83 C2 04 # add edx, 4 -EB EB # jmp push_env_loop - - -#:end_env_loop -# --- args --- -6A 00 # push 0 ; push end of args -# count args -31 C0 # xor eax, eax ; passed_args = 0 -#:countloop -83 39 00 # cmp long [ecx], 0 -74 06 # jz push_args -40 # inc eax -83 C1 04 # add ecx, 4 -EB F5 # jmp countloop - -# push_args -89 C2 # mov edx, eax ; save eax (can't push) -#:push_args_loop -83 E9 04 # sub ecx, 4 - -# copy arg to memory for this process -8B 31 # mov esi, [ecx] - -57 # push edi ; push p_arg - -51 # push ecx -B9 00 01 00 00 # mov ecx, 0x00000100 ; memory per arg -F3 A4 # rep movsb -59 # pop ecx -48 # dec eax -75 EE # jnz push_args_loop - -# finish with argc -89 D0 # mov eax, edx ; restore eax -50 # push eax = argc - -# get current process descriptor -A1 1A 83 00 00 # mov eax, [next_process_num] -48 # dec eax -50 # push eax ; save current process num -C1 E0 0C # shl eax, 0x0C -05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &proc_descriptor[current_process_num] - -89 3D AC 82 00 00 # mov [next_save_process_address], edi - -# copy cwd from current process -05 00 01 00 00 # add eax, 0x100 -89 C6 # mov esi, eax -05 00 10 00 00 # add eax, 0x1000 -89 C7 # mov edi, eax -#loop -AC # lodsb -AA # stosb -3C 00 # cmp al, 0 -75 FA # jne loop - -58 # pop eax ; restore current process num -40 # inc eax ; eax = new process id - -# prepare process image in memory -50 # push eax ; save new process id -# get file address and length -9A 76 80 00 00 08 00 # call absolute_path -9A 13 81 00 00 08 00 # call find_file ; eax=find_file(ebx) - -# zero process memory. -# Do this after looking up file name because that may come from process memory. -50 # push eax -57 # push edi -31 C0 # xor eax, eax -BF 00 80 04 08 # mov edi, 0x08048000 -B9 00 80 FB 26 # mov ecx, 0x26FB8000 -F3 AA # rep stosb -5F # pop edi -58 # pop eax - -C1 E0 04 # shl eax, 04 ; pfile_descriptor = sizeof(file_descriptor) * filenum -05 00 00 00 01 # add eax, 0x01000000 ; pfile_descriptor += &file_descriptors[0] - -8B 40 04 # mov eax, [eax + 0x4] ; eax = pfile_descriptor->file_address -89 C3 # mov ebx, eax ; save file address -31 C9 # xor ecx, ecx -66 8B 48 2C # mov cx, [eax + 0x2C] ; get number of program headers -8B 50 18 # mov edx, [eax + 0x18] ; get process entry address -03 40 1C # add eax, [eax + 0x1C] ; calc first program header address - -#:program_header_loop -51 # push ecx ; save program header count -8B 70 04 # mov esi, [eax + 4] ; get segment file source offset -01 DE # add esi, ebx ; calc segment file address -8B 78 08 # mov edi, [eax + 8] ; get segment memory destination address -8B 48 10 # mov ecx, [eax + 0x10] ; get segment length -F3 A4 # rep movsb - -83 C0 20 # add eax, 0x20 ; go to next program header -59 # pop ecx ; restore program header count -49 # dec ecx -75 EB # jnz program_header_loop - -58 # pop eax ; restore new process num - -85 ED # test ebp, ebp ; new process (vs overlay)? -75 01 # jnz record_process_address -48 # dec eax ; overlay - -#:record_process_address -C1 E0 0C # shl eax, 0x0C -05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &pproc_descriptor[current_process_num] - -03 5B 1C # add ebx, [ebx + 0x1C] ; calc first program header address -8B 5B 08 # mov ebx, [ebx + 0x8] ; get first segment memory address -89 18 # mov [eax], ebx ; pproc_descriptor->process_address = first segment address - -# setup brk -81 C7 00 00 02 00 # add edi, 0x00020000 ; brk after last segment plus 0x20000 -89 78 04 # mov [eax + 4], edi ; pproc_descriptor->brk -31 FF # xor edi, edi -89 78 10 # mov [eax + 0x10], edi ; pproc->forked = false - -# clear open file descriptors -89 C7 # mov edi, eax -81 C7 00 02 00 00 # add edi, 0x0000200 -31 C0 # xor eax, eax -B9 00 0E 00 00 # mov ecx, 0x00000E00 -F3 AA # rep stosb - -85 ED # test ebp, ebp ; new process (vs overlay)? -74 06 # jz after_new_process - -# prepare for next process -FF 05 1A 83 00 00 # inc [next_process_num] - -#:after_new_process -# get entry point and jump -52 # push edx -31 C0 # xor eax, eax -31 DB # xor ebx, ebx -31 C9 # xor ecx, ecx -31 D2 # xor edx, edx -31 F6 # xor esi, esi -31 FF # xor edi, edi -31 ED # xor ebp, ebp -C3 # ret - - -#---------------------------------------- -#[8460] -#:handle_syscall_chdir -56 # push esi -57 # push edi - -9A 76 80 00 00 08 00 # call absolute_path -9A 13 81 00 00 08 00 # call find_file -83 F8 FF # cmp eax, -1 -74 3F # je chdir_finish - -C1 E0 04 # shl eax, 04 -05 08 00 00 01 # add eax, 0x01000008 ; eax = &file_descriptor[filenum].file_length -83 38 00 # cmp long [eax], 0 -74 07 # je chdir_ok - -# can't chdir to a file -B8 FF FF FF FF # mov eax, -1 -EB 2B # jmp chdir_finish - -#:chdir_ok -89 DE # mov esi, ebx -8B 3D 1A 83 00 00 # mov edi, [&next_process_num] -4F # dec edi = current process -C1 E7 0C # shl edi, 0x0C -81 C7 00 01 02 00 # add edi, 0x0020100 ; pproc_descriptor = &pproc_descriptor[current_process_num].current_dir - -AC # lodsb ; first slash -AA # stosb -AC # lodsb -AA # stosb -3C 00 # cmp al, 0 -75 04 # jne chdir_loop -31 C0 # xor eax, eax -74 0D # je chdir_finish ; if "/" don't add slash - -#chdir_loop -AC # lodsb -AA # stosb -3C 00 # cmp al, 0 -75 FA # jne chdir_loop -4F # dec edi - -#:add_slash -B0 2F # mov al, '/' -AA # stosb -31 C0 # xor eax, eax -AA # stosb - -#:chdir_finish -5F # pop edi -5E # pop esi -CB # retf - - -#---------------------------------------- -#[84B7] -#:handle_syscall_exit -A1 1A 83 00 00 # mov eax, [&next_process_num] -48 # dec eax = current process -A3 1A 83 00 00 # mov [&next_process_num], eax -48 # dec eax = parent process - -3C 00 # cmp al, 0 -75 07 # jne not_first -#first process -8B 25 08 10 02 00 # mov esp, [0x021008] -CB # ret - -#not_first -C1 E0 0C # shl eax, 0x0C -05 00 00 02 00 # add eax, 0x0020000 ; pproc_descriptor = &proc_descriptor[0] -89 58 18 # mov [eax+0x18], ebx ; save child exit code - -8B 38 # mov edi, [eax] ; edi = pproc_descriptor->process_address -8B 70 1C # mov esi, [eax+0x1C] ; esi = pproc_descriptor->address_of_saved_process_memory -8B 48 20 # mov ecx, [eax+0x20] ; ecx = pproc_descriptor->length_of_process_memory -F3 A4 # rep movsb - -8B 70 24 # mov esi, [eax+0x24] ; deallocate memory for saved process -89 35 AC 82 00 00 # mov [next_save_process_address], esi - -8B 60 0C # mov esp, [eax+0xc] ; restore stack pointer -8B 70 14 # mov esi, [eax+0x14] ; restore brk pointer -89 70 04 # mov [eax+0x4], esi - -8B 70 24 # mov esi, [eax+0x24] ; restore stack -89 E7 # mov edi, esp -8B 48 28 # mov ecx, [eax+0x28] -F3 A4 # rep movsb - -# mimic syscall_fork's finish -B8 01 00 00 00 # mov eax, 0x1 ; process number for fork -5D # pop ebp -5F # pop edi -5E # pop esi -5A # pop edx -59 # pop ecx -5B # pop ebx -CB # ret ; go back to parent - - -#---------------------------------------- -#[850B] -#:handle_syscall_waitpid -8B 35 1A 83 00 00 # mov esi, [&next_process_num] -4E # dec esi = current process -C1 E6 0C # shl esi, 0x0C -81 C6 18 00 02 00 # add esi, 0x00020018 ; pchild_code = &pproc_descriptor[current_process_num].child_exit_code -8B 06 # mov eax, [esi] ; get exit code -C1 E0 08 # shl eax, 0x08 ; -89 01 # mov [ecx], eax ; waitval = ret << 8 -31 C0 # xor eax, eax -CB # ret - - -#---------------------------------------- -#[8525] -#:handle_syscall_lseek -# inputs: -# ebx: fd -# ecx: value -# edx: method (0=SEEK_SET, 1=SEEK_CUR, 2=SEEK_END) -# outputs: -# eax: offset -# -56 # push esi - -8B 35 1A 83 00 00 # mov esi, [&next_process_num] -4E # dec esi = current process -C1 E6 0C # shl esi, 0x0C -81 C6 04 02 02 00 # add esi, 0x0020204 ; pproc_descriptor = &pproc_descriptor[current_process_num].files[0].offset - -83 FA 01 # cmp edx, 1 -7F 13 # jg seek_end -7C 0A # jl seek_set - -#:seek_cur -8B 04 DE # mov eax, [esi+ebx*8] ; get current_offset -01 C8 # add eax, ecx ; current_pos += offset -89 04 DE # mov [esi+ebx*8], eax ; set current_pos -5E # pop esi -CB # ret - -#:seek_set -89 0C DE # mov [esi+ebx*8], ecx ; set current_pos -89 C8 # mov eax, ecx -5E # pop esi -CB # ret - -#:seek_end -56 # push esi -53 # push ebx -9A 45 81 00 00 08 00 # call fd_to_file_index -BE 00 00 00 01 # mov esi, 0x01000000 ; pfile_descriptor = &file_descriptor[0] -C1 E3 04 # shl ebx, 04 -01 DE # add esi, ebx -8B 46 08 # mov eax, [esi+0x8] ; get current_length -01 C8 # add eax, ecx ; current_length += offset -5B # pop ebx -5E # pop esi - -89 04 DE # mov [esi+ebx*8], eax ; set current_offset - -5E # pop esi -CB # ret - - -#---------------------------------------- -#[856D] -#:handle_syscall_access -#inputs: -# ebx: path -# ecx: mode -9A 76 80 00 00 08 00 # call absolute_path -9A 13 81 00 00 08 00 # call find_file -83 F8 FF # cmp eax, -1 -74 02 # je access_error_exit -31 C0 # xor eax, eax -#:access_error_exit -CB # ret - - -#---------------------------------------- -#[8583] -#:handle_syscall_mkdir -#inputs: -# ebx: path -# ecx: mode -51 # push ecx -B9 41 00 00 00 # mov ecx, 0x41 (O_CREAT | O_WRONLY) -9A 94 7F 00 00 08 00 # call handle_syscall_open -83 F8 FF # cmp eax, -1 -74 02 # je open_error_exit -31 C0 # xor eax, eax -#:open_error_exit -59 # pop ecx -CB # ret - - -#---------------------------------------- -#[8599] -#:handle_syscall_getcwd -#inputs: -# ebx: buf -# ecx: buf size -#outputs: -# eax: buf -56 # push esi -57 # push edi - -89 DF # mov edi, ebx -8B 35 1A 83 00 00 # mov esi, [&next_process_num] -4E # dec esi = current process -C1 E6 0C # shl esi, 0x0C -81 C6 00 01 02 00 # add esi, 0x0020100 ; pproc_descriptor = &pproc_descriptor[current_process_num].current_dir - -# Handle root differently because we don't strip trailing slash -66 83 3E 2F # cmp word [esi], $002f ; is cwd == "/" ? -75 04 # jne copy_cwd -66 A5 # movsw ; copy "/" to buffer -EB 0A # jmp cleanup - -# copy_cwd -AC # lodsb -AA # stosb -3C 00 # cmp al, 0 -75 FA # jne copy_cwd -83 EF 02 # sub edi, 2 ; strip trailing slash -AA # stosb - -# cleanup -89 D8 # mov eax, ebx -5F # pop edi -5E # pop esi -CB # ret - - -#------------------------------------------------------------ -#[85C6] -#:strcmp -# inputs: -# esi: string1 -# edi: string2 -# outputs: -# zero flag -# -50 # push eax -53 # push ebx -56 # push esi -57 # push edi - -#:check_byte -8A 06 # mov al, [esi] -8A 1F # mov bl, [edi] -38 D8 # cmp al, bl -75 0A # jne strcmp_finish -46 # inc esi -47 # inc edi -84 C0 # test al, al -75 F2 # jnz check_byte -84 DB # test bl, bl -75 EE # jnz check_byte - -#:strcmp_finish -5F # pop edi -5E # pop esi -5B # pop ebx -58 # pop eax -CB # ret - - -#------ -#[85E1] -#:io_char -00 -00 # free - -#---------------------------------------- -#[85E3] -#:read -53 # push ebx -51 # push ecx -52 # push edx -B8 03 00 00 00 # mov eax, 3 ; syscall=read -B9 E1 85 00 00 # mov ecx, &io_char -BA 01 00 00 00 # mov edx, 1 - -CD 80 # int 80 syscall - -3C 00 # cmp al, 0 -74 07 # je read_finish - -B4 01 # mov ah, 1 -A0 E1 85 00 00 # mov al, &io_char - -#:read_finish -5A # pop edx -59 # pop ecx -5B # pop ebx -CB # ret - - -#---------------------------------------- -#[8606] -#:write -50 # push eax -53 # push ebx -51 # push ecx -52 # push edx - -A2 E1 85 00 00 # mov &io_char, al -B8 04 00 00 00 # mov eax, 4 ; syscall=write -B9 E1 85 00 00 # mov ecx, &io_char -BA 01 00 00 00 # mov edx, 1 1 byte characters -CD 80 # int 80 syscall - -5A # pop edx -59 # pop ecx -5B # pop ebx -58 # pop eax -CB # ret - - -#------ -#[8625] -#:string_src -#s r c \0 -73 72 63 00 - -#---------------------------------------- -# src: create file from stdin -# -# Read an integer, N, in decimal from stdin. -# Read a space. -# Then, read a file name to create. -# Read a newline. -# Then, read N bytes from stdin and write to the new file. -#---------------------------------------- -#[8629] -#:src -50 # push eax -53 # push ebx -51 # push ecx -52 # push edx -56 # push esi -57 # push edi - -BE 25 86 00 00 # mov esi, string_src -9A 8F 7E 00 00 08 00 # call console_puts - -9A E3 85 00 00 08 00 # call read 'r' -9A E3 85 00 00 08 00 # call read 'c' -9A E3 85 00 00 08 00 # call read ' ' - -31 C9 # xor ecx, ecx ; line count=0 -#parse_line_count_loop: -9A E3 85 00 00 08 00 # call read -3C 20 # cmp al, ' ' -74 0C # je got_count - -6B C9 0A # imul ecx, ecx, 10 ; count = count * 10 -2C 30 # sub al, 30 -0F B6 C0 # movzx eax, al -01 C1 # add ecx, eax ; count += digit - -EB E9 # jmp parse_line_count_loop - -#:got_count -# clear arguments -51 # push ecx -31 C0 # xor eax, eax -BA 00 00 D0 04 # mov edx, 0x04D00000 -B9 00 08 00 00 # mov ecx, 0x00000800 - -#:src_args_zeroloop -88 02 # mov [edx], al -42 # inc edx -49 # dec ecx -75 FA # jnz src_args_zeroloop -59 # pop ecx - -51 # push ecx -B9 00 00 D0 04 # mov ecx, 0x04D00000 -#:get_filename_loop -9A E3 85 00 00 08 00 # call read - -3C 0A # cmp al, '\n' -74 05 # je got_filename -88 01 # mov [ecx], al -41 # inc ecx -EB F0 # jmp get_file_name_loop -59 # pop ecx - -#:got_filename -BE 00 00 D0 04 # mov esi, 0x04D00000 -9A 8F 7E 00 00 08 00 # call console_puts - -# open filename for write -51 # push ecx -BB 00 00 D0 04 # mov ebx, 0x04D00000 -B8 05 00 00 00 # mov eax, 5 ; syscall_open -B9 41 02 00 00 # mov ecx, 0x00000241 O_TRUNC (0x200) | O_CREAT (0x40) | O_WRONLY (0x1) -BA 80 01 00 00 # mov edx, 0x00000180 S_IRUSR (0x100) | S_IWUSR (0x80) -CD 80 # int 80 -59 # pop ecx -89 C2 # mov edx, eax - -# edx has the open file number - -#:readwrite_loop -85 C9 # test ecx, ecx -74 1C # jz src_finish -BF 00 02 04 00 # mov edi, 0x00040200 ; scratch buffer -57 # push edi ; save buffer address -31 DB # xor ebx, ebx ; ebx=0=stdin -9A E3 85 00 00 08 00 # call read -89 D3 # mov ebx, edx ; prepare to write -5E # pop esi ; restore buffer address to esi -9A 06 86 00 00 08 00 # call write -49 # dec ecx ; count-- -EB E0 # jmp read_write_loop - -#:src_finish -5F # pop edi -5E # pop esi -5A # pop edx -59 # pop ecx -5B # pop ebx -58 # pop eax -CB # ret - - - -#------ -#[86E1] -#:hex0_str -#h e x 0 \0 -68 65 78 30 00 - -#------------------------------------------------------------ -#[86E6] -#:hex0 -53 # push ebx -56 # push esi -57 # push edi - -BE E1 86 00 00 # mov esi, hex0_str -9A 8F 7E 00 00 08 00 # call console_puts - -# read "ex0 ' -B1 04 # mov cl, 4 -#:ex0_loop -9A E3 85 00 00 08 00 # call read -FE C9 # dec cl -75 F5 # jnz ex0_loop - -# clear arguments -31 C0 # xor eax, eax -BA 00 00 D0 04 # mov edx, 0x04D00000 -B9 00 08 00 00 # mov ecx, 0x00000800 -#:hex0_args_zeroloop -88 02 # mov [edx], al -42 # inc edx -49 # dec ecx -75 FA # jnz hex0_args_zeroloop - -BA 00 00 D0 04 # mov edx, 0x04D00000 -#:get_file_name1_loop -9A E3 85 00 00 08 00 # call read -9A 6F 7E 00 00 08 00 # call console_putc -3C 20 # cmp al, ' ' -74 05 # je got_filename1 -88 02 # mov [edx], al -42 # inc edx -EB E9 # jmp get_file_name1_loop - -#:got_filename1 -BA 00 04 D0 04 # mov edx, 0x04D00400 -#:get_file_name2_loop -9A E3 85 00 00 08 00 # call read -9A 6F 7E 00 00 08 00 # call console_putc -3C 0A # cmp al, '\n' -74 05 # je got_filename2 -88 02 # mov [edx], al -42 # inc edx -EB E9 # jmp get_file_name2_loop - -# open filename1 for read -BB 00 00 D0 04 # mov ebx, 0x04D00000 -B8 05 00 00 00 # mov eax, 5 ; syscall_open -B9 00 00 00 00 # mov ecx, 0x00000000 -CD 80 # int 80 - -50 # push eax ; save read filenum - -# open filename2 for write -BB 00 04 D0 04 # mov ebx, 0x04D00400 -B8 05 00 00 00 # mov eax, 5 ; syscall_open -B9 41 02 00 00 # mov ecx, 0x00000241 O_TRUNC (0x200) | O_CREAT (0x40) | O_WRONLY (0x1) -BA 80 01 00 00 # mov edx, 0x00000180 S_IRUSR (0x100) | S_IWUSR (0x80) -CD 80 # int 80 -89 C2 # mov edx, eax - -59 # pop ecx ; restore read filenum - -# this flag is set after the first digit is seen -31 DB # xor ebx, ebx - - -#------ -#[8779] -#:hex0_read_loop -53 # push ebx -89 CB # mov ebx, ecx -9A E3 85 00 00 08 00 # call read -5B # pop ebx - -84 e4 # test ah, ah -75 04 # jnz check_command -5F # POP_DI -5E # POP_SI -5B # POP_BX -CB # RETF - -#:check_command -3C 23 # cmp al, '#' - -74 28 # jz skip_comment - -3C 3B # cmp ';' -74 24 # jz skip_comment - -3C 66 # cmp al, 'f' -7F D1 # jg hex0_read_loop - -3C 61 # cmp al, 'a' -7C 04 # jl maybe_upper - -# Handle a to f -2C 57 # sub al, 'a'-10 == 87 = 0x57 -EB 29 # jmp maybe_store - -#:maybe_upper -3C 46 # cmp al, 'F' -7F D5 # jg hex0_read_loop - -3C 41 # cmp al, 'A' -7C 04 # jl maybe_digit - -# Handle A to F -2C 37 # sub al, 'A'-10 == 55 = x37 -EB 1D # jmp maybe_store - -#:maybe_digit -3C 39 # cmp al, '9' -7F C9 # jg hex0_read_loop - -3C 30 # cmp al, '0' -7C C5 # jl hex0_read_loop - -# Handle 0 to 9 -2C 30 # sub al, '0' == x30 -EB 11 # jmp maybe_store - -#:skip_comment -53 # push ebx -89 CB # mov ebx, ecx -9A E3 85 00 00 08 00 # call read -5B # pop ebx -3C 0A # cmp al, '\n' -75 F1 # jnz skip_comment -EB B0 # jmp hex0_read_loop - -# only store on second digit -#:maybe_store -84 DB # test bl, bl -75 09 # jnz second_digit - -# If on first digit, record and keep going -#:first_digit -C0 E0 04 # shl al, 4 -88 C7 # mov bh, al -FE C3 # inc bl -EB A3 # jmp hex0_read_loop - -# If on second digit, store and clear state -#:second_digit -08 C7 # or bh, al -88 F8 # mov al, bh - -53 # push ebx -89 D3 # mov ebx, edx -9A 06 86 00 00 08 00 # call write -5B # pop ebx - -31 DB # xor bx, bx -EA 79 87 00 00 08 00 # jmp hex0_read_loop - - -#------ -#[87EE] -#:cmd_args -00 00 D0 04 -00 04 D0 04 - -#------ -#[87F6] -#:cmd_env -00 00 00 00 - -#------------------------------------------------------------ -#[87FA] -#:handle_other_command -50 # push eax -53 # push ebx -51 # push ecx -52 # push edx -56 # push esi - -# clear arguments -BA 00 00 D0 04 # mov edx, 0x04D00000 -88 02 # mov [edx], al -42 # inc edx -31 C0 # xor eax, eax -B9 FF 07 00 00 # mov ecx, 0x000007FF -#other_args_zeroloop -88 02 # mov [edx], al -42 # inc edx -49 # dec ecx -75 FA # jnz other_args_zeroloop - -BA 01 00 D0 04 # mov edx, 0x04D00001 -#:get_program_name -9A E3 85 00 00 08 00 # call read -3C 20 # cmp al, ' ' -74 05 # je got_program_name -88 02 # mov [edx], al -42 # inc edx -EB F0 # jmp get_program_name - -#got_program_name -BA 00 04 D0 04 # mov edx, 0x04D00400 -#get_argument1_loop -9A E3 85 00 00 08 00 # call read -3C 0A # cmp al, '\n' -74 05 # je got_argument1 -88 02 # mov [edx], al -42 # inc edx -EB F0 # jmp get_argument1_loop - -#:got_argument1 -BE 00 00 D0 04 # mov esi, program -9A 8F 7E 00 00 08 00 # call console_puts - -BE 00 04 D0 04 # mov esi, arg1 -9A 8F 7E 00 00 08 00 # call console_puts - -BB 00 00 D0 04 # mov ebx, program_name -B9 EE 87 00 00 # mov ecx, cmd_args -BA F6 87 00 00 # mov edx, cmd_env -9A 1E 83 00 00 08 00 # call handle_syscall_execve - -5E # pop esi -5A # pop edx -59 # pop ecx -5B # pop ebx -58 # pop eax -CB - - -#------ -#[8872] -#:str_build_finished -#B u i l d f i n i s h e d . \0 -42 75 69 6C 64 20 66 69 6E 69 73 68 65 64 2E 00 - -#------ -#[8882] -#:str_error_no_writes -#E R R O R : n o h d a w r i t e s ! \0 -45 52 52 4F 52 3A 20 6E 6F 20 68 64 61 20 77 72 69 74 65 73 21 00 - -#------ -#[8898] -#:str_dev_hda -#/ d e v / h d a \0 -2F 64 65 76 2F 68 64 61 00 - - -#------------------------------------------------------------ -#[88A1] -#:internalshell -# Start reading stdin from sector 8, cyl 0, head 0 -C7 05 00 00 00 01 08 00 00 00 # mov word [0x01000000], 0x00000008 -# start at "end of sector" to trigger an initial sector read -66 C7 05 04 00 00 01 FF 01 # mov word [0x01000004], 0x01FF -66 C7 05 00 01 02 00 2F 00 # mov [0x00020100], 0x002F ; proc[0].cwd = "/" -66 C7 05 00 11 02 00 2F 00 # mov [0x00021100], 0x002F ; proc[1].cwd = "/" - -# clear file descriptors for process 0 -BF 00 02 02 00 # mov edi, 0x00020200 -B9 00 0E 00 00 # mov ecx, 0x00000E00 -31 C0 # xor eax, eax -F3 AA # rep stosb - -# read from stdin -31 DB # xor ebx, ebx - -#:process_command -9A E3 85 00 00 08 00 # call read -3C 00 # cmp al, 0 -74 23 # je build_finished - -#:check_src_command -3C 73 # cmp al, 's' -75 09 # jne check_hex0_command - -#:handle_src_command -9A 29 86 00 00 08 00 # call src -EB E8 # jmp process_command - -#:check_hex0_command -3C 68 # cmp al, 'h' -75 09 # jne call_handle_other_command - -#:handle_hex0_command -9A E6 86 00 00 08 00 # call hex0 -EB DB # jmp process_command - -#:call_handle_other_command -9A FA 87 00 00 08 00 # call handle_other_command -EB D2 # jmp process_command - -#:build_finished -BE 72 88 00 00 # mov esi, str_build_finished -9A 8F 7E 00 00 08 00 # call console_puts - -# copy memory file /dev/hda to the boot disk -BB 98 88 00 00 # mov ebx, str_dev_hda -9A 13 81 00 00 08 00 # call find_file -83 f8 ff # cmp eax, -1 -75 17 # jne ok_exit - -#:error_exit -BE 82 88 00 00 # mov esi, str_error_no_write -9A 8F 7E 00 00 08 00 # call console_puts - -# one space to flush last line -B0 20 # mov al, 20 -9A 6F 7E 00 00 08 00 # call console_putc -EB 62 # jmp shell_reboot - -#:ok_exit -# get file address to read -C1 E0 04 # shl eax, 04 -05 00 00 00 01 # add eax, 0x01000000 -8B 70 04 # mov esi, [eax+4] ; file_address -8B 58 08 # mov ebx, [eax+8] ; bytes_to_write = file_length - -# print length -89 D8 # mov eax, ebx -B9 04 00 00 00 # mov ecx, 4 -#:shift_loop -C1 C8 18 # ror eax, 24 -9A 7F 7E 00 00 08 00 # call console_put_hex -49 # dec ecx -75 F3 # jnz shift_loop -B0 0A # mov al, 0A -9A 6F 7E 00 00 08 00 # call console_putc - -# set starting disk location to write -31 C9 # xor ecx, ecx -41 # inc ecx -B6 00 # mov dh, 0 - -#:sector_loop -# copy 512 bytes from file to 16 bit buffer -51 # push ecx ; save disk location -BF 00 A0 00 00 # mov edi, 0x000A000 -B9 00 02 00 00 # mov ecx, 0x200 -F3 A4 # rep movsb -59 # pop ecx - -# now write from 16 bit buffer -56 # push esi ; save our location in the file -BE 00 A0 00 00 # mov esi, 0x000A000 -B8 01 00 00 00 # mov eax, 0x0001 ; num_sectors = 1 -9A BD 7E 00 00 08 00 # call write_sectors -5E # pop esi -81 EB 00 02 00 00 # sub ebx, 0x200 ; bytes_to_write -= 512 -7F D7 # jg sector_loop - -B0 20 # mov al, 20 -9A 6F 7E 00 00 08 00 # call console_putc - -#:shell_reboot -EA CD 7E 00 00 08 00 # jmp reboot - -# sector padding -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/parts.rst b/parts.rst @@ -11,13 +11,15 @@ bootstrap-seeds =============== -This is where it all begins. We start with the two raw binary seeds ``hex0-seed`` and ``kaem-optional-seed``. +This is where it all begins. -First, we use those seeds to rebuild themselves. +A kernel bootstrapping option is used by default at the beginning. The tiny ``builder-hex0-x86-stage1`` binary seed boots, builds and runs the ``builder-hex0-x86-stage2`` kernel. The ``builder-hex0-x86-stage1`` and ``builder-hex0-x86-stage2`` kernels are written in ``hex0``. The stage2 kernel has its own built-in shell, the ``hex0`` compiler and the ``src`` tool to load files into its memory file system. In this case the first step is to build the ``hex0-seed`` and ``kaem-optional-seed`` binaries from ``hex0`` source. -Note that all early compilers before ``mes`` are part of `stage0-posix <https://github.com/oriansj/stage0-posix>`_. +Note that all early shells and compilers before ``mes`` are part of `stage0-posix <https://github.com/oriansj/stage0-posix>`_. -A kernel bootstrapping option is used by default at the beginning. ``hex0-seed`` can be used to compile the ``builder-hex0`` kernel which has its own built-in shell, the ``hex0`` compiler and the ``src`` tool to load files into its file system. ``builder-hex0`` runs stage0-posix and then builds ``mes`` and ``tcc``. It then builds and launches the `Fiwix <https://github.com/mikaku/Fiwix>` kernel which runs the build until Linux takes over. +``builder-hex0-x86-stage2`` runs as the kernel for building the stage0-posix compilers and then ``mes`` and ``tcc``. Then the `Fiwix <https://github.com/mikaku/Fiwix>` kernel is built and launched. Then Fiwix runs the build until Linux takes over. + +If chroot or bwrap is specified or if a pre-existing kernel is provided then we start with the two raw binary seeds ``hex0-seed`` and ``kaem-optional-seed``. We use those seeds to rebuild themselves. hex0 @@ -39,9 +41,16 @@ In the first steps we use initial ``hex0`` binary seed to rebuild ``kaem-optiona ``hex0`` can be approximated with: ``sed 's/[;#].*$//g' $input_file | xxd -r -p > $output_file`` -builder-hex0 -============ -By default (when kernel bootstrap is enabled), the ``builder-hex0`` kernel boots from a hard drive and loads an enormous shell script which embeds files (loaded with the ``src`` command) and the initial commands to build ``hex0-seed``, ``kaem-optional-seed``, and the command which launches stage0-posix using ``kaem-optional-seed`` and the stage0-posix launch script ``kaem.x86``. Builder-hex0 is written in hex0 and can be compiled with any one of ``hex0-seed``, ``sed``, the tiny ``builder-hex0-mini`` boot kernel or it can build itself. +builder-hex0-x86-stage1 +======================= + +By default (when kernel bootstrap is enabled), the ``builder-hex0-x86-stage1`` boot loader/compiler boots from a hard drive and loads ``hex0`` source code from disk, compiles, and runs the ``builder-hex0-x86-stage2`` kernel. ``builder-hex0-x86-stage1`` is written in ``hex0`` and can be compiled with any one of ``hex0-seed``, ``sed``, or the tiny ``builder-hex0-mini`` binary. + + +builder-hex0-x86-stage2 +======================= + +When kernel bootstrap is enabled, the ``builder-hex0-x86-stage2`` kernel loads an enormous shell script which embeds files (loaded with the ``src`` command) and the initial commands to build ``hex0-seed``, ``kaem-optional-seed``, and the command which launches stage0-posix using ``kaem-optional-seed`` and the stage0-posix launch script ``kaem.x86``. kaem-optional @@ -222,6 +231,12 @@ kexec-fiwix If the kernel bootstrap option is enabled then a C program `kexec-fiwix` is compiled and run which places the Fiwix ram drive in memory and launches the Fiwix kernel. +kexec-linux +=========== + +If the kernel bootstrap option is enabled then a C program `kexec-linux` is compiled. +This is used as part of the go_sysb step later to launch the Linux kernel. + make 3.82 ========= @@ -686,11 +701,6 @@ The next step is not a package, but the creation of the sysb rootfs, containing all of the scripts for sysb (which merely move to sysc). Again, this is only done in non-chroot mode, because sysb does not exist in chroot mode. -musl 1.2.3 -========== -Prior to building and booting Linux, musl is rebuilt yet again with syscalls -``clone`` and ``set_thread_area`` enabled for Linux thread support. - Linux kernel 4.9.10 =================== @@ -711,6 +721,11 @@ subsequent systems, and we do not have ``modprobe``. Lastly, the initramfs of sysb is generated in this stage, using ``gen_init_cpio`` within the Linux kernel tree. This avoids the compilation of ``cpio`` as well. +musl 1.2.3 +========== +Prior to booting Linux, musl is rebuilt yet again with syscalls +``clone`` and ``set_thread_area`` enabled for Linux thread support. + go_sysb ======= diff --git a/rootfs.py b/rootfs.py @@ -35,11 +35,12 @@ def create_configuration_file(args): config.write(f"CHROOT_ONLY_SYSA={args.bwrap}\n") config.write(f"UPDATE_CHECKSUMS={args.update_checksums}\n") config.write(f"JOBS={args.cores}\n") - config.write("DISK=sda1\n") config.write(f"INTERNAL_CI={args.internal_ci}\n") if (args.bare_metal or args.qemu) and not args.kernel: + config.write("DISK=sda\n") config.write("KERNEL_BOOTSTRAP=True\n") else: + config.write("DISK=sda1\n") config.write("KERNEL_BOOTSTRAP=False\n") config.write(f"BUILD_KERNELS={args.update_checksums or args.build_kernels}\n") diff --git a/sysa.py b/sysa.py @@ -13,7 +13,6 @@ import shutil import tarfile from lib.sysgeneral import SysGeneral, stage0_arch_map -from lib.utils import run # pylint: disable=consider-using-with # pylint: disable=too-many-instance-attributes @@ -113,6 +112,8 @@ class SysA(SysGeneral): for root, _, filepaths in os.walk(dirpath): if 'stage0-posix' in root: continue + if root == os.path.join('sysc', 'distfiles'): + continue with open(file_list_path, 'a', encoding="utf-8") as file_list: for filepath in filepaths: file_list.write(f"/{os.path.join(root, filepath)}\n") @@ -193,12 +194,20 @@ class SysA(SysGeneral): def create_builder_hex0_disk_image(self, image_file_name): """Create builder-hex0 disk image""" - run(os.path.join('sysa', 'stage0-posix', 'src', - 'bootstrap-seeds', 'POSIX', 'x86', 'hex0-seed'), - os.path.join('kernel-bootstrap', 'builder-hex0-x86.hex0'), - image_file_name) + shutil.copyfile(os.path.join('sysa', 'stage0-posix', 'src', 'bootstrap-seeds', + 'NATIVE', 'x86', 'builder-hex0-x86-stage1.img'), + image_file_name) with open(image_file_name, 'ab') as image_file: + # Append stage2 hex0 source + with open(os.path.join('kernel-bootstrap', 'builder-hex0-x86-stage2.hex0'), + encoding="utf-8") as infile: + image_file.write(infile.read().encode()) + # Pad to next sector + current_size = os.stat(image_file_name).st_size + while current_size % 512 != 0: + image_file.write(b'\0') + current_size += 1 self.append_srcfs(image_file) current_size = os.stat(image_file_name).st_size @@ -213,6 +222,6 @@ class SysA(SysGeneral): # fill file with zeros up to desired size, one megabyte at a time with open(image_file_name, 'ab') as image_file: - while current_size < 1008 * megabyte: + while current_size < 16384 * megabyte: image_file.write(b'\0' * megabyte) current_size += megabyte diff --git a/sysa/SHA256SUMS.pkgs b/sysa/SHA256SUMS.pkgs @@ -40,7 +40,7 @@ d7d0a5fc9117f9b3ebd287851a48716c96a3c11991365edb8890f0e203d3b810 curl-7.88.1_1. ed1581d1ef5d42c809a7db1c27614e0a900076e7ce08349ea4797944d41c7bc7 dhcpcd-10.0.1_0.tar.bz2 c4008ae6b168aee4120b0f3624a1875f9e413d8f0c637708b8b04a1fb5be173c diffutils-2.7_0.tar.bz2 bda6afcd3a390a34a57443269a4857ccc470129f7a557981778c145fd841cbd1 dist-3.5-236_0.tar.bz2 -c0514138e251062c9ac2ff1e432e01a541777bfd61480c77479ea55f5b75cdd1 e2fsprogs-1.45.7_0.tar.bz2 +5a5923e9dcbec079b032a349471627460f553a430c82bc9b4b6c0bd34ae97547 e2fsprogs-1.45.7_0.tar.bz2 d7b7453ad400eac1ba39f99971afdc392cb8a92c557ef5d6fd9fa2625124de4a ed-1.4_0.tar.bz2 258282c136145d8fba4d66f7e150800e7ca33e024483083a15d0dba3aeb5e86b file-5.44_0.tar.bz2 5984d3f2d5513dd04dc97619e2809d634fc7e3692f36f770e0202a61b6b2921d findutils-4.2.33_0.tar.bz2 @@ -62,6 +62,7 @@ d85cff8f9ff76533287891ec2019416fa585815e514743e5b76efd9f17f5ef5c grep-3.7_0.tar b38422d646590600444f0ff12fee6fd738baaf471338aa67899db950d3521127 guile-3.0.9_0.tar.bz2 8d2015b87337abbf287f7a39ee4cf53514120b5d3e90a93fe7d533dcc43f14fa help2man-1.36.4_0.tar.bz2 3f06d1a7f1b1770d4550ff6316c7f06fd26e30bddad7c1b665f1fae80e409c8c kbd-1.15_0.tar.bz2 +d23886557310f7ff2c98898eac24b4fe8704b22e88d094e96ff996cf0d2635a4 kexec-linux-1.0.0_0.tar.bz2 2a661da13801028f5af98e5d9f6de417c21c90df1bcef4809caf0c2094fdd8f4 kexec-tools-2.0.22_0.tar.bz2 e89e4fc8ba4f917f4f609ba781fc13e43d31479d47a9da2ba3bc7ce5fcbbe6b3 libarchive-3.5.2_0.tar.bz2 36550df491767bb24d2ccab304ce70a3b4956e7c0c0e0c343d922fd57cdafbdd libatomic_ops-7.6.10_0.tar.bz2 diff --git a/sysa/e2fsprogs-1.45.7/e2fsprogs-1.45.7.sh b/sysa/e2fsprogs-1.45.7/e2fsprogs-1.45.7.sh @@ -30,6 +30,7 @@ src_prepare() { src_configure() { ./configure --prefix="${PREFIX}" \ --sbindir="${PREFIX}/bin" \ + --disable-tls \ with_udev_rules_dir=no \ with_systemd_unit_dir=no } diff --git a/sysa/fiwix-1.4.0-lb1/fiwix-1.4.0-lb1.checksums b/sysa/fiwix-1.4.0-lb1/fiwix-1.4.0-lb1.checksums @@ -1 +0,0 @@ -dd9e799311b3c505fa8efe045b969b851c60499ab41db546e5c8b545b3e19ec8 /boot/fiwix diff --git a/sysa/fiwix-1.4.0-lb1/fiwix-1.4.0-lb1.kaem b/sysa/fiwix-1.4.0-lb1/fiwix-1.4.0-lb1.kaem @@ -1,556 +0,0 @@ -#!/bin/sh -# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> -# SPDX-License-Identifier: MIT - -set -ex - -# Check tarball checksums -checksum-transcriber sources -sha256sum -c sources.SHA256SUM - -# Extract -mkdir build src -cd src -ungz --file ${distfiles}/${pkg}.tar.gz --output ${pkg}.tar -cd .. - -cd build -untar --file ../src/${pkg}.tar -cd ${pkg} - -alias as="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -traditional -I/sysa/fiwix-1.4.0-lb1/build/fiwix-1.4.0-lb1/include" - -alias cc="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -I/sysa/fiwix-1.4.0-lb1/build/fiwix-1.4.0-lb1/include -O2 -fno-pie -fno-common -ffreestanding -Wall -Wstrict-prototypes" - -cd kernel -as -c -o boot.o boot.S -as -c -o core386.o core386.S -cc -c -o main.o main.c -cc -c -o init.o init.c -cc -c -o gdt.o gdt.c -cc -c -o idt.o idt.c -cc -c -o syscalls.o syscalls.c -cc -c -o pic.o pic.c -cc -c -o pit.o pit.c -cc -c -o irq.o irq.c -cc -c -o traps.o traps.c -cc -c -o cpu.o cpu.c -cc -c -o cmos.o cmos.c -cc -c -o timer.o timer.c -cc -c -o sched.o sched.c -cc -c -o sleep.o sleep.c -cc -c -o signal.o signal.c -cc -c -o process.o process.c -cc -c -o multiboot.o multiboot.c - -cd syscalls -cc -c -o umount.o umount.c -cc -c -o getgid.o getgid.c -cc -c -o getppid.o getppid.c -cc -c -o fstatfs.o fstatfs.c -cc -c -o getgroups.o getgroups.c -cc -c -o fsync.o fsync.c -cc -c -o setreuid.o setreuid.c -cc -c -o newuname.o newuname.c -cc -c -o fork.o fork.c -cc -c -o setitimer.o setitimer.c -cc -c -o fdatasync.o fdatasync.c -cc -c -o chmod.o chmod.c -cc -c -o mmap2.o mmap2.c -cc -c -o msgsnd.o msgsnd.c -cc -c -o madvise.o madvise.c -cc -c -o exit.o exit.c -cc -c -o readlink.o readlink.c -cc -c -o socketcall.o socketcall.c -cc -c -o stat64.o stat64.c -cc -c -o readv.o readv.c -cc -c -o sigaction.o sigaction.c -cc -c -o fstat.o fstat.c -cc -c -o waitpid.o waitpid.c -cc -c -o setfsgid.o setfsgid.c -cc -c -o chown.o chown.c -cc -c -o flock.o flock.c -cc -c -o uname.o uname.c -cc -c -o lseek.o lseek.c -cc -c -o setsid.o setsid.c -cc -c -o settimeofday.o settimeofday.c -cc -c -o unlink.o unlink.c -cc -c -o sigprocmask.o sigprocmask.c -cc -c -o ustat.o ustat.c -cc -c -o open.o open.c -cc -c -o sync.o sync.c -cc -c -o iopl.o iopl.c -cc -c -o msgget.o msgget.c -cc -c -o pipe.o pipe.c -cc -c -o shmdt.o shmdt.c -cc -c -o getsid.o getsid.c -cc -c -o setfsuid.o setfsuid.c -cc -c -o signal.o signal.c -cc -c -o newfstat.o newfstat.c -cc -c -o mkdir.o mkdir.c -cc -c -o getcwd.o getcwd.c -cc -c -o link.o link.c -cc -c -o msgctl.o msgctl.c -cc -c -o sethostname.o sethostname.c -cc -c -o semctl.o semctl.c -cc -c -o sysinfo.o sysinfo.c -cc -c -o setdomainname.o setdomainname.c -cc -c -o getegid.o getegid.c -cc -c -o personality.o personality.c -cc -c -o setregid.o setregid.c -cc -c -o setgid.o setgid.c -cc -c -o lstat.o lstat.c -cc -c -o getuid.o getuid.c -cc -c -o llseek.o llseek.c -cc -c -o select.o select.c -cc -c -o ftruncate.o ftruncate.c -cc -c -o getpgid.o getpgid.c -cc -c -o brk.o brk.c -cc -c -o getrusage.o getrusage.c -cc -c -o sigsuspend.o sigsuspend.c -cc -c -o writev.o writev.c -cc -c -o times.o times.c -cc -c -o ssetmask.o ssetmask.c -cc -c -o stat.o stat.c -cc -c -o fchdir.o fchdir.c -cc -c -o chdir.o chdir.c -cc -c -o setgroups.o setgroups.c -cc -c -o newstat.o newstat.c -cc -c -o creat.o creat.c -cc -c -o getdents64.o getdents64.c -cc -c -o getpid.o getpid.c -cc -c -o read.o read.c -cc -c -o dup.o dup.c -cc -c -o utimes.o utimes.c -cc -c -o semget.o semget.c -cc -c -o mount.o mount.c -cc -c -o rmdir.o rmdir.c -cc -c -o setrlimit.o setrlimit.c -cc -c -o sgetmask.o sgetmask.c -cc -c -o pause.o pause.c -cc -c -o utime.o utime.c -cc -c -o statfs.o statfs.c -cc -c -o ioperm.o ioperm.c -cc -c -o exit_group.o exit_group.c -cc -c -o ftime.o ftime.c -cc -c -o truncate.o truncate.c -cc -c -o pipe2.o pipe2.c -cc -c -o old_mmap.o old_mmap.c -cc -c -o olduname.o olduname.c -cc -c -o kill.o kill.c -cc -c -o gettimeofday.o gettimeofday.c -cc -c -o fchmod.o fchmod.c -cc -c -o fcntl64.o fcntl64.c -cc -c -o mprotect.o mprotect.c -cc -c -o getitimer.o getitimer.c -cc -c -o old_select.o old_select.c -cc -c -o symlink.o symlink.c -cc -c -o mknod.o mknod.c -cc -c -o write.o write.c -cc -c -o rename.o rename.c -cc -c -o shmat.o shmat.c -cc -c -o ipc.o ipc.c -cc -c -o lstat64.o lstat64.c -cc -c -o access.o access.c -cc -c -o getrlimit.o getrlimit.c -cc -c -o sigreturn.o sigreturn.c -cc -c -o ioctl.o ioctl.c -cc -c -o umask.o umask.c -cc -c -o geteuid.o geteuid.c -cc -c -o munmap.o munmap.c -cc -c -o alarm.o alarm.c -cc -c -o nanosleep.o nanosleep.c -cc -c -o close.o close.c -cc -c -o chroot.o chroot.c -cc -c -o ftruncate64.o ftruncate64.c -cc -c -o msgrcv.o msgrcv.c -cc -c -o umount2.o umount2.c -cc -c -o time.o time.c -cc -c -o stime.o stime.c -cc -c -o semop.o semop.c -cc -c -o newlstat.o newlstat.c -cc -c -o sigpending.o sigpending.c -cc -c -o reboot.o reboot.c -cc -c -o setuid.o setuid.c -cc -c -o wait4.o wait4.c -cc -c -o chown32.o chown32.c -cc -c -o fcntl.o fcntl.c -cc -c -o fstat64.o fstat64.c -cc -c -o shmctl.o shmctl.c -cc -c -o dup2.o dup2.c -cc -c -o setpgid.o setpgid.c -cc -c -o getdents.o getdents.c -cc -c -o getpgrp.o getpgrp.c -cc -c -o fchown.o fchown.c -cc -c -o execve.o execve.c -cc -c -o shmget.o shmget.c -cd ../.. - -cd mm -cc -c -o bios_map.o bios_map.c -cc -c -o buddy_low.o buddy_low.c -cc -c -o memory.o memory.c -cc -c -o page.o page.c -cc -c -o alloc.o alloc.c -cc -c -o fault.o fault.c -cc -c -o mmap.o mmap.c -cc -c -o swapper.o swapper.c -cd .. - -cd fs -cc -c -o filesystems.o filesystems.c -cc -c -o devices.o devices.c -cc -c -o buffer.o buffer.c -cc -c -o fd.o fd.c -cc -c -o locks.o locks.c -cc -c -o super.o super.c -cc -c -o inode.o inode.c -cc -c -o namei.o namei.c -cc -c -o elf.o elf.c -cc -c -o script.o script.c - -cd minix -cc -c -o super.o super.c -cc -c -o bitmaps.o bitmaps.c -cc -c -o inode.o inode.c -cc -c -o namei.o namei.c -cc -c -o symlink.o symlink.c -cc -c -o dir.o dir.c -cc -c -o file.o file.c -cc -c -o v1_inode.o v1_inode.c -cc -c -o v2_inode.o v2_inode.c -cd .. - -cd ext2 -cc -c -o inode.o inode.c -cc -c -o super.o super.c -cc -c -o namei.o namei.c -cc -c -o symlink.o symlink.c -cc -c -o dir.o dir.c -cc -c -o file.o file.c -cc -c -o bitmaps.o bitmaps.c -cd .. - -cd pipefs -cc -c -o super.o super.c -cc -c -o fifo.o fifo.c -cc -c -o pipe.o pipe.c -cd .. - -cd iso9660 -cc -c -o inode.o inode.c -cc -c -o super.o super.c -cc -c -o namei.o namei.c -cc -c -o dir.o dir.c -cc -c -o file.o file.c -cc -c -o rrip.o rrip.c -cc -c -o symlink.o symlink.c -cd .. - -cd procfs -cc -c -o super.o super.c -cc -c -o inode.o inode.c -cc -c -o namei.o namei.c -cc -c -o dir.o dir.c -cc -c -o file.o file.c -cc -c -o symlink.o symlink.c -cc -c -o tree.o tree.c -cc -c -o data.o data.c -cd ../.. - -cd drivers/char -cc -c -o console.o console.c -cc -c -o tty.o tty.c -cc -c -o tty_queue.o tty_queue.c -cc -c -o vt.o vt.c -cc -c -o defkeymap.o defkeymap.c -cc -c -o keyboard.o keyboard.c -cc -c -o memdev.o memdev.c -cc -c -o serial.o serial.c -cc -c -o lp.o lp.c -cc -c -o fb.o fb.c -cc -c -o sysrq.o sysrq.c -cd .. - -cd block -cc -c -o dma.o dma.c -cc -c -o floppy.o floppy.c -cc -c -o part.o part.c -cc -c -o ata.o ata.c -cc -c -o ata_hd.o ata_hd.c -cc -c -o atapi.o atapi.c -cc -c -o atapi_cd.o atapi_cd.c -cc -c -o ramdisk.o ramdisk.c -cd .. - -cd pci -cc -c -o pci.o pci.c -cd .. - -cd video -cc -c -o video.o video.c -cc -c -o vgacon.o vgacon.c -cc -c -o fbcon.o fbcon.c -cc -c -o fonts.o fonts.c -cc -c -o bga.o bga.c -cd ../.. - -cd lib -cc -c -o ctype.o ctype.c -cc -c -o strings.o strings.c -cc -c -o printk.o printk.c -cd .. - -mkdir /boot -tcc -m32 -Wl,-Ttext=0xC0100000 -static -nostdlib -nostdinc \ - kernel/boot.o \ - kernel/core386.o \ - kernel/main.o kernel/init.o \ - kernel/gdt.o \ - kernel/idt.o \ - kernel/syscalls.o \ - kernel/pic.o \ - kernel/pit.o \ - kernel/irq.o \ - kernel/traps.o \ - kernel/cpu.o \ - kernel/cmos.o \ - kernel/timer.o \ - kernel/sched.o \ - kernel/sleep.o \ - kernel/signal.o \ - kernel/process.o \ - kernel/multiboot.o \ - kernel/syscalls/umount.o \ - kernel/syscalls/getgid.o \ - kernel/syscalls/getppid.o \ - kernel/syscalls/fstatfs.o \ - kernel/syscalls/getgroups.o \ - kernel/syscalls/fsync.o \ - kernel/syscalls/setreuid.o \ - kernel/syscalls/newuname.o \ - kernel/syscalls/fork.o \ - kernel/syscalls/setitimer.o \ - kernel/syscalls/fdatasync.o \ - kernel/syscalls/chmod.o \ - kernel/syscalls/mmap2.o \ - kernel/syscalls/msgsnd.o \ - kernel/syscalls/madvise.o \ - kernel/syscalls/exit.o \ - kernel/syscalls/readlink.o \ - kernel/syscalls/socketcall.o \ - kernel/syscalls/stat64.o \ - kernel/syscalls/readv.o \ - kernel/syscalls/sigaction.o \ - kernel/syscalls/fstat.o \ - kernel/syscalls/waitpid.o \ - kernel/syscalls/setfsgid.o \ - kernel/syscalls/chown.o \ - kernel/syscalls/flock.o \ - kernel/syscalls/uname.o \ - kernel/syscalls/lseek.o \ - kernel/syscalls/setsid.o \ - kernel/syscalls/settimeofday.o \ - kernel/syscalls/unlink.o \ - kernel/syscalls/sigprocmask.o \ - kernel/syscalls/ustat.o \ - kernel/syscalls/open.o \ - kernel/syscalls/sync.o \ - kernel/syscalls/iopl.o \ - kernel/syscalls/msgget.o \ - kernel/syscalls/pipe.o \ - kernel/syscalls/shmdt.o \ - kernel/syscalls/getsid.o \ - kernel/syscalls/setfsuid.o \ - kernel/syscalls/signal.o \ - kernel/syscalls/newfstat.o \ - kernel/syscalls/mkdir.o \ - kernel/syscalls/getcwd.o \ - kernel/syscalls/link.o \ - kernel/syscalls/msgctl.o \ - kernel/syscalls/sethostname.o \ - kernel/syscalls/semctl.o \ - kernel/syscalls/sysinfo.o \ - kernel/syscalls/setdomainname.o \ - kernel/syscalls/getegid.o \ - kernel/syscalls/personality.o \ - kernel/syscalls/setregid.o \ - kernel/syscalls/setgid.o \ - kernel/syscalls/lstat.o \ - kernel/syscalls/getuid.o \ - kernel/syscalls/llseek.o \ - kernel/syscalls/select.o \ - kernel/syscalls/ftruncate.o \ - kernel/syscalls/getpgid.o \ - kernel/syscalls/brk.o \ - kernel/syscalls/getrusage.o \ - kernel/syscalls/sigsuspend.o \ - kernel/syscalls/writev.o \ - kernel/syscalls/times.o \ - kernel/syscalls/ssetmask.o \ - kernel/syscalls/stat.o \ - kernel/syscalls/fchdir.o \ - kernel/syscalls/chdir.o \ - kernel/syscalls/setgroups.o \ - kernel/syscalls/newstat.o \ - kernel/syscalls/creat.o \ - kernel/syscalls/getdents64.o \ - kernel/syscalls/getpid.o \ - kernel/syscalls/read.o \ - kernel/syscalls/dup.o \ - kernel/syscalls/utimes.o \ - kernel/syscalls/semget.o \ - kernel/syscalls/mount.o \ - kernel/syscalls/rmdir.o \ - kernel/syscalls/setrlimit.o \ - kernel/syscalls/sgetmask.o \ - kernel/syscalls/pause.o \ - kernel/syscalls/utime.o \ - kernel/syscalls/statfs.o \ - kernel/syscalls/ioperm.o \ - kernel/syscalls/exit_group.o \ - kernel/syscalls/ftime.o \ - kernel/syscalls/truncate.o \ - kernel/syscalls/pipe2.o \ - kernel/syscalls/old_mmap.o \ - kernel/syscalls/olduname.o \ - kernel/syscalls/kill.o \ - kernel/syscalls/gettimeofday.o \ - kernel/syscalls/fchmod.o \ - kernel/syscalls/fcntl64.o \ - kernel/syscalls/mprotect.o \ - kernel/syscalls/getitimer.o \ - kernel/syscalls/old_select.o \ - kernel/syscalls/symlink.o \ - kernel/syscalls/mknod.o \ - kernel/syscalls/write.o \ - kernel/syscalls/rename.o \ - kernel/syscalls/shmat.o \ - kernel/syscalls/ipc.o \ - kernel/syscalls/lstat64.o \ - kernel/syscalls/access.o \ - kernel/syscalls/getrlimit.o \ - kernel/syscalls/sigreturn.o \ - kernel/syscalls/ioctl.o \ - kernel/syscalls/umask.o \ - kernel/syscalls/geteuid.o \ - kernel/syscalls/munmap.o \ - kernel/syscalls/alarm.o \ - kernel/syscalls/nanosleep.o \ - kernel/syscalls/close.o \ - kernel/syscalls/chroot.o \ - kernel/syscalls/ftruncate64.o \ - kernel/syscalls/msgrcv.o \ - kernel/syscalls/umount2.o \ - kernel/syscalls/time.o \ - kernel/syscalls/stime.o \ - kernel/syscalls/semop.o \ - kernel/syscalls/newlstat.o \ - kernel/syscalls/sigpending.o \ - kernel/syscalls/reboot.o \ - kernel/syscalls/setuid.o \ - kernel/syscalls/wait4.o \ - kernel/syscalls/chown32.o \ - kernel/syscalls/fcntl.o \ - kernel/syscalls/fstat64.o \ - kernel/syscalls/shmctl.o \ - kernel/syscalls/dup2.o \ - kernel/syscalls/setpgid.o \ - kernel/syscalls/getdents.o \ - kernel/syscalls/getpgrp.o \ - kernel/syscalls/fchown.o \ - kernel/syscalls/execve.o \ - kernel/syscalls/shmget.o \ - mm/bios_map.o \ - mm/buddy_low.o \ - mm/memory.o \ - mm/page.o \ - mm/alloc.o \ - mm/fault.o \ - mm/mmap.o \ - mm/swapper.o \ - fs/filesystems.o \ - fs/devices.o \ - fs/buffer.o \ - fs/fd.o \ - fs/locks.o \ - fs/super.o \ - fs/inode.o \ - fs/namei.o \ - fs/elf.o \ - fs/script.o \ - fs/minix/super.o \ - fs/minix/bitmaps.o \ - fs/minix/inode.o \ - fs/minix/namei.o \ - fs/minix/symlink.o \ - fs/minix/dir.o \ - fs/minix/file.o \ - fs/minix/v1_inode.o \ - fs/minix/v2_inode.o \ - fs/ext2/inode.o \ - fs/ext2/super.o \ - fs/ext2/namei.o \ - fs/ext2/symlink.o \ - fs/ext2/dir.o \ - fs/ext2/file.o \ - fs/ext2/bitmaps.o \ - fs/pipefs/super.o \ - fs/pipefs/fifo.o \ - fs/pipefs/pipe.o \ - fs/iso9660/inode.o \ - fs/iso9660/super.o \ - fs/iso9660/namei.o \ - fs/iso9660/dir.o \ - fs/iso9660/file.o \ - fs/iso9660/rrip.o \ - fs/iso9660/symlink.o \ - fs/procfs/super.o \ - fs/procfs/inode.o \ - fs/procfs/namei.o \ - fs/procfs/dir.o \ - fs/procfs/file.o \ - fs/procfs/symlink.o \ - fs/procfs/tree.o \ - fs/procfs/data.o \ - drivers/char/console.o \ - drivers/char/tty.o \ - drivers/char/tty_queue.o \ - drivers/char/vt.o \ - drivers/char/defkeymap.o \ - drivers/char/keyboard.o \ - drivers/char/memdev.o \ - drivers/char/serial.o \ - drivers/char/lp.o \ - drivers/char/fb.o \ - drivers/char/sysrq.o \ - drivers/block/dma.o \ - drivers/block/floppy.o \ - drivers/block/part.o \ - drivers/block/ata.o \ - drivers/block/ata_hd.o \ - drivers/block/atapi.o \ - drivers/block/atapi_cd.o \ - drivers/block/ramdisk.o \ - drivers/pci/pci.o \ - drivers/video/video.o \ - drivers/video/vgacon.o \ - drivers/video/fbcon.o \ - drivers/video/fonts.o \ - drivers/video/bga.o \ - lib/ctype.o \ - lib/strings.o \ - lib/printk.o \ - -o /boot/fiwix - -cd ../.. - -# Checksums -if match x${UPDATE_CHECKSUMS} xTrue; then - sha256sum -o ${pkg}.checksums \ - /boot/fiwix - - cp ${pkg}.checksums ${srcdir} -else - sha256sum -c ${pkg}.checksums -fi diff --git a/sysa/fiwix-1.4.0-lb1/sources b/sysa/fiwix-1.4.0-lb1/sources @@ -1 +0,0 @@ -https://github.com/rick-masters/Fiwix/releases/download/v1.4.0-lb1/fiwix-1.4.0-lb1.tar.gz ff57d1fbf0547a27dec4d7146eb9c17d01158ca5886de54e5b9bac2bec473ef3 diff --git a/sysa/fiwix-1.4.0-lb2/fiwix-1.4.0-lb2.checksums b/sysa/fiwix-1.4.0-lb2/fiwix-1.4.0-lb2.checksums @@ -0,0 +1 @@ +0de298be5c0b00654ddb226c2e657d4fdd2fa0c613ffb3bb32c23c65d2257bf0 /boot/fiwix diff --git a/sysa/fiwix-1.4.0-lb2/fiwix-1.4.0-lb2.kaem b/sysa/fiwix-1.4.0-lb2/fiwix-1.4.0-lb2.kaem @@ -0,0 +1,560 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> +# SPDX-License-Identifier: MIT + +set -ex + +# Check tarball checksums +checksum-transcriber sources +sha256sum -c sources.SHA256SUM + +# Extract +mkdir build src +cd src +ungz --file ${distfiles}/${pkg}.tar.gz --output ${pkg}.tar +cd .. + +cd build +untar --file ../src/${pkg}.tar +cd ${pkg} + +alias as="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DCONFIG_KEXEC -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -traditional -I/sysa/fiwix-1.4.0-lb2/build/fiwix-1.4.0-lb2/include" + +alias cc="tcc -m32 -march=i386 -std=c89 -D__KERNEL__ -DMAX_PID_VALUE=64000000 -DCONFIG_MMAP2 -DCONFIG_64BIT_SYSCALLS -DCONFIG_KEXEC -DNR_PROCS=4096 -DCHILD_MAX=4096 -DOPEN_MAX=1536 -DNR_OPENS=1536 -DINIT_PROGRAM=\"/init\" -DUTS_SYSNAME=\"Linux\" -D__VERSION__=\"tcc\" -I/sysa/fiwix-1.4.0-lb2/build/fiwix-1.4.0-lb2/include -O2 -fno-pie -fno-common -ffreestanding -Wall -Wstrict-prototypes" + +cd kernel +as -c -o boot.o boot.S +as -c -o core386.o core386.S +cc -c -o main.o main.c +cc -c -o init.o init.c +cc -c -o gdt.o gdt.c +cc -c -o idt.o idt.c +cc -c -o syscalls.o syscalls.c +cc -c -o pic.o pic.c +cc -c -o pit.o pit.c +cc -c -o irq.o irq.c +cc -c -o traps.o traps.c +cc -c -o cpu.o cpu.c +cc -c -o cmos.o cmos.c +cc -c -o timer.o timer.c +cc -c -o sched.o sched.c +cc -c -o sleep.o sleep.c +cc -c -o signal.o signal.c +cc -c -o process.o process.c +cc -c -o multiboot.o multiboot.c +cc -c -o kexec.o kexec.c + +cd syscalls +cc -c -o umount.o umount.c +cc -c -o getgid.o getgid.c +cc -c -o getppid.o getppid.c +cc -c -o fstatfs.o fstatfs.c +cc -c -o getgroups.o getgroups.c +cc -c -o fsync.o fsync.c +cc -c -o setreuid.o setreuid.c +cc -c -o newuname.o newuname.c +cc -c -o fork.o fork.c +cc -c -o setitimer.o setitimer.c +cc -c -o fdatasync.o fdatasync.c +cc -c -o chmod.o chmod.c +cc -c -o mmap2.o mmap2.c +cc -c -o msgsnd.o msgsnd.c +cc -c -o madvise.o madvise.c +cc -c -o exit.o exit.c +cc -c -o readlink.o readlink.c +cc -c -o socketcall.o socketcall.c +cc -c -o stat64.o stat64.c +cc -c -o readv.o readv.c +cc -c -o sigaction.o sigaction.c +cc -c -o fstat.o fstat.c +cc -c -o waitpid.o waitpid.c +cc -c -o setfsgid.o setfsgid.c +cc -c -o chown.o chown.c +cc -c -o flock.o flock.c +cc -c -o uname.o uname.c +cc -c -o lseek.o lseek.c +cc -c -o setsid.o setsid.c +cc -c -o settimeofday.o settimeofday.c +cc -c -o unlink.o unlink.c +cc -c -o sigprocmask.o sigprocmask.c +cc -c -o ustat.o ustat.c +cc -c -o open.o open.c +cc -c -o sync.o sync.c +cc -c -o iopl.o iopl.c +cc -c -o msgget.o msgget.c +cc -c -o pipe.o pipe.c +cc -c -o shmdt.o shmdt.c +cc -c -o getsid.o getsid.c +cc -c -o setfsuid.o setfsuid.c +cc -c -o signal.o signal.c +cc -c -o newfstat.o newfstat.c +cc -c -o mkdir.o mkdir.c +cc -c -o getcwd.o getcwd.c +cc -c -o link.o link.c +cc -c -o msgctl.o msgctl.c +cc -c -o sethostname.o sethostname.c +cc -c -o semctl.o semctl.c +cc -c -o sysinfo.o sysinfo.c +cc -c -o setdomainname.o setdomainname.c +cc -c -o getegid.o getegid.c +cc -c -o personality.o personality.c +cc -c -o setregid.o setregid.c +cc -c -o setgid.o setgid.c +cc -c -o lstat.o lstat.c +cc -c -o getuid.o getuid.c +cc -c -o llseek.o llseek.c +cc -c -o select.o select.c +cc -c -o ftruncate.o ftruncate.c +cc -c -o getpgid.o getpgid.c +cc -c -o brk.o brk.c +cc -c -o getrusage.o getrusage.c +cc -c -o sigsuspend.o sigsuspend.c +cc -c -o writev.o writev.c +cc -c -o times.o times.c +cc -c -o ssetmask.o ssetmask.c +cc -c -o stat.o stat.c +cc -c -o fchdir.o fchdir.c +cc -c -o chdir.o chdir.c +cc -c -o setgroups.o setgroups.c +cc -c -o newstat.o newstat.c +cc -c -o creat.o creat.c +cc -c -o getdents64.o getdents64.c +cc -c -o getpid.o getpid.c +cc -c -o read.o read.c +cc -c -o dup.o dup.c +cc -c -o utimes.o utimes.c +cc -c -o semget.o semget.c +cc -c -o mount.o mount.c +cc -c -o rmdir.o rmdir.c +cc -c -o setrlimit.o setrlimit.c +cc -c -o sgetmask.o sgetmask.c +cc -c -o pause.o pause.c +cc -c -o utime.o utime.c +cc -c -o statfs.o statfs.c +cc -c -o ioperm.o ioperm.c +cc -c -o exit_group.o exit_group.c +cc -c -o ftime.o ftime.c +cc -c -o truncate.o truncate.c +cc -c -o pipe2.o pipe2.c +cc -c -o old_mmap.o old_mmap.c +cc -c -o olduname.o olduname.c +cc -c -o kill.o kill.c +cc -c -o gettimeofday.o gettimeofday.c +cc -c -o fchmod.o fchmod.c +cc -c -o fcntl64.o fcntl64.c +cc -c -o mprotect.o mprotect.c +cc -c -o getitimer.o getitimer.c +cc -c -o old_select.o old_select.c +cc -c -o symlink.o symlink.c +cc -c -o mknod.o mknod.c +cc -c -o write.o write.c +cc -c -o rename.o rename.c +cc -c -o shmat.o shmat.c +cc -c -o ipc.o ipc.c +cc -c -o lstat64.o lstat64.c +cc -c -o access.o access.c +cc -c -o getrlimit.o getrlimit.c +cc -c -o sigreturn.o sigreturn.c +cc -c -o ioctl.o ioctl.c +cc -c -o umask.o umask.c +cc -c -o geteuid.o geteuid.c +cc -c -o munmap.o munmap.c +cc -c -o alarm.o alarm.c +cc -c -o nanosleep.o nanosleep.c +cc -c -o close.o close.c +cc -c -o chroot.o chroot.c +cc -c -o ftruncate64.o ftruncate64.c +cc -c -o msgrcv.o msgrcv.c +cc -c -o umount2.o umount2.c +cc -c -o time.o time.c +cc -c -o stime.o stime.c +cc -c -o semop.o semop.c +cc -c -o newlstat.o newlstat.c +cc -c -o sigpending.o sigpending.c +cc -c -o reboot.o reboot.c +cc -c -o setuid.o setuid.c +cc -c -o wait4.o wait4.c +cc -c -o chown32.o chown32.c +cc -c -o fcntl.o fcntl.c +cc -c -o fstat64.o fstat64.c +cc -c -o shmctl.o shmctl.c +cc -c -o dup2.o dup2.c +cc -c -o setpgid.o setpgid.c +cc -c -o getdents.o getdents.c +cc -c -o getpgrp.o getpgrp.c +cc -c -o fchown.o fchown.c +cc -c -o execve.o execve.c +cc -c -o shmget.o shmget.c +cd ../.. + +cd mm +cc -c -o bios_map.o bios_map.c +cc -c -o buddy_low.o buddy_low.c +cc -c -o memory.o memory.c +cc -c -o page.o page.c +cc -c -o alloc.o alloc.c +cc -c -o fault.o fault.c +cc -c -o mmap.o mmap.c +cc -c -o swapper.o swapper.c +cd .. + +cd fs +cc -c -o filesystems.o filesystems.c +cc -c -o devices.o devices.c +cc -c -o buffer.o buffer.c +cc -c -o fd.o fd.c +cc -c -o locks.o locks.c +cc -c -o super.o super.c +cc -c -o inode.o inode.c +cc -c -o namei.o namei.c +cc -c -o elf.o elf.c +cc -c -o script.o script.c + +cd minix +cc -c -o super.o super.c +cc -c -o bitmaps.o bitmaps.c +cc -c -o inode.o inode.c +cc -c -o namei.o namei.c +cc -c -o symlink.o symlink.c +cc -c -o dir.o dir.c +cc -c -o file.o file.c +cc -c -o v1_inode.o v1_inode.c +cc -c -o v2_inode.o v2_inode.c +cd .. + +cd ext2 +cc -c -o inode.o inode.c +cc -c -o super.o super.c +cc -c -o namei.o namei.c +cc -c -o symlink.o symlink.c +cc -c -o dir.o dir.c +cc -c -o file.o file.c +cc -c -o bitmaps.o bitmaps.c +cd .. + +cd pipefs +cc -c -o super.o super.c +cc -c -o fifo.o fifo.c +cc -c -o pipe.o pipe.c +cd .. + +cd iso9660 +cc -c -o inode.o inode.c +cc -c -o super.o super.c +cc -c -o namei.o namei.c +cc -c -o dir.o dir.c +cc -c -o file.o file.c +cc -c -o rrip.o rrip.c +cc -c -o symlink.o symlink.c +cd .. + +cd procfs +cc -c -o super.o super.c +cc -c -o inode.o inode.c +cc -c -o namei.o namei.c +cc -c -o dir.o dir.c +cc -c -o file.o file.c +cc -c -o symlink.o symlink.c +cc -c -o tree.o tree.c +cc -c -o data.o data.c +cd ../.. + +cd drivers/char +cc -c -o console.o console.c +cc -c -o tty.o tty.c +cc -c -o tty_queue.o tty_queue.c +cc -c -o vt.o vt.c +cc -c -o defkeymap.o defkeymap.c +cc -c -o keyboard.o keyboard.c +cc -c -o memdev.o memdev.c +cc -c -o serial.o serial.c +cc -c -o lp.o lp.c +cc -c -o fb.o fb.c +cc -c -o sysrq.o sysrq.c +cd .. + +cd block +cc -c -o dma.o dma.c +cc -c -o floppy.o floppy.c +cc -c -o part.o part.c +cc -c -o ata.o ata.c +cc -c -o ata_hd.o ata_hd.c +cc -c -o ata_pci.o ata_pci.c +cc -c -o atapi.o atapi.c +cc -c -o atapi_cd.o atapi_cd.c +cc -c -o ramdisk.o ramdisk.c +cd .. + +cd pci +cc -c -o pci.o pci.c +cd .. + +cd video +cc -c -o video.o video.c +cc -c -o vgacon.o vgacon.c +cc -c -o fbcon.o fbcon.c +cc -c -o fonts.o fonts.c +cc -c -o bga.o bga.c +cd ../.. + +cd lib +cc -c -o ctype.o ctype.c +cc -c -o strings.o strings.c +cc -c -o printk.o printk.c +cd .. + +mkdir /boot +tcc -m32 -Wl,-Ttext=0xC0100000 -static -nostdlib -nostdinc \ + kernel/boot.o \ + kernel/core386.o \ + kernel/main.o kernel/init.o \ + kernel/gdt.o \ + kernel/idt.o \ + kernel/syscalls.o \ + kernel/pic.o \ + kernel/pit.o \ + kernel/irq.o \ + kernel/traps.o \ + kernel/cpu.o \ + kernel/cmos.o \ + kernel/timer.o \ + kernel/sched.o \ + kernel/sleep.o \ + kernel/signal.o \ + kernel/process.o \ + kernel/multiboot.o \ + kernel/kexec.o \ + kernel/syscalls/umount.o \ + kernel/syscalls/getgid.o \ + kernel/syscalls/getppid.o \ + kernel/syscalls/fstatfs.o \ + kernel/syscalls/getgroups.o \ + kernel/syscalls/fsync.o \ + kernel/syscalls/setreuid.o \ + kernel/syscalls/newuname.o \ + kernel/syscalls/fork.o \ + kernel/syscalls/setitimer.o \ + kernel/syscalls/fdatasync.o \ + kernel/syscalls/chmod.o \ + kernel/syscalls/mmap2.o \ + kernel/syscalls/msgsnd.o \ + kernel/syscalls/madvise.o \ + kernel/syscalls/exit.o \ + kernel/syscalls/readlink.o \ + kernel/syscalls/socketcall.o \ + kernel/syscalls/stat64.o \ + kernel/syscalls/readv.o \ + kernel/syscalls/sigaction.o \ + kernel/syscalls/fstat.o \ + kernel/syscalls/waitpid.o \ + kernel/syscalls/setfsgid.o \ + kernel/syscalls/chown.o \ + kernel/syscalls/flock.o \ + kernel/syscalls/uname.o \ + kernel/syscalls/lseek.o \ + kernel/syscalls/setsid.o \ + kernel/syscalls/settimeofday.o \ + kernel/syscalls/unlink.o \ + kernel/syscalls/sigprocmask.o \ + kernel/syscalls/ustat.o \ + kernel/syscalls/open.o \ + kernel/syscalls/sync.o \ + kernel/syscalls/iopl.o \ + kernel/syscalls/msgget.o \ + kernel/syscalls/pipe.o \ + kernel/syscalls/shmdt.o \ + kernel/syscalls/getsid.o \ + kernel/syscalls/setfsuid.o \ + kernel/syscalls/signal.o \ + kernel/syscalls/newfstat.o \ + kernel/syscalls/mkdir.o \ + kernel/syscalls/getcwd.o \ + kernel/syscalls/link.o \ + kernel/syscalls/msgctl.o \ + kernel/syscalls/sethostname.o \ + kernel/syscalls/semctl.o \ + kernel/syscalls/sysinfo.o \ + kernel/syscalls/setdomainname.o \ + kernel/syscalls/getegid.o \ + kernel/syscalls/personality.o \ + kernel/syscalls/setregid.o \ + kernel/syscalls/setgid.o \ + kernel/syscalls/lstat.o \ + kernel/syscalls/getuid.o \ + kernel/syscalls/llseek.o \ + kernel/syscalls/select.o \ + kernel/syscalls/ftruncate.o \ + kernel/syscalls/getpgid.o \ + kernel/syscalls/brk.o \ + kernel/syscalls/getrusage.o \ + kernel/syscalls/sigsuspend.o \ + kernel/syscalls/writev.o \ + kernel/syscalls/times.o \ + kernel/syscalls/ssetmask.o \ + kernel/syscalls/stat.o \ + kernel/syscalls/fchdir.o \ + kernel/syscalls/chdir.o \ + kernel/syscalls/setgroups.o \ + kernel/syscalls/newstat.o \ + kernel/syscalls/creat.o \ + kernel/syscalls/getdents64.o \ + kernel/syscalls/getpid.o \ + kernel/syscalls/read.o \ + kernel/syscalls/dup.o \ + kernel/syscalls/utimes.o \ + kernel/syscalls/semget.o \ + kernel/syscalls/mount.o \ + kernel/syscalls/rmdir.o \ + kernel/syscalls/setrlimit.o \ + kernel/syscalls/sgetmask.o \ + kernel/syscalls/pause.o \ + kernel/syscalls/utime.o \ + kernel/syscalls/statfs.o \ + kernel/syscalls/ioperm.o \ + kernel/syscalls/exit_group.o \ + kernel/syscalls/ftime.o \ + kernel/syscalls/truncate.o \ + kernel/syscalls/pipe2.o \ + kernel/syscalls/old_mmap.o \ + kernel/syscalls/olduname.o \ + kernel/syscalls/kill.o \ + kernel/syscalls/gettimeofday.o \ + kernel/syscalls/fchmod.o \ + kernel/syscalls/fcntl64.o \ + kernel/syscalls/mprotect.o \ + kernel/syscalls/getitimer.o \ + kernel/syscalls/old_select.o \ + kernel/syscalls/symlink.o \ + kernel/syscalls/mknod.o \ + kernel/syscalls/write.o \ + kernel/syscalls/rename.o \ + kernel/syscalls/shmat.o \ + kernel/syscalls/ipc.o \ + kernel/syscalls/lstat64.o \ + kernel/syscalls/access.o \ + kernel/syscalls/getrlimit.o \ + kernel/syscalls/sigreturn.o \ + kernel/syscalls/ioctl.o \ + kernel/syscalls/umask.o \ + kernel/syscalls/geteuid.o \ + kernel/syscalls/munmap.o \ + kernel/syscalls/alarm.o \ + kernel/syscalls/nanosleep.o \ + kernel/syscalls/close.o \ + kernel/syscalls/chroot.o \ + kernel/syscalls/ftruncate64.o \ + kernel/syscalls/msgrcv.o \ + kernel/syscalls/umount2.o \ + kernel/syscalls/time.o \ + kernel/syscalls/stime.o \ + kernel/syscalls/semop.o \ + kernel/syscalls/newlstat.o \ + kernel/syscalls/sigpending.o \ + kernel/syscalls/reboot.o \ + kernel/syscalls/setuid.o \ + kernel/syscalls/wait4.o \ + kernel/syscalls/chown32.o \ + kernel/syscalls/fcntl.o \ + kernel/syscalls/fstat64.o \ + kernel/syscalls/shmctl.o \ + kernel/syscalls/dup2.o \ + kernel/syscalls/setpgid.o \ + kernel/syscalls/getdents.o \ + kernel/syscalls/getpgrp.o \ + kernel/syscalls/fchown.o \ + kernel/syscalls/execve.o \ + kernel/syscalls/shmget.o \ + mm/bios_map.o \ + mm/buddy_low.o \ + mm/memory.o \ + mm/page.o \ + mm/alloc.o \ + mm/fault.o \ + mm/mmap.o \ + mm/swapper.o \ + fs/filesystems.o \ + fs/devices.o \ + fs/buffer.o \ + fs/fd.o \ + fs/locks.o \ + fs/super.o \ + fs/inode.o \ + fs/namei.o \ + fs/elf.o \ + fs/script.o \ + fs/minix/super.o \ + fs/minix/bitmaps.o \ + fs/minix/inode.o \ + fs/minix/namei.o \ + fs/minix/symlink.o \ + fs/minix/dir.o \ + fs/minix/file.o \ + fs/minix/v1_inode.o \ + fs/minix/v2_inode.o \ + fs/ext2/inode.o \ + fs/ext2/super.o \ + fs/ext2/namei.o \ + fs/ext2/symlink.o \ + fs/ext2/dir.o \ + fs/ext2/file.o \ + fs/ext2/bitmaps.o \ + fs/pipefs/super.o \ + fs/pipefs/fifo.o \ + fs/pipefs/pipe.o \ + fs/iso9660/inode.o \ + fs/iso9660/super.o \ + fs/iso9660/namei.o \ + fs/iso9660/dir.o \ + fs/iso9660/file.o \ + fs/iso9660/rrip.o \ + fs/iso9660/symlink.o \ + fs/procfs/super.o \ + fs/procfs/inode.o \ + fs/procfs/namei.o \ + fs/procfs/dir.o \ + fs/procfs/file.o \ + fs/procfs/symlink.o \ + fs/procfs/tree.o \ + fs/procfs/data.o \ + drivers/char/console.o \ + drivers/char/tty.o \ + drivers/char/tty_queue.o \ + drivers/char/vt.o \ + drivers/char/defkeymap.o \ + drivers/char/keyboard.o \ + drivers/char/memdev.o \ + drivers/char/serial.o \ + drivers/char/lp.o \ + drivers/char/fb.o \ + drivers/char/sysrq.o \ + drivers/block/dma.o \ + drivers/block/floppy.o \ + drivers/block/part.o \ + drivers/block/ata.o \ + drivers/block/ata_hd.o \ + drivers/block/ata_pci.o \ + drivers/block/atapi.o \ + drivers/block/atapi_cd.o \ + drivers/block/ramdisk.o \ + drivers/pci/pci.o \ + drivers/video/video.o \ + drivers/video/vgacon.o \ + drivers/video/fbcon.o \ + drivers/video/fonts.o \ + drivers/video/bga.o \ + lib/ctype.o \ + lib/strings.o \ + lib/printk.o \ + -o /boot/fiwix + +cd ../.. + +# Checksums +if match x${UPDATE_CHECKSUMS} xTrue; then + sha256sum -o ${pkg}.checksums \ + /boot/fiwix + + cp ${pkg}.checksums ${srcdir} +else + sha256sum -c ${pkg}.checksums +fi diff --git a/sysa/fiwix-1.4.0-lb2/sources b/sysa/fiwix-1.4.0-lb2/sources @@ -0,0 +1 @@ +https://github.com/rick-masters/Fiwix/releases/download/v1.4.0-lb2/fiwix-1.4.0-lb2.tar.gz 44fb14fb666dcf4f5abf7f49eb3f1d92436b9d7353daa23138ff21e9ec78e30f diff --git a/sysa/kexec-fiwix/kexec-fiwix.checksums b/sysa/kexec-fiwix/kexec-fiwix.checksums @@ -1 +1 @@ -afb30f2e80adefc979bdffdb525cf2862897f0beefbb0740fbd05ab3246a32c9 /usr/bin/kexec-fiwix +4f78914aef30b569a531102998e52a0514d8836204d57ff42bf0a3324968f247 /usr/bin/kexec-fiwix diff --git a/sysa/kexec-fiwix/src/kexec-fiwix.c b/sysa/kexec-fiwix/src/kexec-fiwix.c @@ -77,10 +77,10 @@ int main() { puts("Preparing multiboot info for kernel..."); char cmdline[256]; - sprintf(cmdline, "fiwix console=/dev/ttyS0 root=/dev/ram0 ramdisksize=%d initrd=sysa.ext2", INITRD_MB * 1024); + sprintf(cmdline, "fiwix console=/dev/ttyS0 root=/dev/ram0 ramdisksize=%d initrd=sysa.ext2 kexec_proto=linux kexec_size=67000 kexec_cmdline=\"init=/init console=ttyS0\"", INITRD_MB * 1024); char * boot_loader_name = "kexec-fiwix"; - unsigned int next_avail_mem = 0x8000; + unsigned int next_avail_mem = 0x9800; multiboot_info_t * pmultiboot_info = (multiboot_info_t *) next_avail_mem; memset(pmultiboot_info, 0, sizeof(multiboot_info_t)); diff --git a/sysa/kexec-linux-1.0.0/files/kexec-linux.c b/sysa/kexec-linux-1.0.0/files/kexec-linux.c @@ -0,0 +1,82 @@ +/* SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> */ +/* SPDX-License-Identifier: MIT */ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <time.h> + +int append_file(FILE *dst_file, char *src_file_name); + + +int main(int argc, char **argv) { + char *ramdrive_file_name, *kernel_file_name, *initramfs_file_name; + FILE *ramdrive_file; + struct stat stats; + uint32_t size; + + if (argc < 3) { + puts("Usage: fiwix-kexec-linux <ram-drive-name> <kernel-file-name> <initramfs-file-name>"); + exit(1); + } + + ramdrive_file_name = argv[1]; + kernel_file_name = argv[2]; + initramfs_file_name = argv[3]; + + + ramdrive_file = fopen(ramdrive_file_name, "wb"); + + /* Write length of kernel */ + if (stat(kernel_file_name, &stats) == 0) { + size = (uint32_t) stats.st_size; + fwrite(&size, sizeof(size), 1, ramdrive_file); + } else { + fprintf(stderr, "Cannot stat kernel file '%s'\n", kernel_file_name); + exit(1); + } + + /* Write length of initramfs */ + if (stat(initramfs_file_name, &stats) == 0) { + size = (uint32_t) stats.st_size; + fwrite(&size, sizeof(size), 1, ramdrive_file); + } else { + fprintf(stderr, "Cannot stat initramfs file '%s'\n", initramfs_file_name); + exit(1); + } + + if (append_file(ramdrive_file, kernel_file_name)) { + fprintf(stderr, "Cannot append kernel '%s'\n", kernel_file_name); + exit(1); + } + if (append_file(ramdrive_file, initramfs_file_name)) { + fprintf(stderr, "Cannot append initramfs '%s'\n", initramfs_file_name); + exit(1); + } + fclose(ramdrive_file); + + /* Flush ram drive writes to device */ + sync(); + + /* Perform syscall reboot to initiate kexec */ + reboot(RB_HALT_SYSTEM); +} + +int append_file(FILE *dst_file, char *src_file_name) { + FILE *src_file; + char buff[BUFSIZ]; + size_t n; + + if (src_file = fopen(src_file_name, "rb")) { + while ((n = fread(buff, 1, BUFSIZ, src_file)) != 0) { + fwrite(buff, 1, n, dst_file ); + } + fclose(src_file); + return 0; + } else { + printf("Cannot open file '%s'\n", src_file_name); + return 1; + } +} diff --git a/sysa/kexec-linux-1.0.0/kexec-linux-1.0.0.sh b/sysa/kexec-linux-1.0.0/kexec-linux-1.0.0.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> +# SPDX-License-Identifier: MIT +src_get() { + : +} + +src_unpack() { + dirname=kexec-linux-1.0.0 + mkdir ${dirname} +} + +src_install() { + install -D "kexec-linux" "${DESTDIR}${PREFIX}/bin/kexec-linux" +} diff --git a/sysa/kexec-linux-1.0.0/mk/main.mk b/sysa/kexec-linux-1.0.0/mk/main.mk @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com> +# SPDX-License-Identifier: MIT +kexec-linux: kexec-linux.c + gcc -static -m32 -march=i386 -o $@ $^ diff --git a/sysa/lwext4-1.0.0-lb1/files/early-artifacts-needed-after-fiwix.txt b/sysa/lwext4-1.0.0-lb1/files/early-artifacts-needed-after-fiwix.txt @@ -21,6 +21,7 @@ /usr/bin/checksum-transcriber /usr/bin/tcc /usr/bin/tcc-0.9.26 +/usr/bin/kexec-linux /usr/lib/mes/libc.a /usr/lib/mes/libgetopt.a /usr/lib/mes/crt1.o diff --git a/sysa/lwext4-1.0.0-lb1/files/make_fiwix_initrd.c b/sysa/lwext4-1.0.0-lb1/files/make_fiwix_initrd.c @@ -71,7 +71,7 @@ static bool open_filedev(void) file_dev_name_set(input_name); bd = file_dev_get(); if (!bd) { - printf("open_filedev: fail\n"); + puts("open_filedev: fail"); return false; } return true; @@ -85,7 +85,7 @@ bool lwext4_mount(struct ext4_blockdev *bdev, struct ext4_bcache *bcache) bd = bdev; if (!bd) { - printf("lwext4_mount: no block device\n"); + puts("lwext4_mount: no block device"); return false; } @@ -155,21 +155,21 @@ bool copy_file(char *src_path, char *dest_path) err = ext4_fopen(&dest_file, dest_path, "wb"); if (err != EOK) { - printf("ext4_open error: %d \n", err); + printf("ext4_open error: %d\n", err); return EXIT_FAILURE; } if (src_len > 0) { err = ext4_fwrite(&dest_file, src_mem, src_len, 0); if (err != EOK) { - printf("ext4_fwrite error: %d \n", err); + printf("ext4_fwrite error: %d\n", err); return EXIT_FAILURE; } } err = ext4_fclose(&dest_file); if (err != EOK) { - printf("ext4_fclose error: %d \n", err); + printf("ext4_fclose error: %d\n", err); return EXIT_FAILURE; } @@ -226,7 +226,7 @@ int main(int argc, char **argv) err = ext4_mkfs(&fs, bd, &info, F_SET_EXT2_V0); if (err != EOK) { - printf("ext4_mkfs error: %d \n", err); + printf("ext4_mkfs error: %d\n", err); return EXIT_FAILURE; } @@ -255,32 +255,44 @@ int main(int argc, char **argv) if (!lwext4_mount(bd, bc)) return EXIT_FAILURE; - printf("ext4_dir_mk /mp/dev\n"); + puts("ext4_dir_mk /mp/dev"); err = ext4_dir_mk("/mp/dev"); if (err != EOK) { - printf("ext4_dir_mk error: %d \n", err); + printf("ext4_dir_mk error: %d\n", err); } - printf("ext4_mknod /mp/dev/console\n"); + puts("ext4_mknod /mp/dev/console"); err = ext4_mknod("/mp/dev/console", EXT4_DE_CHRDEV, MKDEV(5, 1)); if (err != EOK) { - printf("ext4_mknod error: %d \n", err); + printf("ext4_mknod error: %d\n", err); + return EXIT_FAILURE; + } + puts("ext4_mknod /mp/dev/ram0"); + err = ext4_mknod("/mp/dev/ram0", EXT4_DE_BLKDEV, MKDEV(1, 0)); + if (err != EOK) { + printf("ext4_mknod error: %d\n", err); + return EXIT_FAILURE; + } + puts("ext4_mknod /mp/dev/ram1"); + err = ext4_mknod("/mp/dev/ram1", EXT4_DE_BLKDEV, MKDEV(1, 1)); + if (err != EOK) { + printf("ext4_mknod error: %d\n", err); return EXIT_FAILURE; } copy_file("/usr/bin/kaem", "/mp/init"); copy_file("/sysa/after2.kaem", "/mp/kaem.run"); copy_file_list("/sysa/lwext4-1.0.0-lb1/files/fiwix-file-list.txt"); - printf("ext4_dir_mk /mp/tmp\n"); + puts("ext4_dir_mk /mp/tmp"); ext4_dir_mk("/mp/tmp"); - printf("ext4_dir_mk /mp/usr\n"); + puts("ext4_dir_mk /mp/usr"); ext4_dir_mk("/mp/usr"); - printf("ext4_dir_mk /mp/usr/src\n"); + puts("ext4_dir_mk /mp/usr/src"); ext4_dir_mk("/mp/usr/src"); if (!lwext4_umount()) return EXIT_FAILURE; - printf("Fiwix ext2 initrd created successfully.\n"); + puts("Fiwix ext2 initrd created successfully."); return EXIT_SUCCESS; } diff --git a/sysa/lwext4-1.0.0-lb1/lwext4-1.0.0-lb1.checksums b/sysa/lwext4-1.0.0-lb1/lwext4-1.0.0-lb1.checksums @@ -1 +1 @@ -0a3f0012c01cb5aee0643f1674f265e68b5eeadb37596bcc4fe60aad55c9d3d7 /usr/bin/make_fiwix_initrd +7b65748dd946f1a5266b2e6d0c9cf7143b4722dae0dd4a02b89d6fba9909e2bd /usr/bin/make_fiwix_initrd diff --git a/sysa/run.kaem b/sysa/run.kaem @@ -57,7 +57,7 @@ fi if match x${BUILD_FIWIX} xTrue; then # The Fiwix kernel - pkg="fiwix-1.4.0-lb1" + pkg="fiwix-1.4.0-lb2" cd ${pkg} kaem --verbose --file ${pkg}.kaem cd .. diff --git a/sysa/run2.sh b/sysa/run2.sh @@ -25,16 +25,20 @@ create_sysb() { } go_sysb() { - # Mount proc for kexec - mkdir /proc /etc - mount -t proc proc /proc - # kexec time - echo "Loading kernel + sysb initramfs using kexec" - kexec -l "/boot/linux-4.9.10" --console-serial \ - --initrd="/boot/initramfs-sysb.cpio.gz" \ - --append="init=/init console=ttyS0" - echo "kexecing into sysb" - kexec -e + if [ "${KERNEL_BOOTSTRAP}" = True ]; then + kexec-linux "/dev/ram1" "/boot/linux-4.9.10" "/boot/initramfs-sysb.cpio.gz" + else + # Mount proc for kexec + mkdir /proc /etc + mount -t proc proc /proc + # kexec time + echo "Loading kernel + sysb initramfs using kexec" + kexec -l "/boot/linux-4.9.10" --console-serial \ + --initrd="/boot/initramfs-sysb.cpio.gz" \ + --append="init=/init console=ttyS0" + echo "kexecing into sysb" + kexec -e + fi } build automake-1.15.1 @@ -87,6 +91,8 @@ grep --no-filename '^build' "${SOURCES}"/run*.sh | grep -v musl-1.2.3 | sed "s/b done if [ "${CHROOT}" = False ] || [ "${BUILD_KERNELS}" = True ]; then + build kexec-linux-1.0.0 + build kexec-tools-2.0.22 build linux-4.9.10 @@ -96,12 +102,7 @@ build musl-1.2.3 '' no-patches if [ "${CHROOT}" = False ]; then create_sysb - if [ "${KERNEL_BOOTSTRAP}" = True ]; then - echo "Kernel bootstrapping successful." - echo "NOTE: Transition to Linux and building remaining packages is under development." - else - go_sysb - fi + go_sysb else # In chroot mode transition directly into System C. SYSC=/sysc_image diff --git a/sysb/run.sh b/sysb/run.sh @@ -65,15 +65,15 @@ if [ -z "${DISK}" ] || ! [ -e "/dev/${DISK}" ]; then echo "DISK=${DISK}" >> /usr/src/bootstrap.cfg fi -# Is it a full disk, and not a partition +# Is it a full disk, and not a partition? # shellcheck disable=SC2012 if [ $(($(ls -l "/dev/${DISK}" | sed "s/.*, *//" | sed "s/ .*//") % 8)) -eq 0 ]; then - if ! fdisk -l "/dev/${DISK}" | grep -qE "${DISK}p?[0-9]" ; then - echo "Creating partition table and partition" - echo ";" | sfdisk "/dev/${DISK}" - mkfs.ext4 "/dev/${DISK}1" - DISK="${DISK}1" - fi + echo "Creating partition table..." + echo ";" | sfdisk "/dev/${DISK}" + fdisk -l "/dev/${DISK}" + echo "Creating ext4 partition..." + mkfs.ext4 "/dev/${DISK}1" + DISK="${DISK}1" fi echo "export DISK=${DISK}" >> /usr/src/bootstrap.cfg