feat(kernel): probe hardware

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-07-21 18:14:38 +02:00
parent f20f1cc398
commit 78340367b8
15 changed files with 170 additions and 244 deletions

View file

@ -27,6 +27,7 @@ SRCS = kernel.asm \
dev/at/pit.inc \ dev/at/pit.inc \
dev/at/cga.inc \ dev/at/cga.inc \
dev/at/kbd.inc \ dev/at/kbd.inc \
dev/at/com.inc \
dev/at/floppy.inc \ dev/at/floppy.inc \
dev/dev.inc \ dev/dev.inc \
fs/fat.inc \ fs/fat.inc \

View file

@ -8,6 +8,8 @@ COM2 = 0x2F8
COM3 = 0x3E8 COM3 = 0x3E8
COM4 = 0x2E8 COM4 = 0x2E8
NCOM = 4
UART8250_RBR = 0x0 UART8250_RBR = 0x0
UART8250_THR = 0x0 UART8250_THR = 0x0
@ -25,9 +27,58 @@ UART8250_DLL = 0x0
UART8250_DLH = 0x1 UART8250_DLH = 0x1
com_init: com_init:
mov ax, COM1
call com_probe
or eax, eax
jnz @f
mov esi, szMsgCom1Found
call klog
@@:
mov ax, COM2
call com_probe
or eax, eax
jnz @f
mov esi, szMsgCom2Found
call klog
@@:
mov ax, COM3
call com_probe
or eax, eax
jnz @f
mov esi, szMsgCom3Found
call klog
@@:
mov ax, COM4
call com_probe
or eax, eax
jnz @f
mov esi, szMsgCom4Found
call klog
@@:
ret ret
;; Function: com_probe
com_probe: com_probe:
mov dx, ax
add dx, UART8250_LCR
xor al, al
out dx, al
dec dx
out dx, al
xor ecx, ecx
@@:
inc ecx
cmp ecx, 100
jbe @b
in al, dx
and al, 0x38
or al, al
jz @f
mov eax, 1
ret
@@:
xor eax, eax
ret ret
com_irq1: com_irq1:
@ -41,6 +92,52 @@ com_irq2:
popa popa
iret iret
com_open:
ret
com_close:
ret
com_read:
ret
com_write:
ret
com_ioctl:
ret
com_select:
ret
com_stop:
ret
com_mmap:
ret
com_reset:
ret
uCom1Lock dd 0
uCom2Lock dd 0
uComActive db 0
szMsgCom1Found db "COM: com1 found", 0
szMsgCom2Found db "COM: com2 found", 0
szMsgCom3Found db "COM: com3 found", 0
szMsgCom4Found db "COM: com4 found", 0
com_device: com_device:
db 'com', 0, 0, 0, 0, 0 db 'com', 0, 0, 0, 0, 0
dd com_init dd com_init
com_cdevsw:
dd com_open
dd com_close
dd com_read
dd com_write
dd com_ioctl
dd com_select
dd com_stop
dd com_mmap
dd com_reset

View file

@ -91,7 +91,7 @@ floppy_device:
db FLOPPY_BDEV_MAJOR db FLOPPY_BDEV_MAJOR
db FLOPPY_CDEV_MAJOR db FLOPPY_CDEV_MAJOR
floppy_blockdev: floppy_bdevsw:
dd floppy_open dd floppy_open
dd floppy_strategy dd floppy_strategy
dd floppy_ioctl dd floppy_ioctl

View file

@ -76,3 +76,8 @@ aKbdNormalMap:
kbd_device: kbd_device:
db 'kbd', 0, 0, 0, 0, 0 db 'kbd', 0, 0, 0, 0, 0
dd kbd_init dd kbd_init
kbd_cdevws:
dd 0
dd 0
dd 0

View file

@ -63,17 +63,29 @@ NE2K_MAR6 = NE2K_IOBASE + 0xE
NE2K_MAR7 = NE2K_IOBASE + 0xF NE2K_MAR7 = NE2K_IOBASE + 0xF
ne2k_init: ne2k_init:
call ne2k_probe
or eax, eax
jnz @f
mov esi, szMsgNe2kfound
call klog
mov dx, NE2K_IOBASE mov dx, NE2K_IOBASE
in al, dx in al, dx
out dx, al out dx, al
mov al, NE2K_CR_STP mov al, NE2K_CR_STP
out dx, al out dx, al
@@:
ret ret
ne2k_probe: ne2k_probe:
mov dx, NE2K_IOBASE + NE2K_CR
in al, dx
and al, 0x27
cmp al, 0x21
jne @f
xor eax, eax
@@:
ret ret
ne2k_irq: ne2k_irq:
@ -82,3 +94,5 @@ ne2k_irq:
ne2k_device: ne2k_device:
db 'ne2k', 0, 0, 0, 0 db 'ne2k', 0, 0, 0, 0
dd ne2k_init dd ne2k_init
szMsgNe2kfound db "NE2K: found", 0

0
kernel/dev/at/pccons.inc Normal file
View file

View file

@ -25,4 +25,8 @@ console_device:
dd console_write dd console_write
dd console_write dd console_write
console_cdevws:
dd 0
dd 0
uConsoleLock dd 0 uConsoleLock dd 0

View file

@ -1,4 +1,13 @@
;; File: dev.inc ;; File: dev.inc
include 'at/cmos.inc'
include 'at/com.inc'
include 'at/ne2k.inc'
include 'at/pit.inc'
include 'at/kbd.inc'
include 'at/cga.inc'
include 'at/floppy.inc'
struc Device { struc Device {
.name db 8 dup(?) .name db 8 dup(?)
.init dd ? .init dd ?
@ -27,11 +36,12 @@ struc CharDev {
} }
aBlockDevices: aBlockDevices:
dd 10 dup(0) dd floppy_bdevsw
.end: .end:
aCharDevices: aCharDevices:
dd 10 dup(0) dd console_cdevws
dd com_cdevsw
.end: .end:
aDevices: aDevices:

0
kernel/dev/tty.inc Normal file
View file

View file

@ -95,7 +95,7 @@ struc StpdFS_FreeList {
;; .freelist - See <StpdFS_FreeList> ;; .freelist - See <StpdFS_FreeList>
;; .rev - See <STPDFS_SB_REV> ;; .rev - See <STPDFS_SB_REV>
;; .state - See <StupidFS State> ;; .state - See <StupidFS State>
;; .time - Last access time (64bit UNIX timestamp) ;; .time - Last mod time (64bit UNIX timestamp)
struc StpdFS_Sb { struc StpdFS_Sb {
.magic dd ? .magic dd ?
.isize dd ? .isize dd ?

View file

@ -40,6 +40,8 @@ kmain:
mov esi, szMsgKernelAlive mov esi, szMsgKernelAlive
call klog call klog
mov esi, szMsgBuildDate
call klog
; init pmm (kend, 0x400000) ; init pmm (kend, 0x400000)
mov eax, kend mov eax, kend
@ -77,6 +79,8 @@ kmain:
call pit_init call pit_init
call proc_init
call dev_init call dev_init
call vfs_init call vfs_init
@ -88,7 +92,7 @@ kmain:
;call cga_putc ;call cga_putc
.halt: .halt:
hlt ; hlt
jmp $ jmp $
.error_magic: .error_magic:
mov esi, szErrorBootProtocol mov esi, szErrorBootProtocol
@ -96,13 +100,6 @@ kmain:
call klog call klog
jmp .halt jmp .halt
include 'dev/at/cmos.inc'
include 'dev/at/com.inc'
include 'dev/at/ne2k.inc'
include 'dev/at/pit.inc'
include 'dev/at/kbd.inc'
include 'dev/at/cga.inc'
include 'dev/at/floppy.inc'
include 'klog.inc' include 'klog.inc'
include 'dev/console.inc' include 'dev/console.inc'
include 'dev/dev.inc' include 'dev/dev.inc'
@ -122,6 +119,7 @@ kmain:
szMsgKernelAlive db "Kernel (", VERSION_FULL , ") is alive", 0 szMsgKernelAlive db "Kernel (", VERSION_FULL , ") is alive", 0
szMsgBuildDate db "Built ", BUILD_DATE, 0
szErrorBootProtocol db "Error: wrong magic number", 0 szErrorBootProtocol db "Error: wrong magic number", 0
boot_structure BootInfo boot_structure BootInfo

View file

@ -6,6 +6,32 @@ proc_init:
ret ret
proc_alloc:
mov eax, uProcLock
call lock_acquire
xor ecx, ecx
@@:
mov eax, [ecx + Process.state]
or eax, eax
jz @f
add ecx, sizeof.Process
cmp ecx, sizeof.Process * 64
jb @b
mov esi, szErrorNoFreeProcess
call klog
mov eax, -1
jmp .end
@@:
.end:
push eax
mov eax, uProcLock
call lock_release
pop eax
ret
uProcLock dd 0 uProcLock dd 0
pCurrentProc dd 0 pCurrentProc dd 0
szErrorNoFreeProcess db "Error: can't alloc new process", 0

View file

@ -8,12 +8,12 @@ struc Context {
DEFN Context DEFN Context
struc Process { struc Process {
.state dd ?
.pagedir dd ? .pagedir dd ?
.kstack dd ? .kstack dd ?
.parent dd ? .parent dd ?
.trapframe dd ? .trapframe dd ?
.context dd ? .context dd ?
.next dd ?
} }
DEFN Process DEFN Process

View file

@ -1,11 +1,8 @@
TARGET = fat$(EXEXT) coff-ld$(EXEXT) parted$(EXEXT) readcoff$(EXEXT) elf2coff$(EXEXT) TARGET = coff-ld$(EXEXT) parted$(EXEXT) readcoff$(EXEXT) elf2coff$(EXEXT)
.PHONY: all .PHONY: all
all: $(TARGET) all: $(TARGET)
fat$(EXEXT): fat.c
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
coff-ld$(EXEXT): ../bin/ld/main.c coff-ld$(EXEXT): ../bin/ld/main.c
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)

View file

@ -1,226 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <libgen.h>
#include <errno.h>
typedef struct
{
uint8_t jmp[3];
uint8_t OEM[8];
uint16_t bytes_per_sector;
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t number_of_FATs;
uint16_t root_entries;
uint16_t logical_sectors;
uint8_t media_descriptor;
uint16_t sectors_per_FAT;
uint16_t sectors_per_track;
uint16_t heads_per_cylinder;
uint32_t hidden_sectors;
uint32_t total_sectors;
/* EBPB */
uint8_t drive_number;
uint8_t flags;
uint8_t signature;
uint32_t serial;
uint8_t label[11];
uint8_t fs_type[8];
} __attribute__((packed)) BiosParamBlock;
typedef struct
{
uint8_t name[8];
uint8_t ext[3];
uint8_t attr;
uint16_t reserved0;
uint16_t creation_time;
uint16_t creation_date;
uint16_t access_date;
uint16_t reserved1;
uint16_t mod_time;
uint16_t mod_date;
uint16_t start;
uint32_t size;
} __attribute__((packed)) Entry;
static const char *prg_name;
static int sector_size = 512;
static void
fatal(const char *str, ...)
{
va_list ap;
fprintf(stderr, "%s: ", prg_name);
va_start(ap, str);
vfprintf(stderr, str, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
static void
read_sector(uint8_t *dest, int sect, FILE *fp)
{
if (fseek(fp, sect*sector_size, SEEK_SET) != 0) goto fatal_sect;
if (fread(dest, 1, sector_size, fp) != sector_size) goto fatal_sect;
return;
fatal_sect:
fatal("Can't read sector %d", sect);
}
static void
dump_bpb(BiosParamBlock *bpb)
{
char label[12];
printf("Bytes per logical sector: %hd\n", bpb->bytes_per_sector);
sector_size = bpb->bytes_per_sector;
printf("Logical sectors per cluster: %d\n", bpb->sectors_per_cluster);
printf("Reserved logical sectors: %hd\n", bpb->reserved_sectors);
printf("Number of FATs: %d\n", bpb->number_of_FATs);
printf("Root directory entries: %hd\n", bpb->root_entries);
printf("Total logical sectors: %hd\n", bpb->logical_sectors);
printf("Logical sectors per FAT: %hd\n", bpb->sectors_per_FAT);
printf("Serial: %X\n", bpb->serial);
memset(label, 0, 12);
strncpy(label, bpb->label, 11);
printf("Label: '%s'\n", label);
printf("signature: %X\n", bpb->signature);
}
static void
dump_entry(Entry *entry)
{
char filename[9];
char ext[4];
int i;
if (entry->name[0] == 0x0) return;
memset(filename, 0, 9);
strncpy(filename, entry->name, 8);
memset(ext, 0, 4);
strncpy(ext, entry->ext, 3);
for (i = 7; i > 0; i--)
{
if (filename[i] == ' ')
{
filename[i] = '\0';
}
else
{
break;
}
}
printf("%s.%s\n", filename, ext);
}
static void
dump(const char *img)
{
FILE *fp;
BiosParamBlock *bpb;
uint8_t buffer[512];
int root_start;
int root_size;
int i;
int j;
fp = fopen(img, "rb");
if (fp == NULL) fatal("Can't open '%s': %s", img, strerror(errno));
read_sector(buffer, 0, fp);
if (buffer[511] != 0xAA || buffer[510] != 0x55)
{
fatal("MBR not found");
}
bpb = (BiosParamBlock *)buffer;
dump_bpb(bpb);
root_start = bpb->sectors_per_FAT * bpb->number_of_FATs;
root_start += bpb->reserved_sectors;
root_size = bpb->root_entries / (sector_size >> 0x5);
for (i = 0; i < root_size; i++)
{
read_sector(buffer, root_start + i, fp);
for (j = 0; j < sector_size; j+=32)
{
dump_entry((Entry *)(buffer + j));
}
}
fclose(fp);
exit(EXIT_SUCCESS);
}
static void
usage(int retcode)
{
if (retcode == EXIT_FAILURE)
{
fprintf(stderr, "Try '%s -h' form more information.\n", prg_name);
}
else
{
printf("Usage: %s [-hV] [-D IMG] [-b BIN]\n", prg_name);
printf("\t-h\tdisplay this help and exit\n");
printf("\t-V\toutput version information\n");
printf("\t-D IMG\tdump fs information from IMG\n");
printf("\nReport bugs to <%s>\n", MK_BUGREPORT);
}
exit(retcode);
}
static void
version(void)
{
printf("%s commit %s\n", prg_name, MK_COMMIT);
exit(EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
prg_name = argv[0];
while ((argc > 1) && (argv[1][0] == '-'))
{
switch (argv[1][1])
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
case 'D':
argv++;
argc--;
if (argc <= 1) usage(EXIT_FAILURE);
dump(argv[1]);
break;
default:
usage(EXIT_FAILURE);
break;
}
argv++;
argc--;
}
return (EXIT_SUCCESS);
}