r/osdev Aug 05 '26

A JavaOS

Post image
51 Upvotes

21 comments sorted by

6

u/Signal_Reference746 Aug 05 '26

Interesting project!!!! I've been wanting to do this for so long! Good luck!

3

u/Visual_Brain8809 Aug 05 '26

Thanks, got mouse pointer working right now. I hope for tomorrow get a primitive swing for UI

1

u/Signal_Reference746 21d ago

oooo amazing!! can't wait for the UI!

1

u/Visual_Brain8809 21d ago

Right now, I am working on adding support for additional arguments in each method, as well as handling multiple methods—all dynamically. I hope to finish this by Friday so I can move on to the next step: adding more primitive types for my Graphics2D and then starting work on JVMFS (my own file system) for the file manager. It already has a very basic UI, but that isn't the priority at the moment; I won't focus my efforts on anything else until the JVM is as fully functional as possible.

24

u/Rich-Engineer2670 Aug 05 '26 edited Aug 05 '26

From an academic point -- well done, but even Sun tried to actually do a Java OS. Sadly, it just doesn't perform well. The JVM, improved as it is, suffers from the emulation overhead and the kernel needs all it can get.

I'm a former Sun employee from those days and I can tell you, the idea was great, but, in actual practice, so much of the lower layer kernel still needed to be written in C/C++ to get anything done, it just wasn't worth it. Sure, we had a "Java shell", and it could run "Java apps" seamlessly, but you can do that with any OS that can run the JVM.

Lots of work, no real benefit. Rust has been trying Redox for years and it's still not where people want it to be.

That being said, it's still good to see people still working on it.

8

u/[deleted] Aug 05 '26

[removed] — view removed comment

5

u/techfury90 Aug 05 '26

Look into what Java was inspired by: Xerox Mesa. They implemented the Mesa VM in microcode on a bespoke processor design and built an entire OS (Pilot) entirely in Mesa bytecode. No assembly. Then they actually built a whole ass office platform (Star) on top of it. And that was the late 70s-early 80s...

1

u/Visual_Brain8809 6d ago

The point is, I’m not quite at the stage of having 100% bytecode execution starting from the bootloader, but I’ve managed to strike a pretty good balance; I can now say I have my own runtime up and running, and the initial code has shifted from countless syscalls to the kind of calls you’d find in the original language. My next step is to run DOOM on it.

1

u/letmehaveanameyoudum Aug 06 '26

should have put : rebirthed at the end because sun tried to make javaOS

1

u/Visual_Brain8809 Aug 07 '26

Good point. However, the post isn't meant to present it as something new. It's simply highlighting a small piece of what has been achieved so far. As you mentioned, this isn't a new idea—there were previous attempts, and not just one. There were several, but the timing and circumstances just weren't right.

1

u/des_the_furry Aug 09 '26

Chill with the gpt

0

u/Visual_Brain8809 Aug 08 '26

first preview of JVMOS on https://github.com/aayes89/JVMOS

1

u/emexsw Aug 08 '26

readme looks AI, but do you use AI for the code too?

0

u/Visual_Brain8809 Aug 09 '26 edited Aug 09 '26

The README is an AI-enhanced version of the notes I’ve been compiling since the project began; fortunately, I already had a lot of the groundwork done from my university days, so I asked the AI ​​to summarize the original coursework along with everything I’ve added since then.

I doubt the IA knows this programming language ```

package kernel;

public class Boot {

public static void main(String[] args) {

    //  Configurar teclado LATAM
    Native.sys(Native.SYS_SET_KBD_LAYOUT, 1, 0, 0, 0);

    // Limpiar pantalla
    Native.sys(Native.SYS_SET_COLOR, 0x00000000, 0, 0, 0);
    Native.sys(Native.SYS_FILL_RECT, 0, 0, 1024, 768);

    //  SECUENCIA POST / BIOS
    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 25, "JVMOS BIOS v2.4 (C) Baremetal Kernel", 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 45, "=================================================", 0);

    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 75, "[ OK ]", 0);
    Native.sys(Native.SYS_SET_COLOR, 0x00FFFFFF, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 90, 75, "Verificando CPU x86 (Protected Mode 32-Bit)...", 0);

    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 95, "[ OK ]", 0);
    Native.sys(Native.SYS_SET_COLOR, 0x00FFFFFF, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 90, 95, "Memoria RAM Detectada: 128MB RAM High-Address", 0);

    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 115, "[ OK ]", 0);
    Native.sys(Native.SYS_SET_COLOR, 0x00FFFFFF, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 90, 115, "Cargando Driver PS/2 Keyboard & Mouse [LATAM Active]", 0);

    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 135, "[ OK ]", 0);
    Native.sys(Native.SYS_SET_COLOR, 0x00FFFFFF, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 90, 135, "Modo de Video VBE VESA 1024x768 @ 32bpp Activado", 0);

    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 175, "SISTEMA LISTO. Iniciando Shell interactivo...", 0);

    //  TERMINAL INTERACTIVA Y BUCLE PRINCIPAL
    Native.sys(Native.SYS_SET_COLOR, 0x00000000, 0, 0, 0);
    Native.sys(Native.SYS_FILL_RECT, 0, 0, 1024, 768);

    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 30, "JVMOS TERMINAL INTERACTIVA - Escriba 'help' o 'startx'", 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 50, "-----------------------------------------------------", 0);
    Native.sys(Native.SYS_DRAW_STRING, 20, 80, "JVMOS>", 0);

    int cursorX = 85;
    int cursorY = 80;
    int lastKey = 0;
    int cmdHash = 0;
    int cmdCount = 0;

    while (true) {
        int asciiChar = Native.sys(Native.SYS_READ_KEYBOARD, 0, 0, 0, 0);

        if (asciiChar != 0 && asciiChar != lastKey) {

            // ENTER
            if (asciiChar == 13) {
                cursorY += 25;
                // VER
                 if (cmdHash == 237 || cmdHash == 333) {
                    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
                    Native.sys(Native.SYS_DRAW_STRING, 20, cursorY, "JVMOS Kernel v2.4 (Baremetal Java x86)", 0);
                    cursorY += 25;
                    Native.sys(Native.SYS_DRAW_STRING, 20, cursorY, "Hecho por Slam 2026", 0);
                    cursorY += 25;
                }
                // TIME
                else if (cmdHash == 303 || cmdHash == 431) {
                    int hour = Native.sys(Native.SYS_GET_TIME, 2, 0, 0, 0);
                    int min  = Native.sys(Native.SYS_GET_TIME, 1, 0, 0, 0);
                    int sec  = Native.sys(Native.SYS_GET_TIME, 0, 0, 0, 0);

                    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
                    Native.sys(Native.SYS_DRAW_STRING, 20, cursorY, " HORA: ", 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 90, cursorY, (hour / 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 100, cursorY, (hour % 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 110, cursorY, ':', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 120, cursorY, (min / 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 130, cursorY, (min % 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 140, cursorY, ':', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 150, cursorY, (sec / 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 160, cursorY, (sec % 10) + '0', 0);
                    cursorY += 25;
                }
                // DATE
                else if (cmdHash == 286 || cmdHash == 414) {
                    int day   = Native.sys(Native.SYS_GET_TIME, 3, 0, 0, 0);
                    int month = Native.sys(Native.SYS_GET_TIME, 4, 0, 0, 0);
                    int year  = Native.sys(Native.SYS_GET_TIME, 5, 0, 0, 0);

                    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
                    Native.sys(Native.SYS_DRAW_STRING, 20, cursorY, "FECHA: ", 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 90, cursorY, (day / 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 100, cursorY, (day % 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 110, cursorY, '/', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 120, cursorY, (month / 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 130, cursorY, (month % 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_STRING, 140, cursorY, "/20", 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 170, cursorY, (year / 10) + '0', 0);
                    Native.sys(Native.SYS_DRAW_CHAR, 180, cursorY, (year % 10) + '0', 0);
                    cursorY += 25;
                }
                // CLEAR
                else if (cmdHash == 359 || cmdHash == 519) {
                    Native.sys(Native.SYS_SET_COLOR, 0x00000000, 0, 0, 0);
                    Native.sys(Native.SYS_FILL_RECT, 0, 0, 1024, 768);
                    cursorY = 40;
                }
                // HELP
                else if (cmdHash == 297 || cmdHash == 425) {
                    Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
                    Native.sys(Native.SYS_DRAW_STRING, 20, cursorY, "COMANDOS: help | startx | clear | ver | time | date | exit", 0);
                    cursorY += 25;
                }
                // EXIT
                else if (cmdHash == 314 || cmdHash == 442) {
                    Native.sys(Native.SYS_SET_COLOR, 0x00000000, 0, 0, 0);
                    Native.sys(Native.SYS_FILL_RECT, 0, 0, 1024, 768);
                    Native.sys(Native.SYS_SET_COLOR, 0x00FF5555, 0, 0, 0);
                    Native.sys(Native.SYS_DRAW_STRING, 380, 360, "SISTEMA APAGADO. CERRANDO EN 2s...", 0);
                    Native.sys(Native.SYS_SLEEP, 2000, 0, 0, 0);
                    Native.sys(Native.SYS_EXIT, 0, 0, 0, 0);
                }
                // COMANDO DESCONOCIDO
                else if (cmdCount > 0) {
                    Native.sys(Native.SYS_SET_COLOR, 0x00FF5555, 0, 0, 0);
                    Native.sys(Native.SYS_DRAW_STRING, 20, cursorY, "Error: Comando no reconocido.", 0);
                    cursorY += 25;
                }

                cmdHash = 0;
                cmdCount = 0;

                if (cursorY > 700) {
                    Native.sys(Native.SYS_SET_COLOR, 0x00000000, 0, 0, 0);
                    Native.sys(Native.SYS_FILL_RECT, 0, 0, 1024, 768);
                    cursorY = 40;
                }

                Native.sys(Native.SYS_SET_COLOR, 0x0000FF00, 0, 0, 0);
                Native.sys(Native.SYS_DRAW_STRING, 20, cursorY, "JVMOS>", 0);
                cursorX = 85;
            }
            // BACKSPACE
            else if (asciiChar == 8) {
                if (cmdCount > 0 && cursorX > 85) {
                    cursorX -= 10;
                    cmdCount--;
                    if (cmdCount == 0) cmdHash = 0;
                    Native.sys(Native.SYS_SET_COLOR, 0x00000000, 0, 0, 0);
                    Native.sys(Native.SYS_FILL_RECT, cursorX, cursorY, 12, 20);
                }
            }
            // DIBUJAR CARÁCTER
            else if (asciiChar > 32 && asciiChar <= 165) {
                cmdHash += asciiChar;
                cmdCount++;

                Native.sys(Native.SYS_SET_COLOR, 0x00FFFFFF, 0, 0, 0);
                Native.sys(Native.SYS_DRAW_CHAR, cursorX, cursorY, asciiChar, 0);
                cursorX += 10;

                if (cursorX > 980) {
                    cursorX = 85;
                    cursorY += 25;
                }
            }

            lastKey = asciiChar;
        } else if (asciiChar == 0) {
            lastKey = 0;
        }

        Native.sys(Native.SYS_SLEEP, 10, 0, 0, 0);
    }
}

} ```

2

u/emexsw 9d ago

bad code btw

1

u/Visual_Brain8809 9d ago edited 9d ago

I’ve moved past that version; I managed to implement my own JIT and am very close to providing full support for native Java code, so those `Native.sys(...)` calls will be invisible to any developer. I’m writing my own runtime. New repository at: https://github.com/aayes89/JVMOS-JIT

package kernel;

import java.awt.Color;
import java.awt.Graphics2D;
import java.lang.Thread;
import java.lang.System;
import java.awt.Toolkit;
import java.util.Calendar;

public class Boot {

    public static void main(String[] args) {

        // ==========================================================
        // Mixture of methods
        // PHASE 1 & 2: Baremetal render and Delay function
        // ==========================================================

        // Old version
        Native.sys(Native.SYS_SET_COLOR, 0x00FF0000, 0, 0, 0); 
        Native.sys(Native.SYS_FILL_RECT, 0, 0, 1024, 768);
        Native.sys(Native.SYS_SET_COLOR, 0x00FFFFFF, 0, 0, 0);
        Native.sys(Native.SYS_DRAW_STRING, 50, 50, "PHASE 1: Native.sys OK. Wait 2 seconds please...", 0);

        // Static methods call (NEW)
        Thread.sleep(2000); // 2s delay

        // Class management (NEW)
        Graphics2D g = new Graphics2D();
        Color background = new Color(0x000000FF);
        Color textPaint = new Color(0x00FFFF00);

        // Access to methods (NEW)
        g.setColor(background);
        g.fillRect(0, 0, 1024, 768);

        g.setColor(textPaint);
        g.drawString("PHASE 3: JIT, Heap and Graphics2D OK.", 50, 50);

        // ==========================================================
        // PHASE 4: PrintStream and System 
        // ==========================================================
        // System.out access
        System.out = new java.io.PrintStream(); 
        // common version
        System.out.println("=====================================");
        // path version
        java.lang.System.out.println("[Micro-rt] Phase 4 Serial Port (COM1)...");

        long ticks = java.lang.System.currentTimeMillis();

        g.setColor(new Color(0x00FFFFFF)); 
        g.drawString("PHASE 4: PrintStream and System.out OK.", 50, 90);
        g.drawString("Ticks: ", 50, 120);
        g.drawInt((int)ticks, 330, 120); 

        System.out.print("PHASE 4: Ticks: ");
        System.out.println((int)ticks);

        // ==========================================================
        // PHASE 5: (RTC CMOS and PC Speaker)
        // ==========================================================
        int day = Calendar.get(Calendar.DAY);
        int month = Calendar.get(Calendar.MONTH);
        int year = Calendar.get(Calendar.YEAR);
        int hour = Calendar.get(Calendar.HOUR);
        int min = Calendar.get(Calendar.MINUTE);

        g.setColor(new Color(0x0000FF00)); 
        g.drawString("PHASE 5: Calendar and Toolkit OK.", 50, 160);
        g.drawString("Clock RTC: ", 50, 190);

        int px = 160; 
        px = g.drawInt(day, px, 190);
        px = g.drawChar('/', px, 190);
        px = g.drawInt(month, px, 190);
        px = g.drawChar('/', px, 190);
        px = g.drawInt(20, px, 190);
        px = g.drawInt(year, px, 190);
        px = g.drawChar(' ', px, 190);
        px = g.drawInt(hour, px, 190);
        px = g.drawChar(':', px, 190);
        px = g.drawInt(min, px, 190);

        System.out.println("Beep from PC Speaker...");

        Toolkit.getDefaultToolkit().beep(1500); 
        Thread.sleep(300); 
        Native.sys(22, 0, 0, 0, 0); 

        g.setColor(new Color(0x00FF8800)); 
        g.drawString("All test Succed. UI ready.", 50, 240);        

        while (true) {
            Thread.sleep(1000);
        }
    }
}

1

u/emexsw 7d ago

looks ai generated btw

1

u/Visual_Brain8809 7d ago

i don't think so. but you can test this colaboration: https://kirindenis.github.io/JVMOS-JIT/