English / Deutsch | Print version

Prev
PBM6 - EFI
Table of Contents

Development Blog


The new boot manager is written from scratch. Planed features are

  • Full USB 1.1/2.0/3.0 support (thumbs, hard disks, floppys, optical drives, keyboards, hubs, maybe mouse)
  • PC-Card (PCMCIA) flash disk support
  • PCI Express support
  • VHD support
  • (U)EFI support
  • GPT support
  • Simple text mode, enhanced text mode, gfx mode
  • Support various file systems (FAT12/16/32, Ext2/3/4, limited NTFS, limited HFS+)
  • Native Linux Kernel boot
  • Native AHCI support
  • Modular
  • Simple shell

Donations are rare and welcome: Donate



2024-09-01  -  Various fixes and changes


PBM6 hang on some computers

  • MS-DOS boot hang.
  • LILO countdown not working.
  • Linux Kernel BIOS data check boot hang.

Caused by: Timer IRQ not working after using VESA mode.

Solution: Enable IRQ0 when the boot manager starts an OS.


Floppy detection

Fixed: Floppy motor not stopping after floppy drive detection.


Boot from floppy

Fixed: Reading the whole file did not work correctly. The last cluster of the file hasn't been readed.


Floppy image and ISO file

Added pbm6-nt, pbm6-dos.exe and Changelog.txt to floppy image and ISO file.
https://forum.plop.at/index.php/topic,2097.0.html


Various

Renamed pbm6nt to pbm6-nt.
Added intall.bat for pbm6-nt.
Blind: Floppy image file added.


2024-03-01  -  PBM6 - BIOS/Legacy - USB EHCI bugfix, floppy (FAT12) loader update


EHCI Controller freeze

Some EHCI Controllers reading the entry of the Periodic Frame List even when the entry is marked as terminated. This ends in an error when no QH structure is linked.

Fix: Fill the Periodic Frame List with a pointer to an empty/inactive QH. Mark the entry as terminated.


Start PBM6 from floppy

Fixed, FAT12 loader rewritten from scratch.


2023-08-18  -  PBM6 - BIOS/Legacy - A20


Update: Query A20 status.


2023-08-14  -  PBM6 - BIOS/Legacy: Bug fixes and pbm6-dos.exe


New/updated features

  • Floppy Disk Controller driver written. Now you can boot floppies from PBM6.
  • pbm6-dos.exe: A DOS program to start PBM6 and more.
  • Timer function updated.
  • Sleep function rewritten.
  • CDROM Loader rewritten.
  • Kernel Command Line parameters:
    • textmode - Use text mode instead of VESA.
    • dosldr - Install special interrupt vectors. Also used by pbm6-dos.exe.

Bugfixes

  • Main menu: General protection fault fixed. Reason was a wrong memory allocation segment on the menu short code list.
  • ext2/3:
    • Block size calculation fixed.
    • Wrong memory pointer fixed.
    • Wrong memory memory freeing fixed.
    • File system detection updated.

Information about OS/2

Booting OS/2 from PBM6 hang on loading the IBM1S506.ADD driver or fails to boot. OS/2 boots fine when you replace the IBM1S506.ADD with the driver PTI1S506.ADD.

In your file 'c:\config.sys' disable the old driver

rem BASEDEV=IBM1S506.ADD

Enable the new driver. Add this line below the IBM1S506.ADD

BASEDEV=PTI1S506.ADD


pbm6-dos.exe

I have been asked for a tool that runs under DOS to start PBM6 and continue to boot an OS from USB. The idea was to transfer the tool and the boot manager through a serial port connection to computers without (or broken) floppy drive, CD drive and no ability to boot from network, but booting DOS from the hard disk still works. pbm6-dos.exe is a tool for this. Thanks to Lys for the idea and testing.

pbm6-dos.exe is a DOS program to start PBM6. You can also start PlopKexec or a Linux Kernel.

What can you do?

  • You can start PBM6 from DOS and chainload an OS from HDD, USB, CD and so on.
  • You can start a Linux kernel from DOS.
  • You can start PlopKexec from DOS.
  • And more...

You can use the program with some parameters.

Parameters:
/?               This help.
/v               Print program version.
/d               Debug mode.
/e <file name>   Write loader to file.
/k <file name>   Load Boot Manager or Linux Kernel.
/i <file name>   Load initrd file.
/a <parameters>  Append, parameters for the boot manager / kernel. Use " here for
                 multiple parameters.
/s xxxx          Load real mode loader to segment (hex). Example: /s 9000


/d: Some debug information.

/e <file name>: Extract the loader. You can append another program to the loader.
pbm6-dos /e ldr.exe

Attach a new program in DOS:
copy ldr.exe+pbm6 newpbm6.exe

PlopKexec:
copy ldr.exe+plopkexec plpkexec.exe

Or a Linux Kernel:
copy ldr.exe+bzImage linux.exe

2023-02-14  -  PBM6 - EFI


See installation example in the video Install Plop Linux - Desktop - UEFI.


2023-02-06  -  PBM6 - EFI


Minor fix: Hide message "Found ...." when booting in hidden mode.


2023-01-25  -  GNU-EFI patch - UEFI functions with 11 parameters


gnu-efi 3.0.15 supports UEFI functions with at maximum ten parameters. This is my patch for gnu-efi 3.0.15 to extend the support for UEFI functions that have eleven parameters. I came over the problem when I added the USB gamepad support to PBM6-EFI last year. The EFI_USB2_HC_PROTOCOL - USB Control Transfer function has eleven parameters.

Sidenote: The EFI_USB2_HC_PROTOCOL works, but finally I used the EFI_USB_IO_PORTOCOL for the gamepad support.

Download: gnu-efi-3.0.15.patch


2023-01-25  -  PBM6 - EFI: Some fixes


  • QEMU: Text Output Protocol (top error) fixed. PBM6-EFI works now fine with QEMU EFI boot using TianoCore OVMF.fd
  • User Interface: Active sub window is dark. Fixed.
  • Config file: Config file not found when booting from CD/DVD. Fixed.

Download: pbm6-efi-20230125.zip

QEMU EFI: Download OVMF.fd from GitHub (Clear Linux* Project Page).
Start command example: qemu -enable-kvm -smp 4 -m 4096 -bios OVMF.fd -cdrom pbm6-efi.iso


2022-11-18  -  PBM6 - BIOS/Legacy: Bug fixes


The IRQ/INT handling for real mode <-> protected mode has been rewritten. This should solve a lot of issues.

Download: pbm6-test-20221118.zip, pbm6-test-20221118-serial.zip


2022-11-04  -  PBM6 - BIOS/Legacy: Native PXE boot, bug fixes


This release includes a new file called pbm6.pxe. Use it for native boot from network with PXE. Valdo H. asked for that feature.
Requirements and instructions: See pxe/README.txt

This release has some bug fixes but other fixes are still missing. A better version comes soon.

A lot of documentation is still missing.

Download: pbm6-test-20221104.zip, pbm6-test-20221104-serial.zip


2022-11-04  -  PBM6 - EFI: ISO fix


The ISO did not work under VMware. It is fixed now.

Download: pbm6-efi-20221104.zip


2022-10-25  -  PBM6 - EFI: Xbox 360 Controller & PlayStation 3 Dualshock Controller


I received the request to add support for the SteamDeck to navigate through the menu with the SteamDeck controls. As I have no SteamDeck, the development is a bit more complicated. But SteamDeck support will come. Meanwhile, today I added two simple drivers to navigate with the Microsoft Xbox 360 Controller and the Sony PlayStation 3 Dualshock Controller through the menu.

Mapping:

Left Stick, D-Pad: Up, down, left, right
Xbox 360 Controller buttons: A = Enter, B = Back, Y = Tab
PS3 Dualshock Controller buttons: X = Enter, Circle = Back, Triangle = Tab

Supported Vendor/Product IDs:

045e:028e - Xbox 360 Controller
054c:0268 - PS3 Dualshock Controller

Download: pbm6-efi-20221025.zip


2022-07-04  -  Error - value too large for defined data type


During bug fixing of the serial console support I stumbled over a strange bug when booting Linux. I used two old laptops, connected with a serial cable. To be sure that the serial ports are working fine, I booted Plop Linux 22.2 for i486. The laptops have 32 bit processors. Suddenly, booting stopped and I got the error "value too large for defined data type". I was surprised, because booting Plop Linux worked always fine on those machines. So I tried older versions of Plop Linux and finally the version 19.4 booted fine. I figured out that newer glibc versions causing the error. Plop Linux 19.4 is using glibc 2.30, later glibc 2.33 and 2.35 was used.

Another reason for the error is the hardware clock of the laptops. As they are very old and the CMOS battery is empty, they have a default date for example with the year 1998. A correct date does not matter for the serial test, so I booted with the BIOS default values, which failed with the newer glibc (but worked with glibc 2.30). When I set the current date in the BIOS, then booting worked fine with the newer glibc. I played around and saw that a year before 2000 is problematic.

In short, to avoid the glibc error 'value too large for defined data type' on old machines (32 bit) set a date with the year 2000 or later and recent glibc will work fine.


2022-07-03  -  PBM6 - BIOS/Legacy: Serial Console Fix


Fixed serial console support. For testing the configuration is hard coded to COM1, 115200 baud, 8 bits, no parity, one stop bit.

Details coming tomorrow.

Download: pbm6-test-20220719-serial.zip - Use this special version only when you want to try/use the serial console support!


2022-06-11  -  PBM6 - BIOS/Legacy: Serial Console Support


Serial console support has been added. For testing the configuration is hard coded to COM1, 9600 baud, 8 bits, no parity, one stop bit. This will be configurable later. VT100 codes are used for the interface.

When the serial console feature is used, then the boot manager automatically switches to the screen resolution text mode 80x25.

Download: Removed because of bugs


See the demonstration video. Note, keyboard input from serial console & remote computer.

Privacy settings - Embed Youtube content

   
External content blocked. Watch on YouTube


2022-05-29  -  PBM6 - BIOS/Legacy bug fix release


exFAT fix
File Commander VHD/VHDX fix
Source Code: LocalClear macro disabled and replaced clearing the variables manually. This fixes also USB problems.


2022-05-06  -  PBM6 - BIOS/Legacy: Temporary release notes


Windows boot from VHD works with this release. Instructions to create a Windows VHD coming soon. Basically just install Microsoft Windows as usual in Hyper-V or VirtualBox to a VHD disk and add a custom VHD boot entry.

Boot from VHDX should work too, but is untested at the moment. (Have no time)

This release has some boot fixes.

External content blocked. Watch on YouTube


2022-04-06  -  PBM6 - BIOS/Legacy: Temporary release notes


Just an overview. Details coming soon....

Minor USB driver fixes.
Simple file commander added.
File system support added, read only: FAT12/16/32, extFAT, ext2/3, NTFS
Hex viewer / Text file viewer
VHD, VHDX support added.
Partial config file support added.
Kernel command line support added.
Various fixes, still buggy.

External content blocked. Watch on YouTube


2021-09-09  -  PBM6 - BIOS/Legacy: USB 3 fixes


USB 3.0 driver updated.


2021-07-23  -  PBM6 - EFI


Bugfix release + new setup options.


2021-06-16  -  PBM6 - EFI


Initial test release of PBM6-EFI. Written in C using GNU-EFI.


2021-01-25  -  Directories


I renamed the directories in the pbm6-test-20210119.zip. The "native" directory is now the first one. That version is using my drivers from start.

The BIOS version freezes on keypress on some computers.


2021-01-19  -  USB 3 fixes, ACPI


Updated: USB 3.0 driver, USB HUB driver.
Added: ACPI driver, APIC / IO APIC driver (but currently disabled).

There was a break for many months, because I am working on other projects. The most interesting is the work with the Unreal Game Engine. Here are some screenshots, see more here.

 

A few weeks ago I started to fix the USB 3 problem.

I fixed the USB 3 initialization bug that I had with the ASMedia Technology Inc. ASM1142 chipset. One big problem was that the host did not fire an IRQ. I had no clue why. I thought, maybe it works only with the APIC, but I didn't really believed that. Anyway I implemented ACPI which is the base requirement for APIC and then I added the support for Local APIC and IO APIC. That worked fine, but the USB 3 host still did not fire an IRQ. So the bug search continued. Finally, the problem was that I initialized the ERSTBA register before the ERSTSZ register. For easy handling of the specification documents, I always write the page number of the PDF to the comments. So I can find the related sections quickly. By luck I saw that the ERSTSZ init is one page before the ERSTBA page. So I moved the ERSTSZ part up and the chip started to work. However, it wasn't easy to find that. It took days.

Here is the related code. Not easy to fix when you have no idea whats wrong.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    ; Runtime Registers: Setup Interrupt Register Set. 5.5.2 page 424.

; Program the Interrupter Event Ring Segment Table
; Size (ERSTSZ) register (5.5.2.3.1) with the number
; of segments described by the Event Ring Segment
; Table. Page 427.
; Address: Runtime Base + 028h + (32 * Interrupter)
; where: Interrupter is 0, 1, 2, 3, ... 1023
; See page 180 and 181.
mov eax, [.runtime_base]
add eax, 28h + 32 * 0 ; Address of Interrupter 0.
mov dword [fs:eax], 1 ; Only one entry in the Event Ring Segment Table (ERST)
mov edx, [fs:eax] ; Dummy read



; Program the Interrupter Event Ring Segment Table
; Base Address (ERSTBA) register (5.5.2.3.2) with a
; 64-bit address pointer to where the Event Ring
; Segment Table is located.
; Page 428.
; Note that writing the ERSTBA enables the Event
; Ring. Refer to section 4.9.4 for more information
; on the Event Ring registers and their initialization.
mov eax, [.runtime_base]
add eax, 30h + 32 * 0 ; Address of Interrupter 0.
mov ebx, [.event_ring_segment_table]
mov dword [fs:eax], ebx
mov dword [fs:eax + 4], 0
mov edx, [fs:eax] ; Dummy read
mov edx, [fs:eax + 4] ; Dummy read

With the working ASMEDIA chipset I was able to remove some other USB 3 bugs and I added USB 3 support to the USB HUB driver. Additionally, I fixed a HUB driver bug. With the ACPI driver, the shutdown function should work now fine. APIC is disabled, because at first it works fine now with the classic PIC and the second reason is that there would be problems with starting DOS.


2020-04-08  -  Minor updates


Fixed:

  • No partition has been detected after an USB drive has been removed.
  • USB Hub not detecting devices on startup fixed.

Known USB 3 driver issues:

The event ring does not report anything on ASMedia Technology Inc. ASM1142 and NEC Corporation uPD720200 host controllers. I don't know why at the moment.

2020-03-19  -  USB 3 xHCI added, some IDE fixes, partition detection fix


USB 3 support added. The xHCI driver is almost complete. Booting USB 3 devices works. I tried some operating systems, all booted fine. Also Windows 10 PE and it booted from USB very fast without problems.

Finally USB 3 is a simple concept and easy to implement. I like it. The xHCI driver adds only 9.5 KB.

USB 3 Status: USB drives and keyboards are working. But there is a problem with disconnecting and reconnecting a device. USB HUBs are currently not working. They need a special handling. But HUB support for USB 3 will come.

Release fixes:

  • USB Mass Storage driver:
    Endpoint detection fix.

  • IDE:
    Again a device detection fix.
    Sector read on big drives fixed.

  • Partitions:
    Logical partition detection fix.

Some screenshots


2020-03-07  -  USB 3 - xHCI


This week I started with USB 3. Reading the specification document of the USB Controller. The eXtensible Host Controller Interface for Universal Serial Bus (xHCI). Very interesting and different to USB 1.1 and USB 2.0 controllers. It took some time to put all the information together in my brain, but finally I understood it (the most I think). I wrote a test program and SUCCESS - I am able to read data from an USB device. It was not so easy as it sounds, but thats past and doesn't matter now. The basics are done. Next stage is to clean up the code, create a lot of functions and finally create the USB 3 driver. Thats a lot of work, but I have a good feeling.

Source code screenshot


2020-02-20  -  Many bug fixes


I spent a lot of time for bug fixing and I am quite happy with the result. I made also important changes in the internal program structure.

Bug fixes:

  • Stack:
    A wrong parameter size (word/dword) caused a wrong stack. Finding the problematic code line was very difficult. There are many thousand lines of code. The problem was that the effect of this bug came silently. I think it was also the reason for a 'General protection fault' error on some machines.
    Wikipedia: Stack

  • USB:
    I updated the interrupt handling for all USB drivers.
    Some fixes.

  • IDE:
    I fixed the IDE drive detection. On some machines, the drives haven't been detected.
    Non standard I/O port configuration is now also supported.
    I added the support for a second IDE controller chip, that allows up to 8 IDE drives.

  • AHCI/SATA:
    There was a bad bug. Some controllers had no problem, others did not work correctly. On one of my machines, booting with SATA resulted in a freeze. The sector read returned valid data at the first look, but then I saw that it was displaced by one byte. It looked like a transfer buffer alignment problem. Data structures for USB must be aligned too. So its nothing new. And finally it was really a wrong aligned buffer. For those who stumble over the same problem. For the Physical Region Descriptor Table (PRDT), the data block (DBA) must be word aligned. See AHCI Specs Page 40.
    There was also another problem with the sector read/write routine. Some data haven't been cleared completely during the initialization. The result could be invalid data. It has been fixed.

  • Keyboard:
    The PS/2 keyboard driver has been updated.
    The 16 bit and 32 bit Interrupt Service Routine has been rewritten completely. This affects the PS/2 and USB keyboard support. It should work fine now.

  • 16 bit ISRs:
    The 16 bit Interrupt Service routine handling at all has been rewritten. It was some work, but it will make things easier in the future. And the ISRs are working better now.

  • Memory management:
    There was a tiny bug in the initial routine that is responsible for all further memory allocation. Its fixed.

The test version is available for download.


2020-02-12  -  Nightly build with fixes released


Official test release with bug fixes comes in a few days.


2020-02-05  -  Nightly build with fixes released


Official test release with bug fixes comes in a few days.


2019-12-19  -  USB 2.0 fix


A bug for some USB 2.0 controllers has been fixed. I forgot to check bit 0 of the HCCPARAMS register. If the bit is set, you have to use larger data structures (EHCI Specs. Apendix B). Ignoring that was the reason that memory area has been suddenly overwritten which resulted in an error. Also some minor bugs have been fixed.

Download: See top of this page


2019-11-29  -  Many fixes and beeps


This release has a lot of bug fixes. It comes also with the new PC Speaker support, see the post from 2019-11-17 for more information. Sound card support with additional features is planed.

Use CTRL-F5 to enable/disable the PC Speaker support. Pressing F5 will beep the current text as Morse Code.

Download: [removed - outdated]


2019-11-17  -  PC Speaker


PBM6 has PC Speaker support for a simple screen reader and notifications. This will help blind and visually impaired people to use the boot manager. The Morse Code is used for the text.

There is a sound notification when the boot manager is ready to use.

In the main menu, you hear a short information with two chars. For boot entries, the first char is the drive type and the second char is the bus type. Example: Hard disk IDE is HI. CD-ROM SATA is CS. Hard disk USB is HU.

Static menu entries: Setup is SE. About is AB. Shutdown is SH.

With a hotkey, you hear the whole text of the menu entry.

Attaching and removing an USB drive gives a notification sound.

The PC Speaker feature will be available in the next Test Version.

Demonstration video:
External content blocked. Watch on YouTube

Download as MP3: pbm6-pcspeaker.mp3

Download as text: pbm6-pcspeaker.txt


2019-11-04  -  Boot Manager Name - Test Release - Starting the boot manager - Download


At first I have to say, I have chosen a name for the new boot manager. Some people sent me various names, and I say thank you, but none made me happy. The new boot manager will be called 'PBM6' (Plop Boot Manager Six). I know, not really extraordinary. You may ask why I searched for a different name. There are different reasons, but mostly to avoid just saying 'plop' to the boot manager. I am still thinking about an alternative name, but I think 'PBM6' is fine.


Test Release

I think, the time has come to release a test version. The test version is not perfect, so don't expect too much. There is much left to do. Many features are missing.

Known issues:

  • Various orange chars on startup: Just debug stuff. Will be removed later.
  • USB3: There is no driver included at the moment. I am working on it. To use a device with the boot manager, you have to connect the device to the USB 2 port. Also in a Virtual Machine.
  • UEFI: There is no UEFI support at the moment. Starting the boot manager with UEFI will end in an error.
  • There is no MBR installation at the moment. See 'Starting the boot manager' for various ways to start the boot manager.
  • There is no configuration file to configure the boot manager.
  • You can not configure the boot manager with Linux Command Line Parameters.
  • Starting the boot manager from the Windows Boot Menu: Currently is only Windows Vista/7/8/10 supported, because "bcdedit" must be used.
  • Floppy drive is not accessible after booting.
  • Booting floppy from the boot manager is not supported at the moment. Neither a builtin nor an USB floppy drive.
  • Licence: Currently, the boot manager is free personal use. It is not free for commercial use.

What should work:

  • IDE: Hard disks, CD/DVD drives.
  • SATA: Hard disks, CD/DVD drives.
  • USB Controller: USB 1.1 UHCI/OHCI, USB 2.0 EHCI support.
  • USB Device support for keyboard, HUB, thumb drives, hard disks, CD/DVD drives.
  • USB read/write support.
  • USB Hot-Plug.
  • Boot drive partition.
  • Start drive MBR.
  • Boot CD/DVD in no-emulation mode.
  • Eject CD/DVD.
  • Show drive infos.
  • Change screen resolution, also wide screen.
  • Start PMB6 from Floppy, CD/DVD drive, network, Linux Boot Managers, Windows Boot Menu (Vista/7/8/10).

Some notes:

Main Menu: When you select a drive with "Enter", then the boot partition of the hard disk or the CD from the drive will be booted.
When you press the right key on a menu item that has the sign ">", then you open a Sub Menu.

Sub Menu hard disk: You can boot the MBR. You can choose a partition to boot. You can view some drive information.

Sub Menu CD/DVD: You can eject the disc. You can view some drive information.

Minimum requirements: CPU i386, 46 MB RAM.


Starting the boot manager

  • Floppy - A classic way. Write the floppy image to the floppy disk with "dd" or "rawwrite.exe".
  • CDROM - A classic way. Burn the ISO to the CDROM/DVD and boot.
  • ISO - Use the ISO to start the boot manager in a virtual machine.
  • Like a Linux Kernel - As the Plop Boot Manager 5, PBM6 can be started like a Linux Kernel from a Linux Boot Manager like LILO, GRUB and Syslinux (also from network).
  • Windows Boot Menu - Now its possible to start the boot manager directly from the Windows Boot Menu without workarounds like plpbt4win. You have to use "bcdedit". Its tested only on (NOT UEFI installed!) Windows 10.

Instructions for Linux Boot Managers

PBM6 can be started like a Linux Kernel by linux loaders. You can start it over the network with Syslinux in the same ways as Plop Boot Manager 5.

SYSLINUX

You can start PBM6 with the keyword "linux" and "kernel".

Examples:

label pbm6
    menu label ^Plop Boot Manager 6
    linux plop/pbm6


label plp6
    menu label ^Plop Boot Manager 6
    kernel plop/pbm6

GRUB2

You can start PBM6 with the keyword "linux" and "linux16".

Examples:

menuentry "Plop Boot Manager 6" {
    linux16 /boot/plop/pbm6
}

OR

menuentry "Plop Boot Manager 6" {
    linux /boot/plop/pbm6
}

See also https://www.plop.at/en/ploplinux/desktop/grub2.html

Example /etc/grub.d/40_custom

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

insmod ext2
set root='(hd0,1)'

menuentry "Plop Linux" {
    linux /boot/bzImage root=/dev/sda1
}

menuentry "Plop Boot Manager 5" {
    linux16 /boot/plop/plpbt.bin
}

menuentry "Plop Boot Manager 6" {
    linux /boot/plop/pbm6
}

menuentry "PlopKexec" {
    linux /boot/plop/plopkexec
}

menuentry "Memtest" {
    linux16 /boot/memtest/memtest
}    

LILO

Example:

image=/boot/plop/pbm6
label="Plop Boot Manager 6"

Instructions for Windows Vista/7/8/10

UEFI is NOT supported at the moment and will end in an error!

Copy "pbm6nt" to c:\

Add to Windows Boot Menu:
=========================

Open the Command Prompt as "Administrator"

Run the following commands:
bcdedit /create {ntldr} /d "PBM6"
bcdedit /set {ntldr} device boot
bcdedit /set {ntldr} device partition=c:
bcdedit /set {ntldr} path \pbm6nt
bcdedit /displayorder {ntldr} /addlast

Remove the entry:
=================

Warning! Be careful with this command!

bcdedit /delete {ntldr} /f

Download

Download: [removed - outdated]




2019-08-28  -  No special news


I had to do other various work over the last weeks, so no real progress. But the NTFS loader looks really good. Today I fixed a bug in a simple program, that is used for the window development. Its also used as sample program. Weeks ago, I did a heavy but needed code adjustment. A lot of code had to be modified. Required to put the program data on any RAM location. I planed to do that earlier, but it it never happened. Meanwhile all works, also the sample program.

Parallel I spend this week to build a fresh Plop Linux release (Xfce 4.14 is here, yes). Not every updated program compiles flawless. I have to do a lot of things to make it flawless.

I have to do more with the new Blender 2.80, which is amazing. So many new things and changes. Although I have 10 years Blender experience, I feel like a beginner. Unfortunately, I have no time.


2019-07-19  -  NTFS support


Since yesterday, I am working on a simple NTFS driver. My goal is to simplify the process of adding the boot manager to the Windows Boot Menu. Later, the NTFS driver could be used for other tasks too. My driver will not have full write support. Maybe I add some limited write access for existing files to modify bytes and write to a config file. Support for compressed or encrypted files is not planed.

Over twenty years ago (1998, 1999) I also worked on a program with NTFS read access. A lot of analyzing with a Hexeditor was required. Bytes, sectors and so on, figure out how the files are stored on the drive. Nowadays, you find a lot of documentation in the web. This makes the programming much easier. But a Hexeditor is still used, some things will never change. Today, I was looking at my source code from the past. The program was never finished, but important things worked. I was wondering how fast the time goes by.

My goal for today was reading directories and files. A lot of important functions are still missing, but directory listing and file reading works. Goal for today reached.


2019-06-27  -  Boot CD/DVD "El Torito"


I used four days exclusive to extend the INT 13h functions with "El Torito" functionality. This specification handles booting CD-ROMs. The Plop Boot Manager supports only IDE drives. The new boot manager supports now booting CD/DVD on IDE, SATA (AHCI) and USB (UHCI, OHCI, EHCI) without the help of a BIOS. At first, I support only the "No emulation" media type. It is the standard media type since (maybe 20) years. First tests are looking good and disc reading is fast. I tested successful some Linux Distros and various Microsoft Windows install DVDs.

Next goal is to improve the user interface and some additional hardware tests. A first public test release is coming closer, but still so much left to do.

It seems, the new boot manager name won't be "ehBoot" or "eh-boot". Still searching for a name without "Plop".


2019-06-12  -  USB 2.0 HUB and a video


At first, my USB HUB driver works great. The news are not really news. The most happened weeks ago. Lets talk about the USB HUB driver. I was worried about the split transactions, which are required on USB 2.0 HUBs to connect USB 1.1 devices to the USB HUB. But it was no problem to implement it. So the USB Keyboard (USB 1.1) works also fine when its connected to the USB 2.0 HUB. Although the HUB driver was working properly, I was not happy with the code. So I rewrote it completely a few weeks ago. It took two days, but I felt better.

I tested USB boot from a thumb drive with various operating systems. All booted fine. The USB Keyboard works as long as the OS did not grab it. That means, you can use the keyboard with other boot managers and also with DOS when you boot from USB. Remember, thats not possible with the Plop Boot Manager 5.

There was a surprise with ReactOS. It booted very slow. Loading the RamDisk takes ages. That's also stated at the ReactOS Wiki RAM Boot under "Known issues". It took much time with the BIOS USB and also with my new USB driver. But goes really fast with my old Plop Boot Manager 5. I was confused, because usually, the new driver is faster than the old driver. Then I remembered, that I added a simple caching system to the boot manager. I did the same again with the new boot manager, and now it boots also fast. It seems the ReactOS loader reads only one sector after another, instead of many sectors at once, which would be much faster. This could be the reason for the slow RamDisk loading. Just a speculation. I did not check the code.

I created a not very spectacular video, comparing the USB boot process BIOS vs EH-BOOT.

Note, I am a fan of the ReactOS project. I hope they have enough power to create a stable MS Windows compatible release.

Meanwhile I think, I will call the new boot manager "eh-boot" or "ehboot". But I don't know how it sounds from a native English speaker.

Checkout the video. At first, you see the setup with the Asus Eee PC, the USB 2.0 HUB which has the USB Keyboard and Thumb drive connected. Then comes the boot process with a timer that measures the USB part and some time warps when it boots with the BIOS. Recorded by night, because of the lights. Spoiler alarm: BIOS takes 7:22, the new boot manager takes 0:51.

External content blocked. Watch on YouTube

2019-02-22  -  Status update - USB Boot, USB Keyboard


I was busy with other work, but there was also some progress on the new boot manager.

Meanwhile, I wrote the INT 13h handler required to boot native from hard disks without the help of a BIOS. It works native with IDE, SATA and USB hard disk drives. CDROM and Floppy is left to do for for the INT 13 handler. SATA is not tested very well. USB drives bigger than 2 TB are supported, so you can even boot from an 8 TB USB drive. USB read and write is supported. For development purpose, I focused on UHCI. OHCI and EHCI will be added easily when all works fine with UHCI. Currently, DOS and Linux boot fine. Under DOS I copied successful a lot of files using my USB driver, but it has to be tested later by others too. USB write support is experimental.

Also, I almost finished the USB Keyboard driver and the INT 16h handler, required to use an USB keyboard under DOS or another boot manager. It works fine under DOS and also reduces the CPU usage when DOS is idle, because of using the 'hlt' command.

For those who are interested how the driver looks like, find the source code of my USB Keyboard driver below. You have to collapse it :)

The PS/2 keyboard driver has been updated too.

Note: There is still no release date for the new boot manager!

Collapse source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;================================
; USB Keyboard driver by Elmar Hanlhofer (C) 2019
; https://www.plop.at
;================================
;bool USB_KBD_ClaimDevice (dword device)
;bool USB_KBD_ReportCallback (dword transfer)
;void USB_KBD_SetLeds (dword device, word led_bitmap)
;void USB_KBD_SetLedsCallback (dword transfer)
;void USB_KBD_SyncLedsWithBDA (dword device)
;bool USB_KBD_StatusFlagsHandlePress (word bios_key_code)
;void USB_KBD_HandleReports (dword device, dword current_report, dword previous_report)
;void USB_KBD_BDA_SetModifierFlags (word kbd_flags)
;word USB_KBD_TranslateToBiosCode (word kbd_scan_code)
;================================
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
;================================
; USB Keyboard driver by Elmar Hanlhofer (C) 2019
; https://www.plop.at
;================================
;bool USB_KBD_ClaimDevice (dword device)
;bool USB_KBD_ReportCallback (dword transfer)
;void USB_KBD_SetLeds (dword device, word led_bitmap)
;void USB_KBD_SetLedsCallback (dword transfer)
;void USB_KBD_SyncLedsWithBDA (dword device)
;bool USB_KBD_StatusFlagsHandlePress (word bios_key_code)
;void USB_KBD_HandleReports (dword device, dword current_report, dword previous_report)
;void USB_KBD_BDA_SetModifierFlags (word kbd_flags)
;word USB_KBD_TranslateToBiosCode (word kbd_scan_code)
;================================

%define USB_KBD_DEBUG_CLAIM
;%define USB_KBD_DEBUG
;%define USB_KBD_DEBUG_TD
%define USB_KBD_DEBUG_KEY

;-----------------------------------------------------------------------------
; HID1_11.pdf Page 56, Modifier Keys Bitmap
;-----------------------------------------------------------------------------
; Bit Key
; 0 LEFT CTRL
; 1 LEFT SHIFT
; 2 LEFT ALT
; 3 LEFT GUI
; 4 RIGHT CTRL
; 5 RIGHT SHIFT
; 6 RIGHT ALT
; 7 RIGHT GUI
;
;-----------------------------------------------------------------------------
; HID1_11.pdf Page 60
;-----------------------------------------------------------------------------
; The following table represents the keyboard input report (8 bytes).
;
; Byte Description
; 0 Modifier keys
; 1 Reserved
; 2 Keycode 1
; 3 Keycode 2
; 4 Keycode 3
; 5 Keycode 4
; 6 Keycode 5
; 7 Keycode 6
;
; Byte 1 of this report is a constant. This byte is reserved for OEM use. The
; BIOS should ignore this field if it is not used. Returning zeros in unused fields is
; recommended.
;
; The following table represents the keyboard output report (1 byte).
;
; Bit Description
; 0 NUM LOCK
; 1 CAPS LOCK
; 2 SCROLL LOCK
; 3 COMPOSE
; 4 KANA
; 5 to 7 CONSTANT
;
; The LEDs are absolute output items. This means that the state of each LED
; must be included in output reports (0 = off, 1 = on). Relative items would permit
; reports that affect only selected controls (0 = no change, 1= change).
;-----------------------------------------------------------------------------

USB_KBD_LEFT_CTRL equ 0
USB_KBD_LEFT_SHIFT equ 1
USB_KBD_LEFT_ALT equ 2
USB_KBD_LEFT_GUI equ 3
USB_KBD_RIGHT_CTRL equ 4
USB_KBD_RIGHT_SHIFT equ 5
USB_KBD_RIGHT_ALT equ 6
USB_KBD_RIGHT_GUI equ 7

USB_KBD_LED_NUM_LOCK equ 0
USB_KBD_LED_CAPS_LOCK equ 1
USB_KBD_LED_SCROLL_LOCK equ 2



%include "keyboard/keyboard.h"



;======================================
;bool USB_KBD_ClaimDevice (dword device)
;======================================
USB_KBD_ClaimDevice:
M_Vars

M_Arg device, S_DWORD

M_Local buffer, S_DWORD
M_Local device_data, S_DWORD

M_Code
push eax
push esi

mov dword [.device_data], 0

; Check if the device is a keyboard and it supports the boot protocol.

push dword USB_DEVICE.wType
push dword [.device]
call GetValueWord
cmp ax, TYPE_USB_DEVICE
jne .wrong_device

push dword USB_DEVICE.bDeviceClass
push dword [.device]
call GetValueByte
cmp al, 0
je .check_interface
cmp al, 3 ; Human Interface Device
jne .wrong_device

push dword USB_DEVICE.bDeviceSubClass
push dword [.device]
call GetValueByte
cmp al, 1 ; Boot Interface Subclass
jne .wrong_device

push dword USB_DEVICE.bDeviceProtocol
push dword [.device]
call GetValueByte
cmp al, 1 ; Keyboard
jne .wrong_device
jmp .is_keyboard

.check_interface:
push dword USB_DEVICE.dConfigurationDescriptor
push dword [.device]
call GetValueDword
or eax, eax
je .wrong_device

; Pointer to Interface Descriptor.
mov esi, eax
add esi, USB_CONFIGURATION_DESCRIPTOR.size

cmp byte [fs:esi + USB_INTERFACE_DESCRIPTOR.bInterfaceClass], 3 ; Human Interface Device
jne .wrong_device

cmp byte [fs:esi + USB_INTERFACE_DESCRIPTOR.bInterfaceSubClass], 1 ; Boot Interface Subclass
jne .wrong_device

cmp byte [fs:esi + USB_INTERFACE_DESCRIPTOR.bInterfaceProtocol], 1 ; Keyboard
jne .wrong_device

.is_keyboard:
%ifdef USB_KBD_DEBUG_CLAIM
M_PrintfNL "USB_KBD_ClaimDevice: Keyboard detected"
%endif

push word HID_USB_KEYBOARD
push dword USB_DEVICE.bIsHid
push dword [.device]
call SetValueByte

; Create Pipe and add it to the device, register the endpoint descriptor.
push word 50
push word 8
push word 0x81
push dword [.device]
call OpenInterruptPipe ; (dword device, word endpoint_address, word word maximum_packet_size, word interval)
jc .error


; Allocate buffer for the report.
push dword USB_KEYBOARD_REPORT_SIZE
call MEM_Allocate
jc .error

mov [.buffer], eax

; Allocate memory for keyboard related device data.
push dword USB_KEYBOARD_DEVICE_DATA.size
call MEM_Allocate
jc .error

mov [.device_data], eax
mov esi, [.device]
mov [fs:esi + USB_DEVICE.dDeviceData], eax

mov eax, [.buffer]
mov esi, [.device_data]
mov [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport], eax


push dword 0
push dword USB_KBD_ReportCallback
push dword USB_KEYBOARD_REPORT_SIZE
push dword [.buffer]
push word 0x81
push dword [.device]
call QueueDataTransfer ; (dword device, word endpoint_address, dword buffer, dword buffer_len, dword callback dword callback_data)
jc .error

push dword [.device]
call USB_KBD_SyncLedsWithBDA ; (dword device)

mov eax, [.device]
mov byte [fs:eax + USB_DEVICE.bClaimedByDriver], TRUE

clc
jmp .exit

.error:
push dword [.device_data]
call MEM_Free

%ifdef USB_KBD_DEBUG_CLAIM
M_PrintfNL "KBD_ClaimDevice: Error."
%endif
stc
jmp .exit

.wrong_device:
%ifdef USB_KBD_DEBUG_CLAIM
M_PrintfNL "KBD_ClaimDevice: INFO: Device is not a keyboard with boot protocol."
%endif
stc

.exit:

pop esi
pop eax
M_Ret


;======================================
;bool USB_KBD_ReportCallback (dword transfer)
;======================================
USB_KBD_ReportCallback:
M_Vars
M_Arg transfer, S_DWORD

M_Local device, S_DWORD
M_Local buffer, S_DWORD

M_Code
push eax
push esi

%ifdef USB_KBD_DEBUG
M_PrintfNL "REPORT ooooooooooooooooooooooooooooooo"
%endif

push dword TRANSFER.dLastTD
push dword [.transfer]
call GetValueDword ; (dword address, dword offset)

%ifdef USB_KBD_DEBUG_TD
push eax
call PrintTransferDescriptorInfo
%endif

push dword TRANSFER.dDevice
push dword [.transfer]
call GetValueDword ; (dword address, dword offset)
mov [.device], eax


push dword TRANSFER.dBuffer
push dword [.transfer]
call GetValueDword ; (dword address, dword offset)

%ifdef USB_KBD_DEBUG
push word USB_KEYBOARD_REPORT_SIZE
push eax
call PrintHexBuffer32
%endif


push dword [.device]
call USB_GetDeviceData ; (dword device)
mov esi, eax

; Check reports
push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dPrevReport]
push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport]
push dword [.device]
call USB_KBD_HandleReports ; (dword current_report, dword previous_report)

; Free old report
push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dPrevReport]
call MEM_Free

; Set current report to old report
push dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport]
pop dword [fs:esi + USB_KEYBOARD_DEVICE_DATA.dPrevReport]


; Allocate buffer for the report
push dword USB_KEYBOARD_REPORT_SIZE
call MEM_Allocate
jc .error

mov [.buffer], eax
; Save report memory
mov [fs:esi + USB_KEYBOARD_DEVICE_DATA.dReport], eax

push dword 0
push dword USB_KBD_ReportCallback
push dword USB_KEYBOARD_REPORT_SIZE
push dword [.buffer]
push word 0x81
push dword [.device]
call QueueDataTransfer ; (dword device, word endpoint_address, dword buffer, dword buffer_len, dword callback dword callback_data)
jnc .no_error

.error:
;M_PrintfNL "Report error"

.no_error:
pop esi
pop eax
M_Ret


;======================================
;void USB_KBD_SetLeds (dword device, word led_bitmap)
;======================================
USB_KBD_SetLeds:
M_Vars

M_Arg device, S_DWORD
M_Arg led_bitmap, S_WORD

M_Local buffer, S_DWORD
M_Local leds, S_WORD
M_Local setup, S_DWORD

M_Code
push eax
push bx

mov dword [.buffer], 0

; Allocate 1 byte for the led report
push dword 1
call MEM_Allocate
jc .error

mov [.buffer], eax
mov bl, [.led_bitmap]
mov byte [fs:eax], bl

; Setup Packet
push word 1
push word 0000h ; 00 = keyboard HID
push word 0200h ; 02 = output report, 00 = report ID
push word USB_REQUEST_SET_REPORT ; 09h
push word USB_BM_REQUEST_TYPE_HOST_TO_DEVICE | \
USB_BM_REQUEST_TYPE_CLASS | \
USB_BM_REQUEST_TYPE_INTERFACE ; 21h
call CreateSetupPacket ; (word bmRequestType, word bRequest, word wValue, word wIndex, word wLength)
jc .error

mov [.setup], eax

push dword 0
push dword USB_KBD_SetLedsCallback
push dword 1
push dword [.buffer]
push dword [.setup]
push dword [.device]
call QueueControlTransfer ; (dword device, dword setup, dword buffer, dword buffer_len, dword callback, dword callback_data)
jnc .done

.error:
push dword [.buffer]
call MEM_Free

;M_PrintfNL "Error"

.done:
pop bx
pop eax
M_Ret


;======================================
;void USB_KBD_SetLedsCallback (dword transfer)
;======================================
USB_KBD_SetLedsCallback:
M_Vars
M_Arg transfer, S_DWORD

M_Code
push esi

; Free the buffer with the led data
mov esi, [.transfer]
push dword [fs:esi + TRANSFER.dBuffer]
call MEM_Free

pop esi
M_Ret


;======================================
;void USB_KBD_SyncLedsWithBDA (dword device)
;--------------------------------------
; Set leds according to the Bios Data Area Keyboard Flags
;======================================
USB_KBD_SyncLedsWithBDA:
M_Vars
M_Arg device, S_DWORD

M_Code
push eax
push bx

push word BDA_KEYBOARD_STATUS_FLAGS
call BDA_GetByte ; (word offset)

xor bx, bx
test al, b(BDA_KBD_SCROLL_LOCK_ON)
je .test_num_lock
or bl, b(USB_KBD_LED_SCROLL_LOCK)

.test_num_lock:
test al, b(BDA_KBD_NUM_LOCK_ON)
je .test_caps_lock
or bl, b(USB_KBD_LED_NUM_LOCK)

.test_caps_lock:
test al, b(BDA_KBD_CAPS_LOCK_ON)
je .tests_done
or bl, b(USB_KBD_LED_CAPS_LOCK)

.tests_done:
push bx
push dword [.device]
call USB_KBD_SetLeds ; (dword device, word led_bitmap)

pop bx
pop eax
M_Ret


;======================================
;bool USB_KBD_StatusFlagsHandlePress (word bios_key_code)
;--------------------------------------
; Return zero flag, NZ = Shift
;======================================
USB_KBD_StatusFlagsHandlePress:
M_Vars
M_Arg bios_key_code, S_WORD

M_Code
push eax
push bx
push dx

xor dl, dl
mov bx, [.bios_key_code]

push word BDA_KEYBOARD_STATUS_FLAGS
call BDA_GetByte ; (word offset)

cmp bh, 45h ; Num Lock Scan Code
jne .check_caps_lock

xor al, b(BDA_KBD_NUM_LOCK_ON)
jmp .update_bda

.check_caps_lock:
cmp bh, 3Ah ; Caps Lock Scan Code
jne .done

xor al, b(BDA_KBD_CAPS_LOCK_ON)

.update_bda:
push ax
push word BDA_KEYBOARD_STATUS_FLAGS
call BDA_SetByte ; (word offset, word value)
mov dl, 1

.done:
; Return zero flag
or dl, dl

pop dx
pop bx
pop eax
M_Ret


;======================================
;void USB_KBD_HandleReports (dword device, dword current_report, dword previous_report)
;--------------------------------------
; Compare previous report with the current report to find
; the keys that have been pressed and released.
;======================================
USB_KBD_HandleReports:
M_Vars
M_Arg device, S_DWORD
M_Arg current_report, S_DWORD
M_Arg previous_report, S_DWORD

M_Local report_code, S_WORD

M_Code
push eax
push ecx
push edx
push esi
push edi

mov esi, [.current_report]
mov edi, [.previous_report]

;===============================
; Handle Modifier Keys.
;===============================
; Update BDA Flags on change.
; Related bytes:
; 0 Flag byte
; 1 Reserved
;-------------------------------

mov al, [fs:esi]
cmp [fs:edi], al
je .no_change


%ifdef USB_KBD_DEBUG_KEY
M_Printf "Modifier Keys: "
call PrintHex8
M_PrintfNL ""
%endif
push ax
call USB_KBD_BDA_SetModifierFlags ; (word kbd_flags)

.no_change:


;===============================
; Scan Keycode 1-6 for press.
;===============================
; Check: Key is in new report, but not in previous report.
; Related bytes: 2 to 7
;-------------------------------

; Start with offset of Keycode 1, current report.
mov ecx, 2
.loop_press_current:
mov al, [fs:esi + ecx]
or al, al
je .no_key_data_press

; Start with offset of Keycode 1, previous report, old keys.
mov edx, 2
.loop_press_previous:
; Is the key from the previous report in the current report?
; If yes -> skip, key was pressed.
cmp [fs:edi + edx], al
je .key_was_pressed

; Next key in previous report.
inc dl

; End of report reached?
cmp dl, USB_KEYBOARD_REPORT_SIZE
jne .loop_press_previous

; Key is not in the previous report -> Key pressed.

%ifdef USB_KBD_DEBUG_KEY
M_Printf "Key press: "
call PrintHex8
M_Printf " "
%endif
mov [.report_code], al

; Get SCAN CODE|ASCII CODE to AX
push word [.report_code]
call USB_KBD_TranslateToBiosCode ; (word kbd_scan_code)

push word ax
call USB_KBD_StatusFlagsHandlePress ; (word bios_code)
je .skip_leds

push dword [.device]
call USB_KBD_SyncLedsWithBDA ; (dword device)

.skip_leds:

%ifdef USB_KBD_DEBUG_KEY
call PrintHex16
M_Printf " "
call PrintChar
M_PrintfNL ""
%endif

xchg ah, al ; Scan Code to AL
and al, 7Fh ; Remove bit 8
call KBD_AddScanCodeToBuffer

.key_was_pressed:
.no_key_data_press:

; Next key in current report.
inc cl

; End of report reached?
cmp cl, USB_KEYBOARD_REPORT_SIZE
jne .loop_press_current



;===============================
; Scan Keycode 1-6 for release.
;===============================
; Check: Key is in previous report, but not in current report.
; Related bytes: 2 to 7
;-------------------------------

; Start with offset of Keycode 1, previous report, old keys.
mov ecx, 2
.loop_release_previous:
mov al, [fs:edi + ecx]
or al, al
je .no_key_data_release

; Start with offset of Keycode 1, current report.
mov edx, 2
.loop_release_current:
; Is the key from the current report in the previous report?
; If yes -> skip, key is still pressed.
cmp [fs:esi + edx], al
je .key_is_still_pressed

; Next key in current report.
inc dl

; End of report reached?
cmp dl, USB_KEYBOARD_REPORT_SIZE
jne .loop_release_current

; Key is not in the current report -> Key released.

%ifdef USB_KBD_DEBUG_KEY
M_Printf "Key released: "
call PrintHex8
M_PrintfNL ""
%endif

.key_is_still_pressed:
.no_key_data_release:

; Next key in previous report.
inc cl

; End of report reached?
cmp cl, USB_KEYBOARD_REPORT_SIZE
jne .loop_release_previous

pop edi
pop esi
pop edx
pop ecx
pop eax
M_Ret


;======================================
;void USB_KBD_BDA_SetModifierFlags (word kbd_flags)
;======================================
USB_KBD_BDA_SetModifierFlags:
M_Vars
M_Arg kbd_flags, S_WORD

M_Code
push eax
push bx

; Get current keyboard status flags from the Bios Data Area
push word BDA_KEYBOARD_STATUS_FLAGS
call BDA_GetWord

; Clear flags that might be set
and ax, ~( b(BDA_KBD_CTRL) | b(BDA_KBD_SHIFT_LEFT) | b(BDA_KBD_SHIFT_RIGHT) | \
b(BDA_KBD_ALT) | b(BDA_KBD_ALT_LEFT) | b(BDA_KBD_ALT_RIGHT) )

mov bl, [.kbd_flags]

; Detect flags.
test bl, b(USB_KBD_LEFT_CTRL)
je .1
or al, b(BDA_KBD_CTRL)

.1:
test bl, b(USB_KBD_RIGHT_CTRL)
je .2
or al, b(BDA_KBD_CTRL)

.2:
test bl, b(USB_KBD_LEFT_SHIFT)
je .3
or al, b(BDA_KBD_SHIFT_LEFT)

.3:
test bl, b(USB_KBD_RIGHT_SHIFT)
je .4
or al, b(BDA_KBD_SHIFT_RIGHT)

.4:
test bl, b(USB_KBD_LEFT_ALT)
je .5
or al, b(BDA_KBD_ALT)
or ah, b(BDA_KBD_ALT_LEFT)

.5:
test bl, b(USB_KBD_RIGHT_ALT)
je .6
or al, b(BDA_KBD_ALT)
or ah, b(BDA_KBD_ALT_RIGHT)

.6:
; Write back to the Bios Data Area
push ax
push word BDA_KEYBOARD_STATUS_FLAGS
call BDA_SetWord

pop bx
pop eax
M_Ret


;======================================
;word USB_KBD_TranslateToBiosCode (word kbd_scan_code)
;--------------------------------------
; Return:
; AL = ASCII Char
; AH = Scan Code
;======================================
USB_KBD_TranslateToBiosCode:
M_Vars
M_Arg kbd_scan_code, S_WORD

M_Code
push esi

movzx eax, byte [.kbd_scan_code]
cmp al, USB_KBD_TRANSLATION_TABLE_LAST_USB_CODE
ja .unsupported_code

shl eax, 2
mov esi, USB_KBD_TRANSLATION_TABLE - 4 * 4
add esi, eax

; Get PS/2 Scan Code.
mov ah, [esi + 3]

; Get ASCII and check shift and caps lock.
call KBD_HasShift
je .no_shift

inc esi ; Use shift column.

.no_shift:
mov al, [esi]

jmp .done

.unsupported_code:
mov ax, 0

.done:
pop esi
M_Ret


USB_KBD_TRANSLATION_TABLE:
%include "usb/hid/codes/code_table.inc"
; Recalculate the last code: The table has 4 bytes per row and starts with the code 4
USB_KBD_TRANSLATION_TABLE_LAST_USB_CODE equ ($ - USB_KBD_TRANSLATION_TABLE) / 4 + 3

Download: usb_kbd.inc, code_table.inc


2018-12-15  -  Status update - ISO 9660 File System, Boot Menu


The ISO 9660 file system has been implemented quickly two weeks ago. What a nice file system. My driver supports also the Rock Ridge extension. That means long file names and so on.

Currently I am working on the menu. A few boot modes are now working, but you have to wait for a test release!

As in the Plop Boot Manager, there is a fallback mode to an amazing text mode 80x50. See the screen shot. There will be also a Plop Boot Manager theme with the modified borders.


Using the menu

When you press Enter at the drive entry, then the device will be booted in the standard way. This is for hard disks the MBR, for CDROMs the boot volume and for floppies the boot sector.
When you press the key "right" on menu entries with ">", then you open a context menu. So you can also boot a partition (as the hotkey "q" in the Plop Boot Manager) and view the device information.

Pressing key right.

I know, it looks similar to the graphic mode, but its text mode and this is the amazing part, as it was in the Plop Boot Manager :)

The binary size is currently 57 KB. Without textures, no USB, but native IDE and SATA and a lot of other important things. I have to be careful to add one driver after another. The USB drivers needs some adaptions and will be added later.

Note: I saw the new features of Blender and also the new features of the Unity Game Engine. Wow, especially Blender!!! I have to finish the boot manager to continue with my Armored Eye Story/Game. Cyberpunk :)


2018-11-29  -  Loader for CDROM


Implementing the loader to start the boot manager from CDROM was quite easy. Now continuing with the ISO 9660 file system. Its a simple file system and I am sure, I will need it later. Great to see that old and simple concepts like ISO 9660, El Torito and also FAT FS are still important nowadays.


2018-11-27  -  Window based menu system


USB HUB driver

The driver for USB 1.1 works fine. The driver for USB 2.0 is left to do.


Window based menu

I wrote routines for a window based menu system. As the Plop Boot Manager, it supports text and graphic mode, various resolutions (also wide screen), various fonts.

The new system supports background images and textures with alpha support to enable window shadows.


Todo

• Theme system to customize the look easily.
• Custom fonts.
• Font upscale on high resolutions.
• Window animation.
• Dynamic background.
• And a few other things...

This is a list of the functions from the current window library.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
dword W_GetX (dword object)
dword W_GetY (dword object)

byte W_GetType (dword object)
dword W_GetParent (dword object)
void W_SetIsActive (dword object, word status)
bool W_IsActive (dword object)


dword W_CreateWindow (word x, word y, word width, word height, word color, dword texture)
void W_WindowAddItem (dword window, dword item)

void W_DrawWindowNoBorders (dword window)
void W_DrawWindowWithBorders (dword window)
void W_DrawWindowWithTexture (dword window)
void W_ClearWindow (dword window)


dword W_CreateString (dword parent, word x, word y, word color, dword string)
void W_DrawString (dword string)
void W_DrawStringColor (dword string, word color)


dword W_CreateMenu (dword window, word x, word y, word width, word color, word bar_color)
void W_MenuAddItem (dword menu, dword item)
dword W_MenuAddEntry (dword menu, dword string, dword function, word barskip, dword data)
void W_MenuMoveBar (dword menu, word action)
void W_MenuUpdateItemsXY (dword menu)
void W_DrawMenu (dword menu)
dword W_MenuGetActiveEntry (dword menu)
void W_MenuRunEntryFunction (dword menu)


void W_Main (dword menu)


void W_Draw (dword object)
void W_DrawAll()


dword W_CreateBackground ()
void W_DrawBackground (dword dummy)


void W_DestroyMenuEntry (dword entry)
void W_DestroyString (dword string)
void W_Destroy (dword object)


Hello world window code sample

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    ; Create the window object
push dword [.window_texture]
push word COLOR_BG (COLOR_GREEN) | COLOR_WHITE ; Background color | Foreground color
push word 20
push word 50
push word 10
push word 10
call W_CreateWindow ; (word x, word y, word width, word height, word color, dword texture)
jc .error

mov [.window], eax


; Add a string to the window.
; Use text color from the parent window.
push dword TxtHelloWorld
push word 1
push word 2
push dword [.window]
call W_CreateString ; (dword window, word x, word y, dword string)
jc .error

mov [.wstring], eax


; Draw all objects
call W_DrawAll


; Main loop, wait for input and handle menu system.
; This sample has no menu.
push dword 0
call W_Main ; (dword menu)


; Remove the window and free the memory of the window and its childrens.
push dword [.window]
call W_Destroy ; (dword object)


I am coming closer to put all together. The window based menu system is good enough for the moment. It will be improved later. Now, I focus on booting. I have to write a simple loader to start the menu from CD-ROM.


2018-10-05  -  USB HUB driver status - continued


Device enumeration works. The driver works for USB 1.1.

Next: Improving and cleanup the code. Do some testing. Add support for USB 2.0 to the driver.


2018-10-04  -  USB HUB driver status


The USB HUB driver is still under development. Yesterday, I found myself in some kind of a dead end. The HUB worked and I was able to enumerate a fresh connected device. But my code was not good enough to run in an Interrupt Service Routine (ISR). Today, I rewrote mostly and now I am a big step forward. Device connect/disconnect on any port is recognized in the ISR. Device enumeration does not work at the moment, but this comes tomorrow.

Here are two pictures of my current test machine running the HUB driver. It is my old Gericom Webboy, bought (I think) in the year 2000.


2018-09-18  -  UHCI, USB HUB, Synthetic DNA Menu


For a long time nothing Boot Manager related happened. But last week, I made the required code update for the UHCI driver. Then I started to write the USB HUB driver. For testing, I want an USB HUB that supports only USB 1.1. I gave my old USB 1.1 HUB away for a few cents many years ago :(. So bought and received a new one last week.


Last week (Thursday), I also had an idea about an extra ordinary menu. The Synthetic DNA Menu. I realized a concept with Blender. But it's only an idea/dream. Too heavy for a boot manager that has only some basic 3D processing routines. It's just a boot manager :) Maybe, I use this menu with the Armored Eye project. More about the Synthetic DNA Menu is here.

Video

External content blocked. Watch on YouTube

Images


2018-08-07  -  USB mass storage with UHCI/EHCI and the USB floppy drive


The mass storage function call synchronization for UHCI, OHCI and EHCI is almost complete. Hard disks, thumb drives and CDROM drives are working fine with the same function calls for all three controller types.

My USB 1.1 floppy drive did not work on OHCI and UHCI. My fault was to ignore the Interface Protocol value from the device. This drive has to be accessed in another way than Bulk-Only drives. You have to send the ATAPI Command Block over the Control Endpoint and send/receive the data over the Bulk Endpoints. Now, the floppy drive access works fine for OHCI. Some code cleanup and updating the UHCI code is needed.

What comes after the code update? There is still the USB HUB driver missing. The USB keyboard driver needs a lot of updates.


2018-07-24  -  USB DVD drive


The first work I did today was to check why the USB DVD drive did not work. I found the problem quickly. I allocated only 512 bytes instead of 2048 bytes for the sector read destination buffer. 2048 bytes is the block size of CD ROMs. Because of the wrong size there was overlapped memory that created invalid data. The invalid data was the reason for the drive reset. Now the drive works perfect.

The USB Floppy drive still makes problems. I have to check whats going on on the USB bus. But now there is some work to do for EHCI and UHCI.


2018-07-23  -  Just a status update


I synchronized the OHCI and EHCI code that the access to the shared USB functions works in the same way. UHCI is left to synchronize. The base programs for those drivers lived in their own environment and function calls changed during development. Word sized parameters became dword size, here and there is an additional parameter required. Assembler is not flexible as a high level language, even with my macros ;). So you have to take care by yourself to submit the correct parameters in the correct size to a function call. That means more and overall a clean work, but at the end its also more fun for the software developer, in a funny or strange matter ;).

I also cleaned up and simplified the USB Bulk driver, needed to access mass storage devices. I added nearly all required functions like inquiry, read capacity, read sector, write sector and so on. It works fine with the OHCI driver and hard disks/thumb drives. I also tried my USB Floppy Drive and USB DVD Drive. Unfortunately, one drive hung and the other resets itself. In other words, both did not work. That's life. It was a bit disappointing, but I will fix it. For EHCI, I have to update the USB Pipe logic and then test the bulk driver. But that comes later.


2018-07-21  -  ReactOS/FreeLoader/Plop Boot Manager


It has partially to do with the new boot manager. But its also important. I created a dirty fix to start the Plop Boot Manager from the FreeLdr boot menu. It has to be tested.

See https://forum.plop.at/index.php/topic,1840.msg7424.html


Some notes about ReactOS

ReactOS error message "Userinit failed to start the installer!". You are using the wrong ReactOS CD for installation. Don't use the ReactOS Live CD, choose the other one.

ReactOS boot error message "hive header failed" or blue screen. Maybe your virtual hard disk is too small. Use at least a size of 4 GB.


2018-07-11  -  USB OHCI driver 16/32 bit test


Today, I tested my USB OHCI code in my 32 bit environment. The code was written and tested in a 16 bit environment. The plan was/is to run the code in 16 and 32 bit CPU mode. In this experimental stage, the driver is not loaded dynamically. I had to prepare and hard code a few things and then.... It gave me a chill! It was great to see that the code worked fine in the same way as in the 16 bit environment. I am really happy :)

Note: 16/32 bit code runs also on a 64 bit CPU.


2018-07-09  -  USB OHCI driver implementation


I started to add the USB OHCI routines to the boot manager test program as a driver. I was struggling for many hours with a mysteries bug. Finally I fixed the bug (again). The bug was an old "friend". Elmar, just set the device as PCI bus master! Rolling eyes! That was the problem. That hurts. Okay, now I can continue with the driver stuff. There are still tests and a stable workflow required to implement a dynamic driver loading. The OHCI routines have to be tested in various CPU modes too. Its time for a Pizza...


2018-07-06  -  Minor updates


I finished only a few things. INT 13h hook for drive swapping works fine. I extended the FAT read support to FAT12 and FAT32.


2018-06-18  -  FAT16, Linux Kernel, NTLDR


No update since one month. What happened? Nothing special. Just some booting. But don't expect too much!

FAT16 reading works fine. I can change directories and read files. FAT16 writing and FAT12/32 support is left to do. But with the FAT16 reading support, I was able to do some interesting things.

Native Linux Kernel booting works (from FAT16). I can load the kernel and an initrd file and boot Linux. I can also set the Linux Kernel Command Line.

Native Windows XP booting with direct loading of the NTLDR works (from FAT16). More recent Windows booting should work too. That's not an important feature, but nice to have.

MBR loading and booting works too.


What comes next? There are still a lot of things to do. I am far away from any beta testing. Many things that are working are splitted up in own parts and have to put together. But this comes later.

Next steps are

• Boot sector loading and booting. That should not be difficult.
• Writing various loaders to start the Boot Manager Test Program from different locations (MBR, boot sector, floppy, CDROM, ...).
• FAT16 write support.
• FAT12/32 support.
• Some INT 13h hooks for testing. For example drive swapping to boot from the second hard disk.
• Trying to add the USB drivers carefully.
• Looking forward to Ext and NTFS drivers.
That's a heavy to-do list for the next steps!


2018-05-07  -  Are you dreaming in hex?


Maybe sometimes! Hexadecimal is part of my life. File Allocation Table Artwork :)

Dreaming in hex

I started with FAT file system support. Currently required for native Linux kernel loading tests. The boot manager will need FAT support too. I began with FAT16. Directory listing works. Of course with long file name support (optional only 8.3 format). Cluster reading works too. Next step is a working "read file" routine. And then modify the code for FAT12 and FAT32.


2018-05-03  -  MBR Partition Table / GUID Partition Table


The Master Boot Record partition table support has been finished. Classic and cascaded extended partitions are supported. Now, I am numbering the partitions in the same way as Linux. Primary partitions get a number from 1 to 4, according to the position in the partition table. The first logical partition starts with 5.

I also wrote the support for GUID Partition Tables (GPT).

All various partitions are accessed by the same shared ReadSector/WriteSector function call. It works very well :)


2018-04-28  -  Drive access layer


I did some code cleanup and various fixes. I also added a layer to access various drives with the same function call. Now it doesn't matter if its a DVD drive or a hard disk (floppy is not done yet). The drives are registered during PATA/SATA enumeration. I also added a simple support for the classic MBR to access primary partitions. The partitions are registered too and can be also accessed by a shared function call. Full MBR support and GPT support will be implemented on Monday/Thursday.

Read boot sector of partition 1 from drive 3.
Note: Drive number and partition number starts with "0".

1
2
3
4
5
6
7
8
9
10
11
12
    push dword 512
call MEM_Allocate
jc .error
mov dword [.buffer], eax

push eax
push word 1
push dword 0
push word 0
push word 2
call PReadSector28 ; (word drive_number, word partition_number, dword lba, word num_sectors, dword buffer)
jc .error


Drive registration. Using wrapper functions for standardized calls. Dynamic registering for USB drives is not done yet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    M_PrintfNL "SATA device found."

push word ATA_CMD_IDENTIFY
push esi
call AHCI_Identify ; (dword port_address, word identify_command)
jc .check_for_atapi
mov [.identify], eax

; Register drive
push esi
push word 0
push word 0
push dword AHCI_Write28Wrapper
push dword AHCI_Read28Wrapper
push word 512
push dword [.identify]
push word DRIVE_SATA
call RegisterDrive ; (word drive_type, dword identify, word bytes_per_sector,
; dword read_sector_28, dword write_sector_28,
; word pata_channel, word pata_drive,
; dword ahci_port)

Current drive register routine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
;=====================================
;dword RegisterDrive (word drive_type, dword identify, word bytes_per_sector,
; dword read_sector_28, dword write_sector_28,
; word pata_channel, word pata_drive,
; dword ahci_port)
;-------------------------------------
;Returns drive structure address
;Carry on error
;=====================================
RegisterDrive:
M_Vars

M_Arg drive_type, S_WORD
M_Arg identify , S_DWORD

M_Arg bytes_per_sector, S_WORD

M_Arg read_sector_28 , S_DWORD
M_Arg write_sector_28, S_DWORD

M_Arg pata_channel, S_WORD
M_Arg pata_drive , S_WORD

M_Arg ahci_port, S_DWORD

M_Local drive, S_DWORD

M_Code
push ebx
push edi

mov dword [.drive], 0

; Allocate memory for the drive structure
push dword SYS_DRIVE.size
call MEM_Allocate
jc .error

mov edi, eax ; edi became the drive address
mov [.drive], eax

; Fill the structure
mov word [fs:edi + SYS_DRIVE.wType], SYS_TYPE_DRIVE

mov bx, [.drive_type]
mov [fs:edi + SYS_DRIVE.wSubType], bx

mov ebx, [.identify]
mov [fs:edi + SYS_DRIVE.dIdentify], ebx

mov bx, [.bytes_per_sector]
mov [fs:edi + SYS_DRIVE.wBytesPerSector], bx


mov ebx, [.read_sector_28]
mov [fs:edi + SYS_DRIVE.dReadSector28], ebx

mov ebx, [.write_sector_28]
mov [fs:edi + SYS_DRIVE.dWriteSector28], ebx


mov bx, [.pata_channel]
mov [fs:edi + SYS_DRIVE.wChannel], bx

mov bx, [.pata_drive]
mov [fs:edi + SYS_DRIVE.wDrive], bx

mov ebx, [.ahci_port]
mov [fs:edi + SYS_DRIVE.dAHCI_Port], ebx

call GetFreeDriveNumber
jc .error
mov [fs:edi + SYS_DRIVE.bDriveNumber], al


; Add the drive to the drives list
mov ebx, SYS_RAM
add ebx, SYS_KERNEL.dDrives

push edi
push ebx
call LIST_AddEntry ; (dword list, dword entry)
jc .error

; Return drive address
mov eax, edi
jmp .done

.error:
; Release allocated memory
push dword [.drive]
call MEM_Free

; Set carry for error
stc

.done:
pop edi
pop ebx
M_Ret


2018-04-19  -  ATAPI CDROM drive drivers


The ATAPI drivers for IDE (PATA) and AHCI (SATA) for CDROM (and similar) drives are almost done. There is a strange behavior with the AHCI ATAPI driver. The first ATAPI command ends in an error. After this, all tested ATAPI commands are working fine. At the moment, I have no idea why the first command fails.

Drivers tested only on two machines.
BIOS INT 13h implementation is not done.


2018-03-28  -  Relocate addresses for program/driver loading


For long time, nothing important happened. Now, I spent two days for a simple address relocation system which is needed to support dynamic loading of programs and drivers.

I wrote two PHP scripts which are analyzing the list file, generated by NASM with the '-l' parameter.

The first PHP script (syscalls.php) generates a file with jumps to the kernel system functions (syscalls.inc). This generated file is included by the program/driver (my_program.asm) to make it easy to call the kernel functions. NASM generates all addresses according to the ORG command. Those addresses must be updated when the program/driver has been loaded into the memory.

The second PHP script (relocate.php) creates a file with two tables (relocate_table.inc). This tables are holding the positions of all addresses used by the program/driver. This file has to be included too.

The addresses, which are now stored in the header of the program, are updated by a simple routine in the kernel (relocation code), before the kernel can start the program.

Here is an overview with source codes. It may change in the future. It is just the first version. Maybe it looks difficult, but I tried to keep it simple. Explaining is not my strength.


Sample code to load a program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    ; Allocate memory for the program                
push dword [.file_size]
call MEM_Allocate
jc .error

mov [.address], eax

; Load the program
push dword [.address]
push dword [.file_size]
push dword [.file_name]
call SYS_LoadFile
jc .error

; Update addresses
push dword [.address]
call PROGRAM_AddressRelocate

; Start the program
call dword [.address]


Simple program header:

1
2
3
4
5
6
7
8
9
10
11
struc PROGRAM_HEADER                                 

.jump resb 5
.align_bytes resb 3

.reloc_table_syscalls_size resd 1
.reloc_table_local_size resd 1

.reloc_table_syscalls:

endstruc


Address relocation code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
;=====================================
;void PROGRAM_AddressRelocate (dword program_address)
;=====================================
PROGRAM_AddressRelocate:
M_Vars
M_Arg program_address, S_DWORD

M_Code
push ebx
push ecx
push esi
push edi

; Address of the relocation table.
mov esi, [.program_address]
add esi, PROGRAM_HEADER.reloc_table_syscalls

; Get number of syscall addresses.
mov ebx, [.program_address]
mov ecx, [ebx + PROGRAM_HEADER.reloc_table_syscalls_size]
shr ecx, 2 ; We have 4 byte addresses, so divide with 4.
je .skip_syscall_addr ; Skip if we have no address.

.relocate_syscall_addr_loop:
; Get the address in the program.
mov edi, [esi]

; All syscall addresses are lower than the program address.
; Substract the program memory address to restore the kernel address.
sub dword [ebx + edi], ebx

; Next entry.
add esi, 4
dec ecx
jne .relocate_syscall_addr_loop

.skip_syscall_addr:

; The table with the program addresses comes directly after the syscall table,
; there is no need to set ESI.

; Get number of program addresses.
mov ecx, [ebx + PROGRAM_HEADER.reloc_table_local_size]
shr ecx, 2 ; We have 4 byte addresses, so divide with 4.
je .skip_program_addr ; Skip if we have no address.

.relocate_program_addr_loop:
; Get the address in the program.
mov edi, [esi]

; All addresses have to be set relative to the new memory address of the program.
; Add the program memory address.
add dword [ebx + edi], ebx

; Next entry.
add esi, 4
dec ecx
jne .relocate_program_addr_loop

.skip_program_addr:

pop edi
pop esi
pop ecx
pop ebx
M_Ret


Sample syscalls.inc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
; 0000003D MEM_Allocate:                             
MEM_Allocate:
jmp 0000003Dh

; 000000FE MEM_AllocateAligned:
MEM_AllocateAligned:
jmp 000000FEh

;----------- SNIP ---------------

; 00000FCC PrintHex16p:
PrintHex16p:
jmp 00000FCCh

; 00000FFC PrintHex16:
PrintHex16:
jmp 00000FFCh

; 0000100F PrintHex32:
PrintHex32:
jmp 0000100Fh

; 00001021 PrintInt8:
PrintInt8:
jmp 00001021h


Sample program (my_program.asm):
Command: nasm -f bin my_program.asm -o my_program.bin -l my_program.lst

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
%include "sys32/sys32.inc"

%define STRING_END 0
%include "macro/printf.inc"

[ORG 0h]
; Simple program header
jmp start ; Initial jump
db 0, 0, 0 ; Align bytes

%include "relocate_table.inc"

%include "syscalls.inc"

var1 dw 3344h ; Sample variable

;======================
; Program start
;======================
start:

; Use a kernel function
push word [var1]
call PrintHex16p

; Start a function of the program
call TestRoutine

; End program
ret


TestRoutine:

; Use kernel system print
M_PrintfNL "Test"

; Use another system call
mov ax, [var2]
call PrintHex16

ret

var2 dw 2244h ; Sample variable


Simple PHP script to export kernel function calls (syscalls.php):
Command: php syscalls.php kernel.lst > syscalls.inc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php/*    Generate jump instructions for kernel system calls.    Source file is the list file generated by NASM with -l.    Written by Elmar Hanlhofer 2018/03/28    Free to use.        Using: php syscalls.php kernel.lst > syscalls.inc*/    if (!$argv[1])    {        die ("No input file!");    }    $f = file ($argv[1]);    foreach ($f as $v)    {        $v = str_replace ("\n", "", rtrim ($v));        $line_nr = substr ($v, 0, 7);        $addr    = trim (substr ($v, 7, 8));        $opcode  = substr ($v, 16, 19);        $asm     = trim (substr ($v, 40));        if (strpos ($asm, ":") && ($asm[0] == strtoupper ($asm[0]))) // Use only labels which have                                                                      // an upper char at the beginning        {            $label = $asm;        }        if (strpos ($opcode, "<") !== false)        {            unset ($label);        }        if ($addr && $label)        {            if (strpos (" .;%", $label[0]) === false) // Skip various            {                echo "; $addr $label\n";                echo "$label\n";                echo "    jmp $addr" . "h" . "\n\n";            }            unset ($label);        }    }    echo "SYSCALLS_End:\n\n";// Sample input://    87                              <1> MEM_Allocate://    93 0000003D C8040000            <1>     M_Code?>


Simple PHP script to create the relocation table (relocate.php):
Command: php relocate.php my_program.lst > relocate_table.inc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php/*    Generate the relocation address table.    Source file is the list file generated by NASM with -l.    Written by Elmar Hanlhofer 2018/03/28    Free to use.        Using: php relocate.php my_program.lst > relocate_table.inc*/define ("SYSCALLS_END", "SYSCALLS_End:"); // Marker, written by syscalls.phpfunction TableEntry ($code_addr, $opcode, $char_begin, $char_end, $address_size){    if ($offset_addr = strpos ($opcode, $char_begin)) // Is there an address in the opcode?    {        $end  = strpos ($opcode, $char_end);        $size = $end - $offset_addr - 1;        if ($size == $address_size) // Is it the requested size?        {            echo "    dd 0$code_addr" . "h + " . ($offset_addr / 2) . "\n"; // OPCODE COMMAND + POSITION OF ADDRESS                                                                            // div 2 because 1 byte is 2 chars        }    }}    if (!$argv[1])    {        die ("No input file!");     }        $f = file ($argv[1]);        echo "RelocateTableSize_Syscalls dd RelocateTableEnd_Syscalls - RelocateTableStart_Syscalls\n";    echo "RelocateTableSize_Local    dd RelocateTableEnd_Local    - RelocateTableStart_Local\n\n";    echo "RelocateTableStart_Syscalls:\n";    foreach ($f as $v)    {        $v = str_replace ("\n", "", rtrim ($v));                $line_nr = substr ($v, 0, 7);        $addr    = trim (substr ($v, 7, 8));        $opcode  = substr ($v, 16, 19);        $asm     = substr ($v, 40);        if ($asm == SYSCALLS_END) // End of syscalls reached?        {            break;        }        // Build the table for the syscall addresses        TableEntry ($addr, $opcode, "(", ")", 8);        TableEntry ($addr, $opcode, "[", "]", 8);           }    echo "RelocateTableEnd_Syscalls:\n\n";        $syscalls = true;    echo "RelocateTableStart_Local:\n";    foreach ($f as $v)    {        $v = str_replace ("\n", "", rtrim ($v));                $line_nr = substr ($v, 0, 7);        $addr    = trim (substr ($v, 7, 8));        $opcode  = substr ($v, 16, 19);        $asm     = substr ($v, 40);        if ($asm == SYSCALLS_END) // End of syscalls reached?        {            $syscalls = false;        }                if (!$syscalls) // Build the table for program addresses        {                    TableEntry ($addr, $opcode, "(", ")", 8);            TableEntry ($addr, $opcode, "[", "]", 8);        }    }    echo "RelocateTableEnd_Local:\n";?>


2017-12-29  -  NASM Helper


At the beginning of the new boot manager development, I wrote some macros to make the use of function calls easier in Assembler. The macros are written for NASM. Now, I released them under the name "NASM Helper".

NASM Helper

At the bottom of the page, you will find a complex routine called QueueControlTransfer. Its from my OHCI USB driver. I know, its useless without the other functions, but its a nice example for a more complex function.


2017-12-20


OHCI Enumeration bug fixed.

Rewriting UHCI code done.


2017-12-18  -  Bug killed


I found the bug, without converting the old code. I figured out that the host suddenly stopped sending frames. Very mysterious. Finally I found the reason for this behavior. Unintentionally, I set the USB port into suspend mode. I used "OR" to write a bit, without modifying the other bits, in the port register. But for this register, its required to set the bit with "MOV" without other bits set. The strange thing is, that the "OR" works on other hardware, which seem to be more tolerant in this case. This bug wasted a lot of time, but it works now. Now there is a new issue with the enumeration process on that machine, but it should not be difficult to fix it.

Asking again, is the code from 2007 better? No, the new code is better now :)


2017-12-16  -  Hmm, bugs


Hmm, what should I say. I hoped to have finished a lot of things. But I didn't. I was ill in November. Then I had various things to do in the rest of November and in December. And now I am struggling with a crazy "new boot manager" driver bug since a week. Its the OHCI USB driver. I thought it works fine, but then I used it on my old Gericom Webboy Laptop. A simple USB resquest ends in a DeviceNotResponding error. The frustrating thing is, my driver of 2007 works flawless. I cannot figure out whats wrong. Data structures and register values are the same. Frustrating. I am not able to fix that for one week!!!! The old code was written for LZASM. Now I am using NASM. Since days I try to find the bug without converting the old code to NASM. But I fear, I reached the point to accept that I have to convert the old code to find the difference....

Is the code from 2007 better? Hmmm, yes and no.


2017-10-13  -  What do I have so far


Its time for a development status.

The code is written in pure assembler. I am using NASM. The goal is to operate in various CPU modes on i386 CPUs and better. Most of the code is currently tested in the 'unreal mode' (16/32 bit). With just a few modifications, the code will run in native 32 bit too. This code will also run fine on 64 bit CPUs.

The device access (except video mode switching) happens native without BIOS. This is required to work in various CPU modes in the same way, regardless if I have a BIOS in the background or not. Why do I need various CPU modes? Because I want to support old and modern computers. DOS should be able to use the boot manager drivers without additional software. But don't dream about DOS and UEFI. This will not work.

Basic system routines

Memory management: Done.
PCI device enumeration: Done.
CPU mode switching: Done.
Basic text mode output routines: Done.
Graphic mode (VBE): Mode detection, initialization, pixel drawing, text drawing done.
Image files: Reading and display TIFF images done. TIFF format: uncompressed, RGB, Intel.

Driver development stage 1

Keyboard PS/2: Key read done.
PATA (IDE) HDD: Read and write.
PATA (IDE) optical drives: Not done.
SATA AHCI HDD: Read and write.
SATA AHCI optical drives: Not done.
Classic floppy drive: Not done.
USB 1.1 UHCI: Most done, but I am unhappy with the code. I have to rewrite the most.
USB 1.1 OHCI: Initialization, control transfers, interrupt transfers, bulk transfers, USB device enumeration done. Some things are left to do.
USB 2.0 EHCI: Initialization, control transfers, bulk transfers, USB device enumeration done. Lets say over 50% is done. Difficult things like split transactions and other things are left to do.
USB 3.x: Not started.
USB Keyboard: Detection and key read works. TODO: Key mapping.
USB Mass Storage: Basic functions like device identify works. This implementation shouldn't be a big deal.
USB HUB: Starting in the next days.

What means development stage 1? In this stage the drivers are working in their own environment. But its too early to put them together.


2017-10-06  -  A driver development adventure


Last week I started to write the USB 2.0 EHCI driver from scratch. Everything looked fine and worked as expected, but then I tried it with VirtualBox. You know, the Plop Boot Manager 5.0.x hangs when you use the USB 2.0 EHCI driver to boot from USB in VirtualBox. I tried my new code and ........... it hangs too.

I said okay, I try to figure out whats wrong. I am motivated and I want to fix this problem. Then I struggled with the problem for one week. It was frustrating. The queue heads haven't been processed. Only malformed queue heads resulted in a transaction error. But nothing happened on correct queue heads with correct transfer descriptors. For some time I thought the port reset is the problem and the USB device is in a problematic state. You have to know, in VirtualBox, the port reset ends immediately after starting the reset. According to the EHCI Specification, the reset has to be ended by the software and not the host. Then I thought that the host cannot transmit to device 0 because the USB device is still configured with an address because of the strange port reset behavior. So I created queue heads for every possible device number. Hmmmm, I received no errors and no transactions. Nothing! When there is no response, then its really frustrating.

Accepting that my code does not work in VirtualBox became an option for me. But finally I can not accept it. Meanwhile it looks like I am in an endless loop. Doing the same things with the same disappointing result. Then by luck, I made a mistake. And now comes an important information for those who plan to write an EHCI driver. As first transfer descriptor, I linked a transfer descriptor without any data except the 'Next qTD Pointer' to a SETUP transfer descriptor. And suddenly, the SETUP transfer descriptor has been processed as expected. Strange. When the first transfer descriptor is empty, then the following transfer descriptors are processed.

I don't know why, but this works on other EHCI controllers too, so I accept that and I am happy that my code works now also in VirtualBox. I will fix the EHCI driver of the Plop Boot Manager 5.0.15 that the USB 2.0 boot works also in VirtualBox. But thats enough for today.


2017-09-17  -  UEFI


I spent some time for UEFI and created a simple menu to boot Plop Linux and Windows with UEFI. This was just a funny test. There is no dynamic OS detection or config file. All is hard coded, just to see how software development with UEFI works.

External content blocked. Watch on YouTube


2017-07-12


Programming the new boot manager, but it's a slow process. Nothing to show at the moment...


2017-02-12


New development start is April 2017.


2016-07-29


My desk. Developing a driver at night.

During rewriting the USB drivers, I found some bugs in the old code. The chances are good, that I release a 5.1 version of the old 5.0.15 boot manager with fixed USB drivers. But who knows...


2016-06-28


No news, no time to update this page. Coding has been stop at beginning of 05/2016. Maybe I find time in august 2016.


2016-04-22


Continue coding :)


2016-03-14


Coding paused because of other work.


2016-03-13


I created a concept art of the GUI. The final product will look different, but this could be a nice design. No line of code has been written for the GUI, booting has priority ;) A release date is far far away.

There will be also a hidden mode and a simple text mode interface like in the current Plop Boot Manager.


2016-02-02


Work in progress...



© 2024 by Elmar Hanlhofer