Blink by orbitaldecay [web]
Blink 1.0 orbitaldecay@gmail.com -~= What is Blink? =~----------------------------------------------------------- Blink is a 32bit protected mode OS kernel for x86 PCs in 256 bytes! Blink is multiboot compatible, so it can be booted by any multiboot compliant boot loader (GRUB is all I've tested it with). Userland code is provided to the kernel to execute by means of multiboot modules. When Blink is loaded, it specifies the VESA mode it would like to use to the multiboot boot loader. Thus, once userland code starts, a linear frame buffer is already available for drawing. This makes Blink particularly well suited for writing size code. -~= How to run Blink =~--------------------------------------------------------- To run Blink, you'll need GRUB2 installed. It won't work with GRUB legacy because GRUB legacy doesn't support the VESA graphics features of the multiboot specification (AFAIK). At the GRUB2 boot menu, press C to bring up a command line. Then type > legacy_kernel /path/to/blink.bin /path/to/blink.bin > module /path/to/intro.bin > boot where '/path/to' represents a fully qualified path name. After typing 'boot' and pressing enter, Blink will boot and execute the userland code contained in intro.bin. -~= Writing Userland code for Blink =~------------------------------------------ Blink sets up a very minimal userland environment. There is no way to control where GRUB loads multiboot modules, so all userland code must be position independent. Blink does, however, place the address of the begining of the module in ESI and the address of the linear frame buffer in EDI before jumping to the userland module. Blink does not set up a stack for the userland code, so if you need one you'll have to set it up yourself. Blink reserves memory from 0x00100200 to 0x00200000 for use by userland code. Various constants are stored in settings.def which should aid development. For example, if you wanted to set up a stack and install an ISR to run every time the timer is triggered (IRQ0), you could do it like this: %include 'settings.def' bits 32 user.start: ; At this point ESI contains a pointer to USER.start (which could be loaded ; anywhere) and EDI contains a pointer to our linear frame buffer (LFB) ; Initialize segment registers and setup stack mov esp, USER_STACK ; USER_STACK is defined in settings.def ; Save pointer to LFB mov [USER_DATA], edi ; USER_DATA is defined in settings.def ; Install ISR 0x20 to draw when the timer goes off (IRQ0) mov eax, IDT_ADDR + 0x20 * 8 ; IDT_ADDR is defined in settings.def add esi, (user.isr20h - user.start) mov word [eax], si shr esi, 16 mov word [eax + 6], si user.spin: jmp user.spin ; ISR for 20h user.isr20h: pushad ; Clear master PIC mov al, 0x20 out 0x20, al ; Fill the screen mov eax, USER_DATA mov ebx, [eax] ; Load LFB address mov edx, [eax + 4] ; Load frame counter xor ecx, ecx ; Clear the pixel counter user.isr20h_fillscreen: mov byte [ebx + ecx * 4], dl inc ecx cmp ecx, VID_WIDTH * VID_HEIGHT ; Video resolution from settings.def jnz user.isr20h_fillscreen ; Increment frame counter inc dword [eax + 4] ; Goodbye popad iretd user.end: -~= Thanks =~------------------------------------------------------------------- ... to the OS dev community and all the 1337 h4xx0rz out there who keep the scene alive. E-mail me with questions or comments. Peace. orbitaldecay 2014
[ back to the prod ]