Compare commits
12 Commits
eb3edda68a
...
6ce3a4a2a8
Author | SHA1 | Date |
---|---|---|
bzt | 6ce3a4a2a8 | |
Binary Craft | d6845611e0 | |
Binary Craft | 33e59feaf4 | |
bzt | 1793d99368 | |
bzt | 47c01213e5 | |
bzt | ef5aa234c5 | |
bzt | 190375cfd6 | |
bzt | 77db2bf6d2 | |
bzt | 6b56345f01 | |
bzt | 2b3fb32025 | |
bzt | be253ad7a7 | |
bzt | 1a36775605 |
|
@ -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
|
||||
==================================
|
||||
|
|
Binary file not shown.
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
|
||||
fb = 0xfffffffffc000000;
|
||||
bootboot = 0xffffffffffe00000;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
|
||||
fb = 0xfffffffffc000000;
|
||||
bootboot = 0xffffffffffe00000;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
|
||||
fb = 0xfffffffffc000000;
|
||||
bootboot = 0xffffffffffe00000;
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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),
|
||||
};
|
Binary file not shown.
|
@ -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) }
|
||||
}
|
|
@ -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) {}
|
||||
}
|
|
@ -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.
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue