Compare commits

...

12 Commits

Author SHA1 Message Date
bzt 6ce3a4a2a8 Merge branch 'master' into 'master'
Zig kernel example

See merge request bztsrc/bootboot!14
2023-01-13 05:49:20 +00:00
Binary Craft d6845611e0 fixed readme formating 2023-01-12 10:05:58 +08:00
Binary Craft 33e59feaf4 Zig kernel example 2023-01-12 09:55:11 +08:00
bzt 1793d99368 Added ENTRY() to linker scripts 2023-01-06 19:13:45 +01:00
bzt 47c01213e5 Use correct CRLFs in BIOS version 2022-12-27 13:46:05 +01:00
bzt ef5aa234c5 Do not rely on BIOS, initialize the serial port ourselves 2022-12-27 11:12:15 +01:00
bzt 190375cfd6 More docs 2022-12-16 04:29:02 +01:00
bzt 77db2bf6d2 More docs 2022-12-16 04:28:18 +01:00
bzt 6b56345f01 More mingw workarounds in mkbootimg... 2022-11-21 07:30:36 +01:00
bzt 2b3fb32025 Stupid proof fread 2022-11-21 06:28:56 +01:00
bzt be253ad7a7 Fixing printf on mingw 2022-11-21 05:33:59 +01:00
bzt 1a36775605 Update LeanFS to v0.8 2022-11-11 19:45:03 +01:00
25 changed files with 557 additions and 56 deletions

View File

@ -1,8 +1,7 @@
**!!!WARNING!!**
Microsoft-paid trolls got me banned from OSDev.org and they are lying about BOOTBOOT ever since. Do not ask questions about
BOOTBOOT there, because you won't get correct answers. Use GitLab issues instead or mail me directly. And by the way, BOOTBOOT does
provide the same environment and a consistent, architecture-independent memory map on ALL supported platforms, see for yourself.
Microsoft-paid trolls got me banned from OSDev.org and they are [spreading lies about BOOTBOOT](osdev.md) ever since. Do not ask
questions about BOOTBOOT there, because you won't get correct answers. Use GitLab issues instead or mail me directly.
BOOTBOOT Reference Implementations
==================================

BIN
dist/bootboot.bin vendored

Binary file not shown.

View File

@ -19,7 +19,7 @@ fájlrendszerek:
| `fat` | ✗No | ✔Yes | [spec](https://gitlab.com/bztsrc/bootboot/raw/binaries/specs/vfat.pdf) (csak nem-ESP, LFN-el) |
| `minix` | ✗No | ✔Yes | [V2 spec](https://gitlab.com/bztsrc/bootboot/raw/binaries/specs/minix.pdf), [V3 forrás](https://github.com/Stichting-MINIX-Research-Foundation/minix/tree/master/minix/fs/mfs) (V3 támogatott, de csak V2-höz van spec) |
| `ext2` | ✗No | ✔Yes | [spec](https://gitlab.com/bztsrc/bootboot/raw/binaries/specs/ext2.pdf), [dokumentáció](https://www.nongnu.org/ext2-doc/ext2.html) |
| `lean` | ✗No | ✔Yes | [V0.6 spec](http://freedos-32.sourceforge.net/lean/specification.php), [V0.7 spec](http://www.fysnet.net/leanfs/specification.php) |
| `lean` | ✗No | ✔Yes | [V0.6 spec](http://freedos-32.sourceforge.net/lean/specification.php), [V0.8 spec](http://www.fysnet.net/leanfs/specification.php) |
A kód úgy lett megírva, hogy könnyű legyen bővíteni új fájlrendszerekkel.

View File

@ -18,7 +18,7 @@ also creates an initrd or a disk partition from a directory. Supported file syst
| `fat` | ✗No | ✔Yes | [spec](https://gitlab.com/bztsrc/bootboot/raw/binaries/specs/vfat.pdf) (non-ESP only, with LFN) |
| `minix` | ✗No | ✔Yes | [V2 spec](https://gitlab.com/bztsrc/bootboot/raw/binaries/specs/minix.pdf), [V3 source](https://github.com/Stichting-MINIX-Research-Foundation/minix/tree/master/minix/fs/mfs) (V3 supported, but there's only V2 spec) |
| `ext2` | ✗No | ✔Yes | [spec](https://gitlab.com/bztsrc/bootboot/raw/binaries/specs/ext2.pdf), [documentation](https://www.nongnu.org/ext2-doc/ext2.html) |
| `lean` | ✗No | ✔Yes | [V0.6 spec](http://freedos-32.sourceforge.net/lean/specification.php), [V0.7 spec](http://www.fysnet.net/leanfs/specification.php) |
| `lean` | ✗No | ✔Yes | [V0.6 spec](http://freedos-32.sourceforge.net/lean/specification.php), [V0.8 spec](http://www.fysnet.net/leanfs/specification.php) |
The code is written in a way that it is easily expandable with new file systems.

View File

@ -63,7 +63,7 @@ int main(int argc, char **argv)
fprintf(stderr, "bin2h: memory allocation error\r\n");
exit(2);
}
fread(buff, size, 1, f);
fread(buff, 1, size, f);
fclose(f);
fn = strrchr(argv[file], '/');
if(!fn) fn = strrchr(argv[file], '\\');

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,7 @@
#define sizeof_boot_bin 512
extern unsigned char binary_boot_bin[512];
#define sizeof_bootboot_bin 13312
extern unsigned char binary_bootboot_bin[9299];
extern unsigned char binary_bootboot_bin[9329];
#define sizeof_bootboot_efi 103614
extern unsigned char binary_bootboot_efi[46348];
#define sizeof_bootboot_img 35344

View File

@ -173,7 +173,7 @@ unsigned char *fat_writelfn(unsigned char *dir, char *name, int type, int size,
dir[0x1C] = size & 0xFF; dir[0x1D] = (size >> 8) & 0xFF;
dir[0x1E] = (size >> 16) & 0xFF; dir[0x1F] = (size >> 24) & 0xFF;
}
if(!clu) clu = fat_nextcluster;
if(!clu) clu = size > 0 || type ? fat_nextcluster : 0;
if(clu < 3) clu = 0;
dir[0x1A] = clu & 0xFF; dir[0x1B] = (clu >> 8) & 0xFF;
dir[0x14] = (clu >> 16) & 0xFF; dir[0x15] = (clu >> 24) & 0xFF;
@ -220,7 +220,7 @@ void fat_open(gpt_t *gpt_entry)
fat_fat32_1 = fat_fat32_2 = NULL;
} else {
/* FAT32 */
fat_spf = (fat_numclu*4) / 512 - 8;
fat_spf = (fat_numclu*4) / 512;
fs_base[0xD] = SECTOR_PER_CLUSTER; fs_base[0xE] = 8;
fs_base[0x24] = fat_spf & 0xFF; fs_base[0x25] = (fat_spf >> 8) & 0xFF;
fs_base[0x26] = (fat_spf >> 16) & 0xFF; fs_base[0x27] = (fat_spf >> 24) & 0xFF;
@ -244,7 +244,7 @@ void fat_open(gpt_t *gpt_entry)
void fat_add(struct stat *st, char *name, unsigned char *content, int size)
{
int parent = 2, clu, i;
int parent = 2, clu, i, j;
unsigned char *dir = fat_rootdir;
char *end, *fn = strrchr(name, '/');
if(!fn) fn = name; else fn++;
@ -256,7 +256,7 @@ void fat_add(struct stat *st, char *name, unsigned char *content, int size)
if(!end) end = name + strlen(name);
fat_lfncnt = 1;
do {
dir = fat_readlfn(dir, &clu, &size, parent);
dir = fat_readlfn(dir, &clu, &j, parent);
if(!dir) return;
if(!memcmp(fat_lfn, fn, end - fn) && !fat_lfn[end - fn]) {
fat_lfncnt = 1;

View File

@ -51,7 +51,7 @@ void gpt_maketable()
unsigned long int size, ps, total, l;
unsigned char *iso, *p;
uint16_t *u;
char isodate[17], key[64], *tmp, *name;
char isodate[64], key[64], *tmp, *name;
guid_t typeguid;
FILE *f;

View File

@ -25,14 +25,17 @@
*
* This file is part of the BOOTBOOT Protocol package.
* @brief LeanFS file system driver
* See http://freedos-32.sourceforge.net/lean/specification.php
* See http://www.fysnet.net/leanfs/specification.php
* See http://freedos-32.sourceforge.net/lean/specification.php (v0.6, original)
* See http://www.fysnet.net/leanfs/specification.php (v0.7 and later, forked by fys)
*
* The FS we create here does not use any v0.8 or v0.7 specific features, hence it is v0.6 compatible
* (no hidden or undeleted files, no bad sectors, sector size 512 bytes, six extents per inode etc.)
*
*/
#include "main.h"
#define LEAN_SUPER_MAGIC 0x4E41454C
#define LEAN_SUPER_VERSION 0x0007 /* could be 0x0006 as well, backwards compatible */
#define LEAN_SUPER_VERSION 0x0008 /* could be 6 or 7 as well */
#define LEAN_INODE_MAGIC 0x45444F4E
#define LEAN_INODE_EXTENT_CNT 6
#define LEAN_FT_MT 0

View File

@ -31,15 +31,16 @@
#include "fs.h"
#ifdef __WIN32__
#include <windows.h>
#define ISHH(x) ((((x)>>30)&0xFFFFFFFF)==0xFFFFFFFF)
# include <windows.h>
# define ISHH(x) ((((x)>>30)&0xFFFFFFFF)==0xFFFFFFFF)
# define LL "I64"
#else
#define ISHH(x) (((x)>>30)==0x3FFFFFFFF)
#endif
#if defined(MACOSX) || __WORDSIZE == 32
#define LL "ll"
#else
#define LL "l"
# define ISHH(x) (((x)>>30)==0x3FFFFFFFF)
# if defined(MACOSX) || __WORDSIZE == 32
# define LL "ll"
# else
# define LL "l"
# endif
#endif
extern const char deflate_copyright[];
@ -349,7 +350,7 @@ void parsekernel(int idx, unsigned char *data, int v)
{ if(v) { printf("invalid\r\n"); } fprintf(stderr,"mkbootimg: initstack %s\r\n",lang[ERR_BADSIZE]); exit(1); }
if(v) printf("OK\r\n");
}
if(v) printf("Load segment: %016" LL "x size %" LL "dK offs %" LL "x ", core_addr, (core_size + bss + 1024)/1024, core_ptr);
if(v) printf("Load segment: %016" LL "x size %" LL "uK offs %" LL "x ", core_addr, (core_size + bss + 1024)/1024, core_ptr);
if(!ISHH(core_addr)) { if(v) { printf("invalid\r\n"); } fprintf(stderr,"mkbootimg: segment %s\r\n",lang[ERR_BADADDR]); exit(1); }
if(core_addr & 4095) { if(v) { printf("invalid\r\n"); } fprintf(stderr,"mkbootimg: segment %s\r\n",lang[ERR_PAGEALIGN]); exit(1); }
if(core_size + bss > 16 * 1024 * 1024) { if(v) { printf("invalid\r\n"); } fprintf(stderr,"mkbootimg: segment %s\r\n",lang[ERR_BIGSEG]); exit(1); }
@ -423,7 +424,7 @@ int flashmapadd(char *file)
fseek(f,0L,SEEK_SET);
data=(unsigned char*)malloc(size + bs);
if(!data) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_MEM]); exit(1); }
data[0] = 0; fread(data,size,1,f);
data[0] = 0; fread(data,1,size,f);
fclose(f);
if(memcmp(data, "__FMAP__", 8)) { free(data); return 0; }
if(!initrd_buf[0] || bs < 1) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_NOINITRD]); exit(1); }

View File

@ -194,7 +194,7 @@ extern initrd_open rd_open;
extern initrd_add rd_add;
extern initrd_close rd_close;
extern long int read_size;
extern int64_t read_size;
unsigned char* readfileall(char *file);
unsigned int gethex(char *ptr, int len);
void getguid(char *ptr, guid_t *guid);

View File

@ -32,6 +32,7 @@
#include <unistd.h>
#ifdef __WIN32__
#include <windows.h>
int readlink(char *path, char *target, int len) {
(void)path;
(void)target;
@ -56,13 +57,34 @@ initrd_close rd_close = NULL;
/**
* Read a file entirely into memory. Don't use it with partition image files
*/
long int read_size;
int64_t read_size;
unsigned char* readfileall(char *file)
{
unsigned char *data=NULL;
#ifdef __WIN32__
HANDLE f;
DWORD r, t;
#else
FILE *f;
int64_t t;
#endif
read_size=0;
if(!file || !*file) return NULL;
/* for some reason sometimes fread refuses to load the entire file under Windows... even if it's as small as 10k... */
#ifdef __WIN32__
f=CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(f){
r=GetFileSize(f,NULL);
read_size=r;
data=(unsigned char*)malloc(read_size+1);
if(!data) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_MEM]); exit(1); }
memset(data,0,read_size+1);
if(!ReadFile(f,data,r,&t,NULL) || r != t) { fprintf(stderr,"mkbootimg: '%s' ReadFile %ld != %ld ???\r\n",file,t,r); exit(1); }
data[read_size] = 0;
CloseHandle(f);
}
#else
f=fopen(file,"r");
if(f){
fseek(f,0L,SEEK_END);
@ -71,10 +93,12 @@ unsigned char* readfileall(char *file)
data=(unsigned char*)malloc(read_size+1);
if(!data) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_MEM]); exit(1); }
memset(data,0,read_size+1);
fread(data,read_size,1,f);
t = fread(data,1,read_size,f);
if(t != read_size) { fprintf(stderr,"mkbootimg: '%s' fread %ld != %ld ???\r\n",file,(long int)t,(long int)read_size); exit(1); }
data[read_size] = 0;
fclose(f);
}
#endif
return data;
}

View File

@ -13,4 +13,4 @@ Compilation
-----------
In the language's directory, just run `make`. You'll need `gcc`, `g++`, `gnat` (GNU Ada), `fpc` (FreePascal
Compiler), `cargo` + `rust`, and `gccgo` (GNU go-lang compiler, NOT the official go-lang compiler!).
Compiler), `cargo` + `rust`, `gccgo` (GNU go-lang compiler, NOT the official go-lang compiler!), and `zig`.

View File

@ -28,6 +28,8 @@
*
*/
ENTRY(_start)
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
fb = 0xfffffffffc000000;
bootboot = 0xffffffffffe00000;

View File

@ -28,6 +28,8 @@
*
*/
ENTRY(_start)
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
fb = 0xfffffffffc000000;
bootboot = 0xffffffffffe00000;

View File

@ -28,6 +28,8 @@
*
*/
ENTRY(_start)
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
fb = 0xfffffffffc000000;
bootboot = 0xffffffffffe00000;

36
mykernel/zig/Makefile Normal file
View File

@ -0,0 +1,36 @@
#
# mykernel/zig/Makefile
#
# Copyright (C) 2022 binarycraft
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use, copy,
# modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# This file is part of the BOOTBOOT Protocol package.
# @brief An example Makefile for sample kernel
#
#
all: mykernel.x86_64.elf
# Kernel build
mykernel.x86_64.elf: src/**
zig build -Drelease-fast
cp ./zig-out/bin/mykernel.x86_64.elf mykernel.x86_64.elf

18
mykernel/zig/build.zig Normal file
View File

@ -0,0 +1,18 @@
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
var target = std.zig.CrossTarget{
.os_tag = .freestanding,
.cpu_arch = .x86_64,
.abi = .none,
};
const mode = b.standardReleaseOptions();
const kernel = b.addExecutable("mykernel.x86_64.elf", "src/main.zig");
kernel.setLinkerScriptPath(.{ .path = "src/link.ld" });
kernel.code_model = .kernel;
kernel.setTarget(target);
kernel.setBuildMode(mode);
kernel.install();
kernel.strip = true;
}

View File

@ -0,0 +1,123 @@
pub const BOOTBOOT_MAGIC = "BOOT";
// default virtual addresses for level 0 and 1 static loaders
pub const BOOTBOOT_MMIO = 0xfffffffff8000000; // memory mapped IO virtual address
pub const BOOTBOOT_FB = 0xfffffffffc000000; // frame buffer virtual address
pub const BOOTBOOT_INFO = 0xffffffffffe00000; // bootboot struct virtual address
pub const BOOTBOOT_ENV = 0xffffffffffe01000; // environment string virtual address
pub const BOOTBOOT_CORE = 0xffffffffffe02000; // core loadable segment start
// minimum protocol level:
// hardcoded kernel name, static kernel memory addresses
pub const PROTOCOL_MINIMAL = 0;
// static protocol level:
// kernel name parsed from environment, static kernel memory addresses
pub const PROTOCOL_STATIC = 1;
// dynamic protocol level:
// kernel name parsed, kernel memory addresses from ELF or PE symbols
pub const PROTOCOL_DYNAMIC = 2;
// big-endian flag
pub const PROTOCOL_BIGENDIAN = 0x80;
// loader types, just informational
pub const LOADER_BIOS = 0 << 2;
pub const LOADER_UEFI = 1 << 2;
pub const LOADER_RPI = 2 << 2;
pub const LOADER_COREBOOT = 3 << 2;
// framebuffer pixel format, only 32 bits supported
pub const FramebufferFormat = enum(u8) {
ARGB = 0,
RGBA = 1,
ABGR = 2,
BGRA = 3,
};
// mmap entry, type is stored in least significant tetrad (half byte) of size
// this means size described in 16 byte units (not a problem, most modern
// firmware report memory in pages, 4096 byte units anyway).
pub const MMapEnt = extern struct {
ptr: u64 align(1),
size: u64 align(1),
const Self = @This();
pub inline fn getPtr(self: *Self) u64 {
return self.ptr;
}
pub inline fn getSizeInBytes(self: *Self) u64 {
return self.size & 0xFFFFFFFFFFFFFFF0;
}
pub inline fn getSizeIn4KiBPages(self: *Self) u64 {
return self.getSizeInBytes() / 4096;
}
pub inline fn getType(self: *Self) MMapType {
return @intToEnum(MMapType, @truncate(u4, self.size));
}
pub inline fn isFree(self: *Self) bool {
return (self.size & 0xF) == 1;
}
};
pub const MMapType = enum(u4) {
/// don't use. Reserved or unknown regions
MMAP_USED = 0,
/// usable memory
MMAP_FREE = 1,
/// acpi memory, volatile and non-volatile as well
MMAP_ACPI = 2,
/// memory mapped IO region
MMAP_MMIO = 3,
};
pub const INITRD_MAXSIZE = 16; // Mb
pub const BOOTBOOT = extern struct {
magic: [4]u8 align(1),
size: u32 align(1),
protocol: u8 align(1),
fb_type: u8 align(1),
numcores: u16 align(1),
bspid: u16 align(1),
timezone: i16 align(1),
datetime: [8]u8 align(1),
initrd_ptr: u64 align(1),
initrd_size: u64 align(1),
fb_ptr: u64 align(1),
fb_size: u32 align(1),
fb_width: u32 align(1),
fb_height: u32 align(1),
fb_scanline: u32 align(1),
arch: extern union {
x86_64: extern struct {
acpi_ptr: u64,
smbi_ptr: u64,
efi_ptr: u64,
mp_ptr: u64,
unused0: u64,
unused1: u64,
unused2: u64,
unused3: u64,
},
aarch64: extern struct {
acpi_ptr: u64,
mmio_ptr: u64,
efi_ptr: u64,
unused0: u64,
unused1: u64,
unused2: u64,
unused3: u64,
unused4: u64,
},
} align(1),
mmap: MMapEnt align(1),
};

BIN
mykernel/zig/src/font.psf Normal file

Binary file not shown.

57
mykernel/zig/src/link.ld Normal file
View File

@ -0,0 +1,57 @@
/*
* mykernel/c/link.ld
*
* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* This file is part of the BOOTBOOT Protocol package.
* @brief An example linker script for sample kernel
*
*/
ENTRY(_start)
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
fb = 0xfffffffffc000000;
bootboot = 0xffffffffffe00000;
environment = 0xffffffffffe01000;
/* initstack = 1024; */
PHDRS
{
boot PT_LOAD; /* one single loadable segment */
}
SECTIONS
{
. = 0xffffffffffe02000;
.text : {
KEEP(*(.text.boot)) *(.text .text.*) /* code */
*(.rodata .rodata.*) /* data */
*(.data .data.*)
} :boot
.bss (NOLOAD) : { /* bss */
. = ALIGN(16);
*(.bss .bss.*)
*(COMMON)
} :boot
/DISCARD/ : { *(.eh_frame) *(.comment) }
}

149
mykernel/zig/src/main.zig Normal file
View File

@ -0,0 +1,149 @@
/// mykernel/zig/src/main.zig
///
/// Copyright (C) 2022 binarycraft
///
/// Permission is hereby granted, free of charge, to any person
/// obtaining a copy of this software and associated documentation
/// files (the "Software"), to deal in the Software without
/// restriction, including without limitation the rights to use, copy,
/// modify, merge, publish, distribute, sublicense, and/or sell copies
/// of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be
/// included in all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
/// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
///
/// This file is part of the BOOTBOOT Protocol package.
/// @brief A sample BOOTBOOT compatible kernel
const std = @import("std");
const BOOTBOOT = @import("bootboot.zig").BOOTBOOT;
const fontEmbedded = @embedFile("font.psf");
// imported virtual addresses, see linker script
extern var bootboot: BOOTBOOT; // see bootboot.zig
extern var environment: [4096]u8; // configuration, UTF-8 text key=value pairs
extern var fb: u8; // linear framebuffer mapped
// Display text on screen
const PsfFont = packed struct {
magic: u32, // magic bytes to identify PSF
version: u32, // zero
headersize: u32, // offset of bitmaps in file, 32
flags: u32, // 0 if there's no unicode table
numglyph: u32, // number of glyphs
bytesperglyph: u32, // size of each glyph
height: u32, // height in pixels
width: u32, // width in pixels
};
// function to display a string
pub fn puts(string: []const u8) void {
const font = @bitCast(PsfFont, fontEmbedded[0..@sizeOf(PsfFont)].*);
var bytesperline = (font.width + 7) / 8;
var framebuffer = @intToPtr([*]u32, @ptrToInt(&fb));
for (string) |char, i| {
var offs = i * (font.width + 1) * 4;
var idx = if (char > 0 and char < font.numglyph) blk: {
break :blk font.headersize + (char * font.bytesperglyph);
} else blk: {
break :blk font.headersize + (0 * font.bytesperglyph);
};
{
var y: usize = 0;
while (y < font.height) : (y += 1) {
var line = offs;
var mask = @as(u32, 1) << @intCast(u5, font.width - 1);
{
var x: usize = 0;
while (x < font.width) : (x += 1) {
if ((fontEmbedded[idx] & mask) == 0) {
framebuffer[line / @sizeOf(u32)] = 0x000000;
} else {
framebuffer[line / @sizeOf(u32)] = 0xFFFFFF;
}
mask >>= 1;
line += 4;
}
}
framebuffer[line / @sizeOf(u32)] = 0;
idx += bytesperline;
offs += bootboot.fb_scanline;
}
}
}
}
// Entry point, called by BOOTBOOT Loader
export fn _start() callconv(.Naked) noreturn {
// NOTE: this code runs on all cores in parallel
var s = bootboot.fb_scanline;
var w = bootboot.fb_width;
var h = bootboot.fb_height;
var framebuffer = @intToPtr([*]u32, @ptrToInt(&fb));
if (s > 0) {
// cross-hair to see screen dimension detected correctly
{
var y: usize = 0;
while (y < h) : (y += 1) {
framebuffer[(s * y + w * 2) / @sizeOf(u32)] = 0x00FFFFFF;
}
}
{
var x: usize = 0;
while (x < w) : (x += 1) {
framebuffer[(s * (h / 2) + x * 4) / @sizeOf(u32)] = 0x00FFFFFF;
}
}
// red, green, blue boxes in order
{
var y: usize = 0;
while (y < 20) : (y += 1) {
var x: usize = 0;
while (x < 20) : (x += 1) {
framebuffer[(s * (y + 20) + (x + 20) * 4) / @sizeOf(u32)] = 0x00FF0000;
}
}
}
{
var y: usize = 0;
while (y < 20) : (y += 1) {
var x: usize = 0;
while (x < 20) : (x += 1) {
framebuffer[(s * (y + 20) + (x + 50) * 4) / @sizeOf(u32)] = 0x0000FF00;
}
}
}
{
var y: usize = 0;
while (y < 20) : (y += 1) {
var x: usize = 0;
while (x < 20) : (x += 1) {
framebuffer[(s * (y + 20) + (x + 80) * 4) / @sizeOf(u32)] = 0x000000FF;
}
}
}
// say hello
puts("Hello from a simple BOOTBOOT kernel");
}
// hang for now
while (true) {}
}

53
osdev.md Normal file
View File

@ -0,0 +1,53 @@
OSDev Lies
==========
Sadly that place isn't the place it used to be. Here are a few examples as a proof, lies spread most notably by
nexos and Octocontrabass:
["No, it does not."](https://forum.osdev.org/viewtopic.php?f=2&t=33362&p=337968&hilit=bootboot#p337968)
Yes, **it does**. BOOTBOOT does provide the same environment and a consistent, architecture-independent memory map on ALL supported platforms, see for yourself.
["BOOTBOOT is very finicky from what I've seen."](https://forum.osdev.org/viewtopic.php?f=1&t=56430&p=343068&hilit=bootboot#p343068)
A lie, and just an opinion based on bad education. Limine has exactly the same bad design decisions like GRUB, just far less tested, and it does not have a bootable image creator either.
["No, that's normal for BOOTBOOT."](https://forum.osdev.org/viewtopic.php?f=1&t=56430&p=343010&hilit=bootboot#p343010)
No, it's absolutely not.
["And it looks like BOOTBOOT doesn't correctly align the stack according to the System V ABI..."](https://forum.osdev.org/viewtopic.php?f=1&t=56430&p=343000&hilit=bootboot#p343000)
Bullshit, a clear cut lie, proved wrong by multiple working kernels using BOOTBOOT. (Since when address 0 isn't aligned with *anything*?)
["And is BOOTBOOT really a sane bootloader if it places arbitrary limits on the kernel size?"](https://forum.osdev.org/viewtopic.php?f=1&t=56430&p=342990&hilit=bootboot#p342990)
Show me one bootloader which does not limit the size. The memory has limits, no bootloader can load infinite size kernels. And does that carefully choosen 16Mb really concern you? My current Linux kernel is 10Mb, and man, that's not a hobby microkernel, but a bloated monolithic beast.
["BOOTBOOT is much more limited than whichever bootloader you're using, so your linker script won't work with BOOTBOOT."](https://forum.osdev.org/viewtopic.php?f=1&t=56430&p=342916&hilit=bootboot#p342916)
Another lie. BOOTBOOT requires your kernel to be linked at higher half to save you from the gdt trickery and trampoline mess, but that's not a limitation, quite the contrary.
["Now, it would be best practice to do what Limine does and create entries specifically for this kind of memory"](https://forum.osdev.org/viewtopic.php?f=1&t=51891&p=333429&hilit=bootboot#p333429)
Wrong. The reason why BOOTBOOT doesn't have such entries, because it does not pollute your memory, all bootloader memory is already freed by the time your kernel runs. If you really want to know the physical address of your own kernel, look it up in the initrd or walk the page tables.
Some more lies, unrelated to this project:
["I can safely say that Microsoft wasn't involved in the design until after the original EFI ABI and API were developed"](https://forum.osdev.org/viewtopic.php?p=331940#p331940)
Never mind it's acknowledged in the spec... and EFI just accidentally using MS' patented file system, MS' execute format, MS' ABI, MS' API, manufacturers ship MS' keys exclusively as it happens ...etc. But MS wasn't involved in EFI, yeah, sure...
["SDA specification does require using only exFAT for SDXC cards"](https://forum.osdev.org/viewtopic.php?f=15&t=42387&p=320913&hilit=sdhc+exfat#p320913)
No comment. Tell the Raspberry Pi guys they are just imagining booting Raspbian from ext4...
...etc. Long story short, avoid OSDev forum, it's now overtaken by paid trolls and has a very toxic athmosphere, where only klange's OS is considered a valid hobby OS.

View File

@ -302,15 +302,21 @@ realmode_start:
mov byte [cdromdev], al
@@:
;-----initialize serial port COM1,115200,8N1------
mov ax, 0401h
xor bx, bx
mov cx, 030Bh
xor dx, dx
int 14h
; if there's no serial, but BIOS incorrectly sets the IO port for it
; mov ax, 0401h
; xor bx, bx
; mov cx, 030Bh
; xor dx, dx
; int 14h
mov dx, word [400h]
or dx, dx
jz @f
jnz @f
; if the IO port isn't set, try the default one of COM1
mov dx, 3f8h
mov word [400h], dx
; initialize the serial outselves, because Bochs BIOS is buggy
@@: call serialsetup
; if there's no serial, but BIOS incorrectly sets the IO port for it
mov dx, word [400h]
add dx, 5
in al, dx
cmp al, 0FFh
@ -438,6 +444,32 @@ start_of_setup:
jmp 9000h:realmode_start-loader
; --- end of Linux boot protocol header ---
serialsetup:
inc dx
xor al, al
out dx, al ; IER int off
mov al, 80h
add dx, 2
out dx, al ; LCR set divisor mode
mov al, 1
sub dx, 3
out dx, al ; DLL divisor lo 115200
xor al, al
inc dx
out dx, al ; DLH divisor hi
inc dx
out dx, al ; FCR fifo off
mov al, 43h
inc dx
out dx, al ; LCR 8N1, break on
mov al, 8
inc dx
out dx, al ; MCR Aux out 2
xor al, al
sub dx, 4
in al, dx ; clear receiver/transmitter
ret
cpuok: DBG dbg_A20
;-----enable A20-----
@ -2974,30 +3006,30 @@ bsp_done: db 0 ;flag to indicate APs can run
fattype: db 0
bkp: dd ' '
if BBDEBUG eq 1
dbg_cpu db " * Detecting CPU",10,13,0
dbg_A20 db " * Enabling A20",10,13,0
dbg_mem db " * E820 Memory Map",10,13,0
dbg_systab db " * System tables",10,13,0
dbg_time db " * System time",10,13,0
dbg_serial db " * Initrd over serial",10,13,0
dbg_gpt db " * Reading GPT",10,13,0
dbg_cdrom db " * Detected CDROM boot",10,13,0
dbg_env db " * Environment",10,13,0
dbg_initrd db " * Initrd loaded",10,13,0
dbg_gzinitrd db " * Gzip compressed initrd",10,13,0
dbg_scan db " * Autodetecting kernel",10,13,0
dbg_elf db " * Parsing ELF64",10,13,0
dbg_pe db " * Parsing PE32+",10,13,0
dbg_cpu db " * Detecting CPU",13,10,0
dbg_A20 db " * Enabling A20",13,10,0
dbg_mem db " * E820 Memory Map",13,10,0
dbg_systab db " * System tables",13,10,0
dbg_time db " * System time",13,10,0
dbg_serial db " * Initrd over serial",13,10,0
dbg_gpt db " * Reading GPT",13,10,0
dbg_cdrom db " * Detected CDROM boot",13,10,0
dbg_env db " * Environment",13,10,0
dbg_initrd db " * Initrd loaded",13,10,0
dbg_gzinitrd db " * Gzip compressed initrd",13,10,0
dbg_scan db " * Autodetecting kernel",13,10,0
dbg_elf db " * Parsing ELF64",13,10,0
dbg_pe db " * Parsing PE32+",13,10,0
dbg_smp db " * SMP numcores ",0
dbg_madt db " (bad MADT)",0
dbg_vesa db " * Screen VESA VBE",10,13,0
dbg_vesa db " * Screen VESA VBE",13,10,0
end if
backup: db " * Backup initrd",10,13,0
backup: db " * Backup initrd",13,10,0
passphrase: db " * Passphrase? ",0
decrypting: db 13," * Decrypting...",0
clrdecrypt: db 13," ",13,0
starting: db "Booting OS..."
crlf: db 10,13,0
crlf: db 13,10,0
panic: db "-PANIC: ",0
noarch: db "Hardware not supported",0
a20err: db "Failed to enable A20",0
@ -3015,8 +3047,8 @@ bigcore: db "Kernel is too big",0
novbe: db "VESA VBE error, no framebuffer",0
nogzip: db "Unable to uncompress",0
notcdsect: db "Not 2048 sector aligned",0
nocipher: db "Unsupported cipher",10,13,0
badpass: db 13,"BOOTBOOT-ERROR: Bad passphrase",10,13,0
nocipher: db "Unsupported cipher",13,10,0
badpass: db 13,"BOOTBOOT-ERROR: Bad passphrase",13,10,0
cfgfile: db "sys/config",0,0,0
kernel: db "sys/core"
db (64-($-kernel)) dup 0