Begin NBOOT V2, Cleanup old files
This commit is contained in:
parent
843d3b6c0c
commit
e1696b82e7
25
build.i686
25
build.i686
@ -39,26 +39,28 @@ case $yn in
|
|||||||
echo ----------------
|
echo ----------------
|
||||||
|
|
||||||
sudo losetup -d /dev/loop900
|
sudo losetup -d /dev/loop900
|
||||||
dd if=/dev/zero of=build/main.img bs=512 count=50000
|
dd if=/dev/zero of=build/main.img bs=512 count=2880
|
||||||
mkdir -p build/mnt
|
mkdir -p build/mnt
|
||||||
sudo losetup -P /dev/loop900 build/main.img
|
sudo losetup -P /dev/loop900 build/main.img
|
||||||
sudo parted /dev/loop900 mktable msdos
|
sudo mkfs.fat -F12 /dev/loop900
|
||||||
sudo parted /dev/loop900 mkpart primary fat16 2048s 100%
|
sudo mount /dev/loop900 build/mnt
|
||||||
sudo parted /dev/loop900p1 set 1 boot on
|
|
||||||
sudo mkfs.fat -F16 /dev/loop900p1
|
|
||||||
sudo mount /dev/loop900p1 build/mnt
|
|
||||||
sudo mkdir build/mnt/boot
|
sudo mkdir build/mnt/boot
|
||||||
sudo mkdir build/mnt/boot/grub
|
sudo mkdir build/mnt/boot/grub
|
||||||
sudo mkdir build/mnt/misc
|
sudo mkdir build/mnt/misc
|
||||||
sudo mkdir build/mnt/misc/src
|
sudo mkdir build/mnt/misc/src
|
||||||
sudo cp -r src/* build/mnt/src
|
sudo cp -r src/* build/mnt/misc/src
|
||||||
sudo cp -r grub/* build/mnt/boot/grub
|
sudo cp -r grub/* build/mnt/boot/grub
|
||||||
sudo cp build/nanite.bin build/mnt/boot/nanite
|
sudo cp build/nanite.bin build/mnt/boot/nanite
|
||||||
sudo grub-install \
|
sudo grub-install \
|
||||||
--install-modules="part_msdos gettext all_video gfxterm png normal echo multiboot2" \
|
--install-modules="part_msdos normal echo multiboot2 ls" \
|
||||||
|
--locales=en@quot \
|
||||||
|
--fonts=none \
|
||||||
|
--themes=none \
|
||||||
--boot-directory=build/mnt/boot \
|
--boot-directory=build/mnt/boot \
|
||||||
--target=i386-pc \
|
--target=i386-pc \
|
||||||
--bootloader-id=GRUB \
|
--bootloader-id=GRUB \
|
||||||
|
--allow-floppy \
|
||||||
|
--force \
|
||||||
/dev/loop900 -v
|
/dev/loop900 -v
|
||||||
sudo umount build/mnt
|
sudo umount build/mnt
|
||||||
sudo losetup -d /dev/loop900
|
sudo losetup -d /dev/loop900
|
||||||
@ -86,8 +88,11 @@ case $yn in
|
|||||||
-serial chardev:serial1 \
|
-serial chardev:serial1 \
|
||||||
-audiodev pa,id=speaker \
|
-audiodev pa,id=speaker \
|
||||||
-machine pcspk-audiodev=speaker \
|
-machine pcspk-audiodev=speaker \
|
||||||
-hda build/main.img \
|
-fda build/main.img \
|
||||||
-m size=16M
|
-m size=4M \
|
||||||
|
-vga std \
|
||||||
|
-cpu 486-v1 \
|
||||||
|
-name Nanite
|
||||||
echo --------
|
echo --------
|
||||||
echo Finshed!
|
echo Finshed!
|
||||||
echo --------
|
echo --------
|
||||||
|
|||||||
13
doc/Bootloader.md
Normal file
13
doc/Bootloader.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Bootloader
|
||||||
|
|
||||||
|
Nanite has support for a couple of loaders, including GRUB2 and anything supporting the multiboot2 standard
|
||||||
|
Nanite ALSO has its own custom bootloader called NBOOT, while temporarily abandoned between 2025-2026 its being re-written from scratch.
|
||||||
|
|
||||||
|
## GRUB
|
||||||
|
|
||||||
|
Grub's support is... mixed? its fairly buggy as it falls back on BIOS memory detection (since i can't seem to get multiboot2's mem info block to work...)
|
||||||
|
Its very Useful for testing tho
|
||||||
|
|
||||||
|
## NBOOT
|
||||||
|
|
||||||
|
NBOOT is, experimental and unfinished, looking at it wrong would likely break it.
|
||||||
@ -3,26 +3,15 @@ set default=0
|
|||||||
set pager=1
|
set pager=1
|
||||||
|
|
||||||
insmod part_msdos
|
insmod part_msdos
|
||||||
set root='hd0,1'
|
set root='fd0'
|
||||||
|
|
||||||
set gfxmode=800x600
|
set gfxmode=800x600
|
||||||
insmod all_video
|
|
||||||
set locale_dir=$prefix/locale
|
set locale_dir=$prefix/locale
|
||||||
set lang=en_CA
|
|
||||||
insmod gettext
|
|
||||||
|
|
||||||
terminal_input console
|
terminal_input console
|
||||||
|
|
||||||
insmod gfxmenu
|
|
||||||
# loadfont /boot/grub/themes/nanite/font10.pf2
|
|
||||||
# loadfont /boot/grub/themes/nanite/font12.pf2
|
|
||||||
# loadfont /boot/grub/themes/nanite/font14.pf2
|
|
||||||
# set theme=/boot/grub/themes/nanite/theme.txt
|
|
||||||
# export theme
|
|
||||||
insmod png
|
|
||||||
|
|
||||||
menuentry "NANITE" {
|
menuentry "NANITE" {
|
||||||
set root='hd0,1'
|
set root='fd0'
|
||||||
insmod fat
|
insmod fat
|
||||||
multiboot2 /boot/nanite
|
multiboot2 /boot/nanite
|
||||||
echo "Booting NANITE..."
|
echo "Booting NANITE..."
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,40 +0,0 @@
|
|||||||
# Nanite GRUB 2 Theme
|
|
||||||
|
|
||||||
message-font: "DEFCON Regular 14"
|
|
||||||
message-color: "#FFF"
|
|
||||||
terminal-font: "DEFCON Regular 12"
|
|
||||||
desktop-image: "background.png"
|
|
||||||
desktop-image-scale-method: "crop"
|
|
||||||
|
|
||||||
|
|
||||||
#boot menu
|
|
||||||
+ boot_menu {
|
|
||||||
left = 10%
|
|
||||||
width = 80%
|
|
||||||
top = 20%
|
|
||||||
height = 50%
|
|
||||||
item_font = "DEFCON Regular 12"
|
|
||||||
item_color = "#fff"
|
|
||||||
selected_item_font = "DEFCON Regular 14"
|
|
||||||
selected_item_color= "#f0f"
|
|
||||||
icon_height = 25
|
|
||||||
icon_width = 25
|
|
||||||
item_height = 26
|
|
||||||
item_padding = 0
|
|
||||||
item_icon_space = 0
|
|
||||||
item_spacing = 1
|
|
||||||
scrollbar = true
|
|
||||||
scrollbar_width = 20
|
|
||||||
}
|
|
||||||
|
|
||||||
+ label {
|
|
||||||
top = 100%-25
|
|
||||||
left = 0
|
|
||||||
width = 100%
|
|
||||||
height = 20
|
|
||||||
text = "@KEYMAP_MIDDLE@"
|
|
||||||
align = "center"
|
|
||||||
font = "DEFCON Regular 10"
|
|
||||||
color = "#FFF"
|
|
||||||
bg_color = "#000"
|
|
||||||
}
|
|
||||||
@ -20,18 +20,6 @@
|
|||||||
align 4
|
align 4
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
section .boot
|
|
||||||
extern start
|
|
||||||
global _start
|
|
||||||
_start:
|
|
||||||
push 0
|
|
||||||
popf
|
|
||||||
push ebx
|
|
||||||
push eax
|
|
||||||
call start
|
|
||||||
cli
|
|
||||||
hlt
|
|
||||||
|
|
||||||
section .multiboot
|
section .multiboot
|
||||||
header_start:
|
header_start:
|
||||||
dd 0xe85250d6 ; magic number
|
dd 0xe85250d6 ; magic number
|
||||||
|
|||||||
@ -157,8 +157,8 @@ char kscan() {
|
|||||||
case KEYBOARD_LAYOUT_8: _keyboard_scancode = 0; return '8';
|
case KEYBOARD_LAYOUT_8: _keyboard_scancode = 0; return '8';
|
||||||
case KEYBOARD_LAYOUT_9: _keyboard_scancode = 0; return '9';
|
case KEYBOARD_LAYOUT_9: _keyboard_scancode = 0; return '9';
|
||||||
case KEYBOARD_LAYOUT_0: _keyboard_scancode = 0; return '0';
|
case KEYBOARD_LAYOUT_0: _keyboard_scancode = 0; return '0';
|
||||||
case KEYBOARD_LAYOUT_OEM_MI: _keyboard_scancode = 0; return '-';
|
case KEYBOARD_LAYOUT_OEM_MI: _keyboard_scancode = 0; if(_shift == true) return '_'; else return '-';
|
||||||
case KEYBOARD_LAYOUT_OEM_PL: _keyboard_scancode = 0; return '=';
|
case KEYBOARD_LAYOUT_OEM_PL: _keyboard_scancode = 0; if(_shift == true) return '+'; else return '=';
|
||||||
case KEYBOARD_LAYOUT_BACK: _keyboard_scancode = 0; return '\b';
|
case KEYBOARD_LAYOUT_BACK: _keyboard_scancode = 0; return '\b';
|
||||||
case KEYBOARD_LAYOUT_TAB: _keyboard_scancode = 0; return '\t';
|
case KEYBOARD_LAYOUT_TAB: _keyboard_scancode = 0; return '\t';
|
||||||
case KEYBOARD_LAYOUT_Q: _keyboard_scancode = 0; return 'Q';
|
case KEYBOARD_LAYOUT_Q: _keyboard_scancode = 0; return 'Q';
|
||||||
@ -173,7 +173,7 @@ char kscan() {
|
|||||||
case KEYBOARD_LAYOUT_P: _keyboard_scancode = 0; return 'P';
|
case KEYBOARD_LAYOUT_P: _keyboard_scancode = 0; return 'P';
|
||||||
case KEYBOARD_LAYOUT_OEM_4: _keyboard_scancode = 0; return '[';
|
case KEYBOARD_LAYOUT_OEM_4: _keyboard_scancode = 0; return '[';
|
||||||
case KEYBOARD_LAYOUT_OEM_6: _keyboard_scancode = 0; return ']';
|
case KEYBOARD_LAYOUT_OEM_6: _keyboard_scancode = 0; return ']';
|
||||||
case KEYBOARD_LAYOUT_OEM_5: _keyboard_scancode = 0; return '\\';
|
case KEYBOARD_LAYOUT_OEM_5: _keyboard_scancode = 0; if(_shift == true) return '|'; else return '\\';
|
||||||
case KEYBOARD_LAYOUT_A: _keyboard_scancode = 0; return 'A';
|
case KEYBOARD_LAYOUT_A: _keyboard_scancode = 0; return 'A';
|
||||||
case KEYBOARD_LAYOUT_S: _keyboard_scancode = 0; return 'S';
|
case KEYBOARD_LAYOUT_S: _keyboard_scancode = 0; return 'S';
|
||||||
case KEYBOARD_LAYOUT_D: _keyboard_scancode = 0; return 'D';
|
case KEYBOARD_LAYOUT_D: _keyboard_scancode = 0; return 'D';
|
||||||
@ -183,7 +183,7 @@ char kscan() {
|
|||||||
case KEYBOARD_LAYOUT_J: _keyboard_scancode = 0; return 'J';
|
case KEYBOARD_LAYOUT_J: _keyboard_scancode = 0; return 'J';
|
||||||
case KEYBOARD_LAYOUT_K: _keyboard_scancode = 0; return 'K';
|
case KEYBOARD_LAYOUT_K: _keyboard_scancode = 0; return 'K';
|
||||||
case KEYBOARD_LAYOUT_L: _keyboard_scancode = 0; return 'L';
|
case KEYBOARD_LAYOUT_L: _keyboard_scancode = 0; return 'L';
|
||||||
case KEYBOARD_LAYOUT_OEM_1: _keyboard_scancode = 0; return ';';
|
case KEYBOARD_LAYOUT_OEM_1: _keyboard_scancode = 0; if(_shift == true) return ':'; else return ';';
|
||||||
case KEYBOARD_LAYOUT_OEM_7: _keyboard_scancode = 0; return '\'';
|
case KEYBOARD_LAYOUT_OEM_7: _keyboard_scancode = 0; return '\'';
|
||||||
case KEYBOARD_LAYOUT_RETURN: _keyboard_scancode = 0; return '\n';
|
case KEYBOARD_LAYOUT_RETURN: _keyboard_scancode = 0; return '\n';
|
||||||
case KEYBOARD_LAYOUT_Z: _keyboard_scancode = 0; return 'Z';
|
case KEYBOARD_LAYOUT_Z: _keyboard_scancode = 0; return 'Z';
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
ENTRY(_start)
|
ENTRY(start)
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
.multiboot : { __multiboot_start = .; *(.multiboot)}
|
.multiboot : { __multiboot_start = .; *(.multiboot)}
|
||||||
.notes : { __notes_start = .; *(.notes) }
|
.notes : { __notes_start = .; *(.notes) }
|
||||||
.boot : { __boot_start = .; *(.boot) }
|
.entry : { __entry_start = .; *(.entry) }
|
||||||
.entry : { __entry_start = .; *(.entry) }
|
|
||||||
.text : { __text_start = .; *(.text) }
|
.text : { __text_start = .; *(.text) }
|
||||||
.data : { __data_start = .; *(.data) }
|
.data : { __data_start = .; *(.data) }
|
||||||
.rodata : { __rodata_start = .; *(.rodata*) }
|
.rodata : { __rodata_start = .; *(.rodata*) }
|
||||||
|
|||||||
@ -48,8 +48,6 @@
|
|||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
|
|
||||||
#include <util/param.h>
|
|
||||||
#include <util/util.h>
|
|
||||||
#include <util/binary.h>
|
#include <util/binary.h>
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
@ -67,7 +65,7 @@ extern int uptime; // System uptime measured by precision timer unit.
|
|||||||
uint16_t DEBUG_COM_PORT = COM1_PORT; // COM Port to Output Debug strings to
|
uint16_t DEBUG_COM_PORT = COM1_PORT; // COM Port to Output Debug strings to
|
||||||
|
|
||||||
/*Main Kernel Function*/
|
/*Main Kernel Function*/
|
||||||
void start(unsigned long magic, unsigned long address) {
|
void __attribute__((section(".entry"))) start(unsigned long magic, unsigned long address) {
|
||||||
|
|
||||||
struct multiboot_tag* tag;
|
struct multiboot_tag* tag;
|
||||||
|
|
||||||
@ -121,7 +119,6 @@ void start(unsigned long magic, unsigned long address) {
|
|||||||
// Hardware Detection
|
// Hardware Detection
|
||||||
Serial_Printf(DEBUG_COM_PORT, "MEMORY:> There is %dKB of Memory Available\nThe Kernel is loaded between 0x%x and 0x%x\n", Detect_Memory(), __bss_start, __end);
|
Serial_Printf(DEBUG_COM_PORT, "MEMORY:> There is %dKB of Memory Available\nThe Kernel is loaded between 0x%x and 0x%x\n", Detect_Memory(), __bss_start, __end);
|
||||||
printf("%dKB Of Memory Availible!\n", Detect_Memory());
|
printf("%dKB Of Memory Availible!\n", Detect_Memory());
|
||||||
// printf("Random Number! %u\n", rand());
|
|
||||||
|
|
||||||
// Serial_Printf(DEBUG_COM_PORT, "CPU Vendor: %s\n", CPUID_Get_Vendor()); // CPUID Stuff is pain and suffering, like page faults and suffering
|
// Serial_Printf(DEBUG_COM_PORT, "CPU Vendor: %s\n", CPUID_Get_Vendor()); // CPUID Stuff is pain and suffering, like page faults and suffering
|
||||||
|
|
||||||
@ -144,16 +141,17 @@ void start(unsigned long magic, unsigned long address) {
|
|||||||
printf("Would you like to change the time and date? [y/N] ");
|
printf("Would you like to change the time and date? [y/N] ");
|
||||||
scanf("%s", answer);
|
scanf("%s", answer);
|
||||||
if (!strcmp(answer, "Y") || !strcmp(answer, "y")) {
|
if (!strcmp(answer, "Y") || !strcmp(answer, "y")) {
|
||||||
printf("Please insert Date and Time in [SS]:[MM]:[HH] [DD]/[MM]/[YYYY] Format: ");
|
printf("Please insert Date and Time in [SS]:[MM]:[HH] [DD]/[MM]/[YYYY] Format:\n");
|
||||||
scanf("%s", answer);
|
scanf("%s", answer);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("Starting Shell...");
|
printf("Starting Shell...");
|
||||||
spinner(20);
|
spinner(20); // yes. i fake the loading, i think its funny cope
|
||||||
printf("Done!\n");
|
printf("Done!\n");
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
char* input;
|
||||||
printf(":>");
|
printf(":>");
|
||||||
scanf("");
|
scanf("%s", input);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|||||||
@ -404,7 +404,9 @@ int scanf(const char* fmt, ...) {
|
|||||||
switch (character) {
|
switch (character) {
|
||||||
case '\n': printf("\n");
|
case '\n': printf("\n");
|
||||||
return 0;
|
return 0;
|
||||||
case '\b': printf("\b ");
|
case '\t': printf(" ");
|
||||||
|
break;
|
||||||
|
case '\b': printf("\b "); // keep here lmao.
|
||||||
default: if(character != 0) {
|
default: if(character != 0) {
|
||||||
if(_shift == true) {
|
if(_shift == true) {
|
||||||
printf("%c", character);
|
printf("%c", character);
|
||||||
@ -424,10 +426,9 @@ int scanf(const char* fmt, ...) {
|
|||||||
case '\n': printf("\n");
|
case '\n': printf("\n");
|
||||||
*va_arg(args, char*) = *buffer;
|
*va_arg(args, char*) = *buffer;
|
||||||
return 0;
|
return 0;
|
||||||
case '\b': printf("\b"); i--; buffer[i] = '\0';
|
|
||||||
break;
|
|
||||||
case '\t': printf(" ");
|
case '\t': printf(" ");
|
||||||
break;
|
break;
|
||||||
|
case '\b': printf("\b "); buffer[i] = '\0'; i--;
|
||||||
default: if(character != 0) {
|
default: if(character != 0) {
|
||||||
if(_shift == true) {
|
if(_shift == true) {
|
||||||
printf("%c", character);
|
printf("%c", character);
|
||||||
|
|||||||
@ -10,11 +10,3 @@ uint8_t Get_Bit(uint8_t bits, uint8_t pos)
|
|||||||
{
|
{
|
||||||
return (bits >> pos) & 0x01;
|
return (bits >> pos) & 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int Byte_Parse(int8_t byteFlag, int whichBit)
|
|
||||||
// {
|
|
||||||
// if (whichBit > 0 && whichBit <= 8)
|
|
||||||
// return (byteFlag & (1<<(whichBit-1)));
|
|
||||||
// else
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
@ -12,5 +12,3 @@
|
|||||||
#define BCD2BIN(bcd) ((((bcd)&15) + ((bcd)>>4)*10)) // Takes value in `bcd` and outputs it as binary
|
#define BCD2BIN(bcd) ((((bcd)&15) + ((bcd)>>4)*10)) // Takes value in `bcd` and outputs it as binary
|
||||||
|
|
||||||
uint8_t Get_Bit(uint8_t bits, uint8_t pos);
|
uint8_t Get_Bit(uint8_t bits, uint8_t pos);
|
||||||
|
|
||||||
//int Byte_Parse(int8_t byteFlag, int whichBit);
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
/*----------------*\
|
|
||||||
|Nanite OS |
|
|
||||||
|Copyright (C) 2026|
|
|
||||||
|Xircon |
|
|
||||||
\*----------------*/
|
|
||||||
#include "param.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int paramloader(char filename) {
|
|
||||||
printf("Sorry! This is not currently implemented, Need to Make disk calls and kinda uhm... forgot? i didn't before soooooo YEP!");
|
|
||||||
printf("And heres yer filename: %s", filename);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
/*----------------*\
|
|
||||||
|Nanite OS |
|
|
||||||
|Copyright (C) 2026|
|
|
||||||
|Xircon |
|
|
||||||
\*----------------*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
int paramloader(char filename);
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
/*----------------*\
|
|
||||||
|Nanite OS |
|
|
||||||
|Copyright (C) 2026|
|
|
||||||
|Xircon |
|
|
||||||
\*----------------*/
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int string_length(char s[]) {
|
|
||||||
int i = 0;
|
|
||||||
while (s[i] != '\0') {
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void append(char s[], char n) {
|
|
||||||
int len = string_length(s);
|
|
||||||
s[len] = n;
|
|
||||||
s[len + 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// void Print_Storage_Types(int masterFDDType, int slaveFDDType)
|
|
||||||
// {
|
|
||||||
// // Master FDD
|
|
||||||
// if (masterFDDType == 0) printf("No Master Floppy Drive Detected!\n");
|
|
||||||
// if (masterFDDType == 1) printf("Master Floppy Drive Detected!\nType: 360 KB 5.25 Inch Drive\n");
|
|
||||||
// if (masterFDDType == 2) printf("Master Floppy Drive Detected!\nType: 1.2 MB 5.25 Inch Drive\n");
|
|
||||||
// if (masterFDDType == 3) printf("Master Floppy Drive Detected!\nType: 720 KB 3.5 Inch Drive\n");
|
|
||||||
// if (masterFDDType == 4) printf("Master Floppy Drive Detected!\nType: 1.44 MB 3.5 Inch Drive\n");
|
|
||||||
// if (masterFDDType == 5) printf("Master Floppy Drive Detected!\nType: 2.88 MB 3.5 Inch Drive\n");
|
|
||||||
// // Slave FDD
|
|
||||||
// if (slaveFDDType == 0) printf("No Slave Floppy Drive Detected!\n");
|
|
||||||
// if (slaveFDDType == 1) printf("Slave Floppy Drive Detected!\nType: 360 KB 5.25 Inch Drive\n");
|
|
||||||
// if (slaveFDDType == 2) printf("Slave Floppy Drive Detected!\nType: 1.2 MB 5.25 Inch Drive\n");
|
|
||||||
// if (slaveFDDType == 3) printf("Slave Floppy Drive Detected!\nType: 720 KB 3.5 Inch Drive\n");
|
|
||||||
// if (slaveFDDType == 4) printf("Slave Floppy Drive Detected!\nType: 1.44 MB 3.5 Inch Drive\n");
|
|
||||||
// if (slaveFDDType == 5) printf("Slave Floppy Drive Detected!\nType: 2.88 MB 3.5 Inch Drive\n");
|
|
||||||
// }
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
/*----------------*\
|
|
||||||
|Nanite OS |
|
|
||||||
|Copyright (C) 2026|
|
|
||||||
|Xircon |
|
|
||||||
\*----------------*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define incptr(p, n) ((void *)(((uintptr_t)(p)) + (n)))
|
|
||||||
|
|
||||||
int string_length(char s[]);
|
|
||||||
void append(char s[], char n);
|
|
||||||
// void Print_Storage_Types(int masterFDDType, int slaveFDDType);
|
|
||||||
@ -6,6 +6,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/" // Nanite's Logo as a formatted string
|
#define LOGO " _ _____ _ __________________\n / | / / | / | / / _/_ __/ ____/\n / |/ / /| | / |/ // / / / / __/ \n / /| / ___ |/ /| // / / / / /___ \n/_/ |_/_/ |_/_/ |_/___/ /_/ /_____/" // Nanite's Logo as a formatted string
|
||||||
#define VERSION "RD-00128" // Current Version of Nanite
|
#define VERSION "RD-00132" // Current Version of Nanite
|
||||||
#define BOOTLOGO " _ ______ ____ ____ ______\n / | / / __ )/ __ \\/ __ /_ __/\n / |/ / __ / / / / / / // / \n / /| / /_/ / /_/ / /_/ // / \n/_/ |_/_____/\\____/\\____//_/ \n" // Old bootloader logo
|
#define BOOTLOGO " _ ______ ____ ____ ______\n / | / / __ )/ __ \\/ __ /_ __/\n / |/ / __ / / / / / / // / \n / /| / /_/ / /_/ / /_/ // / \n/_/ |_/_____/\\____/\\____//_/ \n" // Old bootloader logo
|
||||||
// one day i will re-implement NBOOT V 2
|
// one day i will re-implement NBOOT V 2
|
||||||
|
|||||||
14
src/nboot/bootsector/Makefile
Normal file
14
src/nboot/bootsector/Makefile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
BUILD_DIR?=build/
|
||||||
|
TARGET_ASMFLAGS += -f bin
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: bootsector
|
||||||
|
|
||||||
|
bootsector: $(BUILD_DIR)/bootsector.bin
|
||||||
|
|
||||||
|
$(BUILD_DIR)/bootsector.bin:
|
||||||
|
$(TARGET_ASM) bootsector.asm $(TARGET_ASMFLAGS) -o $(BUILD_DIR)/bootsector.bin
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BUILD_DIR)/bootsector.bin
|
||||||
396
src/nboot/bootsector/bootsector.asm
Normal file
396
src/nboot/bootsector/bootsector.asm
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
;/////////////////////;
|
||||||
|
;NBOOT ;
|
||||||
|
;COPYRIGHT (C) 2026 ;
|
||||||
|
;Xircon ;
|
||||||
|
;/////////////////////;
|
||||||
|
org 0x7C00
|
||||||
|
[bits 16]
|
||||||
|
|
||||||
|
|
||||||
|
%define ENDL 0x0D, 0x0A
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; FAT12 header
|
||||||
|
;
|
||||||
|
jmp short start
|
||||||
|
nop
|
||||||
|
|
||||||
|
bdb_oem: db 'MSWIN4.1' ; 8 bytes
|
||||||
|
bdb_bytes_per_sector: dw 512
|
||||||
|
bdb_sectors_per_cluster: db 1
|
||||||
|
bdb_reserved_sectors: dw 1
|
||||||
|
bdb_fat_count: db 2
|
||||||
|
bdb_dir_entries_count: dw 0E0h
|
||||||
|
bdb_total_sectors: dw 2880 ; 2880 * 512 = 1.44MB
|
||||||
|
bdb_media_descriptor_type: db 0F0h ; F0 = 3.5" floppy disk
|
||||||
|
bdb_sectors_per_fat: dw 9 ; 9 sectors/fat
|
||||||
|
bdb_sectors_per_track: dw 18
|
||||||
|
bdb_heads: dw 2
|
||||||
|
bdb_hidden_sectors: dd 0
|
||||||
|
bdb_large_sector_count: dd 0
|
||||||
|
|
||||||
|
; extended boot record
|
||||||
|
ebr_drive_number: db 0 ; 0x00 floppy, 0x80 hdd, useless
|
||||||
|
db 0 ; reserved
|
||||||
|
ebr_signature: db 29h
|
||||||
|
ebr_volume_id: db 12h, 34h, 56h, 78h ; serial number, value doesn't matter
|
||||||
|
ebr_volume_label: db 'NANITE ' ; 11 bytes, padded with spaces
|
||||||
|
ebr_system_id: db 'FAT12 ' ; 8 bytes
|
||||||
|
|
||||||
|
;
|
||||||
|
; Code goes here
|
||||||
|
;
|
||||||
|
|
||||||
|
start:
|
||||||
|
; setup data segments
|
||||||
|
mov ax, 0 ; can't set ds/es directly
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
; setup stack
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, 0x7C00 ; stack grows downwards from where we are loaded in memory
|
||||||
|
|
||||||
|
; some BIOSes might start us at 07C0:0000 instead of 0000:7C00, make sure we are in the
|
||||||
|
; expected location
|
||||||
|
push es
|
||||||
|
push word .after
|
||||||
|
retf
|
||||||
|
|
||||||
|
.after:
|
||||||
|
|
||||||
|
; read something from floppy disk
|
||||||
|
; BIOS should set DL to drive number
|
||||||
|
mov [ebr_drive_number], dl
|
||||||
|
|
||||||
|
; show loading message
|
||||||
|
mov si, msg_loading
|
||||||
|
call puts
|
||||||
|
|
||||||
|
; read drive parameters (sectors per track and head count),
|
||||||
|
; instead of relying on data on formatted disk
|
||||||
|
push es
|
||||||
|
mov ah, 08h
|
||||||
|
int 13h
|
||||||
|
jc error
|
||||||
|
pop es
|
||||||
|
|
||||||
|
and cl, 0x3F ; remove top 2 bits
|
||||||
|
xor ch, ch
|
||||||
|
mov [bdb_sectors_per_track], cx ; sector count
|
||||||
|
|
||||||
|
inc dh
|
||||||
|
mov [bdb_heads], dh ; head count
|
||||||
|
|
||||||
|
; compute LBA of root directory = reserved + fats * sectors_per_fat
|
||||||
|
; note: this section can be hardcoded
|
||||||
|
mov ax, [bdb_sectors_per_fat]
|
||||||
|
mov bl, [bdb_fat_count]
|
||||||
|
xor bh, bh
|
||||||
|
mul bx ; ax = (fats * sectors_per_fat)
|
||||||
|
add ax, [bdb_reserved_sectors] ; ax = LBA of root directory
|
||||||
|
push ax
|
||||||
|
|
||||||
|
; compute size of root directory = (32 * number_of_entries) / bytes_per_sector
|
||||||
|
mov ax, [bdb_dir_entries_count]
|
||||||
|
shl ax, 5 ; ax *= 32
|
||||||
|
xor dx, dx ; dx = 0
|
||||||
|
div word [bdb_bytes_per_sector] ; number of sectors we need to read
|
||||||
|
|
||||||
|
test dx, dx ; if dx != 0, add 1
|
||||||
|
jz .root_dir_after
|
||||||
|
inc ax ; division remainder != 0, add 1
|
||||||
|
; this means we have a sector only partially filled with entries
|
||||||
|
.root_dir_after:
|
||||||
|
|
||||||
|
; read root directory
|
||||||
|
mov cl, al ; cl = number of sectors to read = size of root directory
|
||||||
|
pop ax ; ax = LBA of root directory
|
||||||
|
mov dl, [ebr_drive_number] ; dl = drive number (we saved it previously)
|
||||||
|
mov bx, buffer ; es:bx = buffer
|
||||||
|
call disk_read
|
||||||
|
|
||||||
|
; search for stage2
|
||||||
|
xor bx, bx
|
||||||
|
mov di, buffer
|
||||||
|
|
||||||
|
; .search_boot_dir:
|
||||||
|
; mov si, boot_dir
|
||||||
|
; mov cx, 11 ; compare up to 11 characters
|
||||||
|
; push di
|
||||||
|
; repe cmpsb
|
||||||
|
; pop di
|
||||||
|
; je .found_boot_dir
|
||||||
|
|
||||||
|
; add di, 32
|
||||||
|
; inc bx
|
||||||
|
; cmp bx, [bdb_dir_entries_count]
|
||||||
|
; jl .search_boot_dir
|
||||||
|
|
||||||
|
; ; kernel not found
|
||||||
|
; jmp error
|
||||||
|
|
||||||
|
; .found_boot_dir:
|
||||||
|
; hlt
|
||||||
|
|
||||||
|
.search_stage2:
|
||||||
|
mov si, file_stage2_bin
|
||||||
|
mov cx, 11 ; compare up to 11 characters
|
||||||
|
push di
|
||||||
|
repe cmpsb
|
||||||
|
pop di
|
||||||
|
je .found_stage2
|
||||||
|
|
||||||
|
add di, 32
|
||||||
|
inc bx
|
||||||
|
cmp bx, [bdb_dir_entries_count]
|
||||||
|
jl .search_stage2
|
||||||
|
|
||||||
|
; kernel not found
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
.found_stage2:
|
||||||
|
|
||||||
|
; di should have the address to the entry
|
||||||
|
mov ax, [di + 26] ; first logical cluster field (offset 26)
|
||||||
|
mov [stage2_cluster], ax
|
||||||
|
|
||||||
|
; load FAT from disk into memory
|
||||||
|
mov ax, [bdb_reserved_sectors]
|
||||||
|
mov bx, buffer
|
||||||
|
mov cl, [bdb_sectors_per_fat]
|
||||||
|
mov dl, [ebr_drive_number]
|
||||||
|
call disk_read
|
||||||
|
|
||||||
|
; read kernel and process FAT chain
|
||||||
|
mov bx, STAGE2_LOAD_SEGMENT
|
||||||
|
mov es, bx
|
||||||
|
mov bx, STAGE2_LOAD_OFFSET
|
||||||
|
|
||||||
|
.load_stage2_loop:
|
||||||
|
|
||||||
|
; Read next cluster
|
||||||
|
mov ax, [stage2_cluster]
|
||||||
|
|
||||||
|
; not nice :( hardcoded value
|
||||||
|
add ax, 31 ; first cluster = (kernel_cluster - 2) * sectors_per_cluster + start_sector
|
||||||
|
; start sector = reserved + fats + root directory size = 1 + 18 + 134 = 33
|
||||||
|
mov cl, 1
|
||||||
|
mov dl, [ebr_drive_number]
|
||||||
|
call disk_read
|
||||||
|
|
||||||
|
add bx, [bdb_bytes_per_sector]
|
||||||
|
|
||||||
|
; compute location of next cluster
|
||||||
|
mov ax, [stage2_cluster]
|
||||||
|
mov cx, 3
|
||||||
|
mul cx
|
||||||
|
mov cx, 2
|
||||||
|
div cx ; ax = index of entry in FAT, dx = cluster mod 2
|
||||||
|
|
||||||
|
mov si, buffer
|
||||||
|
add si, ax
|
||||||
|
mov ax, [ds:si] ; read entry from FAT table at index ax
|
||||||
|
|
||||||
|
or dx, dx
|
||||||
|
jz .even
|
||||||
|
|
||||||
|
.odd:
|
||||||
|
shr ax, 4
|
||||||
|
jmp .next_cluster_after
|
||||||
|
|
||||||
|
.even:
|
||||||
|
and ax, 0x0FFF
|
||||||
|
|
||||||
|
.next_cluster_after:
|
||||||
|
cmp ax, 0x0FF8 ; end of chain
|
||||||
|
jae .read_finish
|
||||||
|
|
||||||
|
mov [stage2_cluster], ax
|
||||||
|
jmp .load_stage2_loop
|
||||||
|
|
||||||
|
.read_finish:
|
||||||
|
|
||||||
|
; jump to our kernel
|
||||||
|
mov dl, [ebr_drive_number] ; boot device in dl
|
||||||
|
|
||||||
|
mov ax, STAGE2_LOAD_SEGMENT ; set segment registers
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
|
||||||
|
jmp STAGE2_LOAD_SEGMENT:STAGE2_LOAD_OFFSET
|
||||||
|
|
||||||
|
jmp wait_key_and_reboot ; should never happen
|
||||||
|
|
||||||
|
cli ; disable interrupts, this way CPU can't get out of "halt" state
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Error handler (i needed more room.)
|
||||||
|
;
|
||||||
|
|
||||||
|
error:
|
||||||
|
mov si, msg_error
|
||||||
|
call puts
|
||||||
|
jmp wait_key_and_reboot
|
||||||
|
|
||||||
|
wait_key_and_reboot:
|
||||||
|
mov ah, 0
|
||||||
|
int 16h ; wait for keypress
|
||||||
|
jmp 0FFFFh:0 ; jump to beginning of BIOS, should reboot
|
||||||
|
|
||||||
|
.halt:
|
||||||
|
cli ; disable interrupts, this way CPU can't get out of "halt" state
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Prints a string to the screen
|
||||||
|
; Params:
|
||||||
|
; - ds:si points to string
|
||||||
|
;
|
||||||
|
puts:
|
||||||
|
; save registers we will modify
|
||||||
|
push si
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
lodsb ; loads next character in al
|
||||||
|
or al, al ; verify if next character is null?
|
||||||
|
jz .done
|
||||||
|
|
||||||
|
mov ah, 0x0E ; call bios interrupt
|
||||||
|
mov bh, 0 ; set page number to 0
|
||||||
|
int 0x10
|
||||||
|
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
.done:
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
pop si
|
||||||
|
ret
|
||||||
|
|
||||||
|
;
|
||||||
|
; Disk routines
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Converts an LBA address to a CHS address
|
||||||
|
; Parameters:
|
||||||
|
; - ax: LBA address
|
||||||
|
; Returns:
|
||||||
|
; - cx [bits 0-5]: sector number
|
||||||
|
; - cx [bits 6-15]: cylinder
|
||||||
|
; - dh: head
|
||||||
|
;
|
||||||
|
|
||||||
|
lba_to_chs:
|
||||||
|
|
||||||
|
push ax
|
||||||
|
push dx
|
||||||
|
|
||||||
|
xor dx, dx ; dx = 0
|
||||||
|
div word [bdb_sectors_per_track] ; ax = LBA / SectorsPerTrack
|
||||||
|
; dx = LBA % SectorsPerTrack
|
||||||
|
|
||||||
|
inc dx ; dx = (LBA % SectorsPerTrack + 1) = sector
|
||||||
|
mov cx, dx ; cx = sector
|
||||||
|
|
||||||
|
xor dx, dx ; dx = 0
|
||||||
|
div word [bdb_heads] ; ax = (LBA / SectorsPerTrack) / Heads = cylinder
|
||||||
|
; dx = (LBA / SectorsPerTrack) % Heads = head
|
||||||
|
mov dh, dl ; dh = head
|
||||||
|
mov ch, al ; ch = cylinder (lower 8 bits)
|
||||||
|
shl ah, 6
|
||||||
|
or cl, ah ; put upper 2 bits of cylinder in CL
|
||||||
|
|
||||||
|
pop ax
|
||||||
|
mov dl, al ; restore DL
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Reads sectors from a disk
|
||||||
|
; Parameters:
|
||||||
|
; - ax: LBA address
|
||||||
|
; - cl: number of sectors to read (up to 128)
|
||||||
|
; - dl: drive number
|
||||||
|
; - es:bx: memory address where to store read data
|
||||||
|
;
|
||||||
|
disk_read:
|
||||||
|
|
||||||
|
push ax ; save registers we will modify
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push di
|
||||||
|
|
||||||
|
push cx ; temporarily save CL (number of sectors to read)
|
||||||
|
call lba_to_chs ; compute CHS
|
||||||
|
pop ax ; AL = number of sectors to read
|
||||||
|
|
||||||
|
mov ah, 02h
|
||||||
|
mov di, 3 ; retry count
|
||||||
|
|
||||||
|
.retry:
|
||||||
|
pusha ; save all registers, we don't know what bios modifies
|
||||||
|
stc ; set carry flag, some BIOS'es don't set it
|
||||||
|
int 13h ; carry flag cleared = success
|
||||||
|
jnc .done ; jump if carry not set
|
||||||
|
|
||||||
|
; read failed
|
||||||
|
popa
|
||||||
|
call disk_reset
|
||||||
|
|
||||||
|
dec di
|
||||||
|
test di, di
|
||||||
|
jnz .retry
|
||||||
|
|
||||||
|
.fail:
|
||||||
|
; all attempts are exhausted
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
.done:
|
||||||
|
popa
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax ; restore registers modified
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
; Resets disk controller
|
||||||
|
; Parameters:
|
||||||
|
; dl: drive number
|
||||||
|
;
|
||||||
|
disk_reset:
|
||||||
|
pusha
|
||||||
|
mov ah, 0
|
||||||
|
stc
|
||||||
|
int 13h
|
||||||
|
jc error
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
msg_loading: db 'Loading NBOOT...', ENDL, 0
|
||||||
|
msg_error: db 'ERR!', ENDL, 0
|
||||||
|
file_stage2_bin: db 'NBOOT BIN'
|
||||||
|
boot_dir: db 'BOOT '
|
||||||
|
stage2_cluster: dw 0
|
||||||
|
|
||||||
|
STAGE2_LOAD_SEGMENT equ 0x0
|
||||||
|
STAGE2_LOAD_OFFSET equ 0x500
|
||||||
|
|
||||||
|
times 510-($-$$) db 0
|
||||||
|
dw 0AA55h
|
||||||
|
|
||||||
|
buffer:
|
||||||
44
src/nboot/stage2/Makefile
Normal file
44
src/nboot/stage2/Makefile
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
TARGET_ASMFLAGS += -f elf
|
||||||
|
TARGET_CFLAGS += -ffreestanding -nostdlib -I.
|
||||||
|
TARGET_LIBS += -lgcc
|
||||||
|
TARGET_LINKFLAGS += -T linker.ld -nostdlib
|
||||||
|
|
||||||
|
HEADERS_C = $(wildcard *.h) \
|
||||||
|
$(wildcard */*.h) \
|
||||||
|
$(wildcard */*/*.h) \
|
||||||
|
$(wildcard */*/*/*.h) \
|
||||||
|
|
||||||
|
SOURCES_C = $(wildcard *.c) \
|
||||||
|
$(wildcard */*.c) \
|
||||||
|
$(wildcard */*/*.c) \
|
||||||
|
$(wildcard */*/*/*.c) \
|
||||||
|
|
||||||
|
OBJECTS_C = $(patsubst %.c, $(BUILD_DIR)/nboot/c/%.obj, $(SOURCES_C))
|
||||||
|
|
||||||
|
HEADERS_ASM = $(wildcard *.inc)
|
||||||
|
SOURCES_ASM = $(wildcard *.asm)
|
||||||
|
|
||||||
|
OBJECTS_ASM = $(patsubst %.asm, $(BUILD_DIR)/nboot/asm/%.obj, $(SOURCES_ASM))
|
||||||
|
|
||||||
|
.PHONY: all nboot clean always
|
||||||
|
|
||||||
|
all: nboot
|
||||||
|
|
||||||
|
nboot: $(BUILD_DIR)/nboot.bin
|
||||||
|
|
||||||
|
$(BUILD_DIR)/nboot.bin: $(OBJECTS_ASM) $(OBJECTS_C)
|
||||||
|
@$(TARGET_LD) $(TARGET_LINKFLAGS) -Wl,-Map=$(BUILD_DIR)/kernel.map -o $@ $^ $(TARGET_LIBS)
|
||||||
|
@echo "--> Created: nboot.bin"
|
||||||
|
|
||||||
|
$(BUILD_DIR)/nboot/c/%.obj: %.c $(HEADERS_C)
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
@$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $<
|
||||||
|
@echo "--> Compiled: " $<
|
||||||
|
|
||||||
|
$(BUILD_DIR)/nboot/asm/%.obj: %.asm $(HEADERS_ASM)
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
@$(TARGET_ASM) $(TARGET_ASMFLAGS) -o $@ $<
|
||||||
|
@echo "--> Compiled: " $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BUILD_DIR)/nboot.bin
|
||||||
175
src/nboot/stage2/entry.asm
Normal file
175
src/nboot/stage2/entry.asm
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
;/////////////////////;
|
||||||
|
;NBOOT ;
|
||||||
|
;COPYRIGHT (C) 2026 ;
|
||||||
|
;Xircon ;
|
||||||
|
;/////////////////////;
|
||||||
|
[bits 16]
|
||||||
|
|
||||||
|
section .entry
|
||||||
|
|
||||||
|
extern __bss_start
|
||||||
|
extern __end
|
||||||
|
|
||||||
|
extern start
|
||||||
|
global entry
|
||||||
|
|
||||||
|
entry:
|
||||||
|
cli
|
||||||
|
|
||||||
|
; save boot drive
|
||||||
|
mov [g_BootDrive], dl
|
||||||
|
|
||||||
|
; setup stack
|
||||||
|
mov ax, ds
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, 0xFFF0
|
||||||
|
mov bp, sp
|
||||||
|
|
||||||
|
; switch to PMODE
|
||||||
|
call EnableA20
|
||||||
|
call LoadGDT
|
||||||
|
|
||||||
|
; set PMODE enable flag in CR0
|
||||||
|
mov eax, CR0
|
||||||
|
or al, 1
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
; far jmp into PMODE
|
||||||
|
jmp dword 08h:.pmode
|
||||||
|
|
||||||
|
.pmode:
|
||||||
|
; we are now in protected mode!
|
||||||
|
[bits 32]
|
||||||
|
|
||||||
|
; 6 - setup segment registers
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov al, 0
|
||||||
|
cld
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
; clear BSS (uninit data)
|
||||||
|
mov edi, __bss_start
|
||||||
|
mov ecx, __end
|
||||||
|
sub ecx, edi
|
||||||
|
|
||||||
|
|
||||||
|
xor edx, edx
|
||||||
|
mov dl, [g_BootDrive]
|
||||||
|
push edx
|
||||||
|
call start
|
||||||
|
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EnableA20:
|
||||||
|
[bits 16]
|
||||||
|
; disable keyboard
|
||||||
|
call A20WaitInput
|
||||||
|
mov al, KbdControllerDisableKeyboard
|
||||||
|
out KbdControllerCommandPort, al
|
||||||
|
|
||||||
|
; read control output port
|
||||||
|
call A20WaitInput
|
||||||
|
mov al, KbdControllerReadCtrlOutputPort
|
||||||
|
out KbdControllerCommandPort, al
|
||||||
|
|
||||||
|
call A20WaitOutput
|
||||||
|
in al, KbdControllerDataPort
|
||||||
|
push eax
|
||||||
|
|
||||||
|
; write control output port
|
||||||
|
call A20WaitInput
|
||||||
|
mov al, KbdControllerWriteCtrlOutputPort
|
||||||
|
out KbdControllerCommandPort, al
|
||||||
|
|
||||||
|
call A20WaitInput
|
||||||
|
pop eax
|
||||||
|
or al, 2 ; bit 2 = A20 bit
|
||||||
|
out KbdControllerDataPort, al
|
||||||
|
|
||||||
|
; enable keyboard
|
||||||
|
call A20WaitInput
|
||||||
|
mov al, KbdControllerEnableKeyboard
|
||||||
|
out KbdControllerCommandPort, al
|
||||||
|
|
||||||
|
call A20WaitInput
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
A20WaitInput:
|
||||||
|
[bits 16]
|
||||||
|
; wait until status bit 2 (input buffer) is 0
|
||||||
|
; by reading from command port, we read status byte
|
||||||
|
in al, KbdControllerCommandPort
|
||||||
|
test al, 2
|
||||||
|
jnz A20WaitInput
|
||||||
|
ret
|
||||||
|
|
||||||
|
A20WaitOutput:
|
||||||
|
[bits 16]
|
||||||
|
; wait until status bit 1 (output buffer) is 1 so it can be read
|
||||||
|
in al, KbdControllerCommandPort
|
||||||
|
test al, 1
|
||||||
|
jz A20WaitOutput
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
LoadGDT:
|
||||||
|
[bits 16]
|
||||||
|
lgdt [g_GDTDesc]
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KbdControllerDataPort equ 0x60
|
||||||
|
KbdControllerCommandPort equ 0x64
|
||||||
|
KbdControllerDisableKeyboard equ 0xAD
|
||||||
|
KbdControllerEnableKeyboard equ 0xAE
|
||||||
|
KbdControllerReadCtrlOutputPort equ 0xD0
|
||||||
|
KbdControllerWriteCtrlOutputPort equ 0xD1
|
||||||
|
|
||||||
|
ScreenBuffer equ 0xB8000
|
||||||
|
|
||||||
|
g_GDT: ; NULL descriptor
|
||||||
|
dq 0
|
||||||
|
|
||||||
|
; 32-bit code segment
|
||||||
|
dw 0FFFFh ; limit (bits 0-15) = 0xFFFFF for full 32-bit range
|
||||||
|
dw 0 ; base (bits 0-15) = 0x0
|
||||||
|
db 0 ; base (bits 16-23)
|
||||||
|
db 10011010b ; access (present, ring 0, code segment, executable, direction 0, readable)
|
||||||
|
db 11001111b ; granularity (4k pages, 32-bit pmode) + limit (bits 16-19)
|
||||||
|
db 0 ; base high
|
||||||
|
|
||||||
|
; 32-bit data segment
|
||||||
|
dw 0FFFFh ; limit (bits 0-15) = 0xFFFFF for full 32-bit range
|
||||||
|
dw 0 ; base (bits 0-15) = 0x0
|
||||||
|
db 0 ; base (bits 16-23)
|
||||||
|
db 10010010b ; access (present, ring 0, data segment, executable, direction 0, writable)
|
||||||
|
db 11001111b ; granularity (4k pages, 32-bit pmode) + limit (bits 16-19)
|
||||||
|
db 0 ; base high
|
||||||
|
|
||||||
|
; 16-bit code segment
|
||||||
|
dw 0FFFFh ; limit (bits 0-15) = 0xFFFFF
|
||||||
|
dw 0 ; base (bits 0-15) = 0x0
|
||||||
|
db 0 ; base (bits 16-23)
|
||||||
|
db 10011010b ; access (present, ring 0, code segment, executable, direction 0, readable)
|
||||||
|
db 00001111b ; granularity (1b pages, 16-bit pmode) + limit (bits 16-19)
|
||||||
|
db 0 ; base high
|
||||||
|
|
||||||
|
; 16-bit data segment
|
||||||
|
dw 0FFFFh ; limit (bits 0-15) = 0xFFFFF
|
||||||
|
dw 0 ; base (bits 0-15) = 0x0
|
||||||
|
db 0 ; base (bits 16-23)
|
||||||
|
db 10010010b ; access (present, ring 0, data segment, executable, direction 0, writable)
|
||||||
|
db 00001111b ; granularity (1b pages, 16-bit pmode) + limit (bits 16-19)
|
||||||
|
db 0 ; base high
|
||||||
|
|
||||||
|
g_GDTDesc: dw g_GDTDesc - g_GDT - 1 ; limit = size of GDT
|
||||||
|
dd g_GDT ; address of GDT
|
||||||
|
|
||||||
|
g_BootDrive: db 0
|
||||||
12
src/nboot/stage2/linker.ld
Normal file
12
src/nboot/stage2/linker.ld
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ENTRY(start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.entry : { __entry_start = .; *(.entry) }
|
||||||
|
.text : { __text_start = .; *(.text) }
|
||||||
|
.data : { __data_start = .; *(.data) }
|
||||||
|
.rodata : { __rodata_start = .; *(.rodata*) }
|
||||||
|
.bss : { __bss_start = .; *(.bss) }
|
||||||
|
|
||||||
|
__end = .;
|
||||||
|
}
|
||||||
10
src/nboot/stage2/main.c
Normal file
10
src/nboot/stage2/main.c
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*----------------*\
|
||||||
|
|NBOOT |
|
||||||
|
|Copyright (C) 2026|
|
||||||
|
|Xircon |
|
||||||
|
\*----------------*/
|
||||||
|
#include <version.h>
|
||||||
|
|
||||||
|
void __attribute__((section(".entry"))) start() {
|
||||||
|
|
||||||
|
}
|
||||||
10
src/nboot/stage2/version.h
Normal file
10
src/nboot/stage2/version.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*----------------*\
|
||||||
|
|NBOOT |
|
||||||
|
|Copyright (C) 2026|
|
||||||
|
|Xircon |
|
||||||
|
\*----------------*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define VERSION "RD-00002" // Current Version of Nanite
|
||||||
|
#define LOGO " _ ______ ____ ____ ______\n / | / / __ )/ __ \\/ __ /_ __/\n / |/ / __ / / / / / / // / \n / /| / /_/ / /_/ / /_/ // / \n/_/ |_/_____/\\____/\\____//_/ \n"
|
||||||
|
// one day i will re-implement NBOOT V 2
|
||||||
Loading…
x
Reference in New Issue
Block a user