Use GAS instead of YASM.

This commit is contained in:
Dale Weiler 2015-05-20 03:12:20 -04:00
parent 7f66c10230
commit 01176e0f97
15 changed files with 408 additions and 340 deletions

2
.gitignore vendored
View File

@ -10,7 +10,7 @@
*.swn
*.toc
*.ko
kernel/symbols.s
kernel/symbols.S
.compositor-check
.config
.gdb_history

View File

@ -11,6 +11,7 @@ CC = i686-pc-toaru-gcc
NM = i686-pc-toaru-nm
CXX= i686-pc-toaru-g++
AR = i686-pc-toaru-ar
AS = i686-pc-toaru-as
# Build flags
CFLAGS = -O2 -std=c99
@ -19,6 +20,8 @@ CFLAGS += -Wall -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-format
CFLAGS += -pedantic -fno-omit-frame-pointer
CFLAGS += -D_KERNEL_
ASFLAGS = --32
# Kernel autoversioning with git sha
CFLAGS += -DKERNEL_GIT_TAG=`util/make-version`
@ -26,7 +29,8 @@ CFLAGS += -DKERNEL_GIT_TAG=`util/make-version`
YASM = yasm
# All of the core parts of the kernel are built directly.
KERNEL_OBJS = $(patsubst %.c,%.o,$(wildcard kernel/*/*.c))
KERNEL_OBJS = $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard kernel/*/*.S)))
KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/*/*.c))
KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/*/*/*.c))
# Loadable modules
@ -160,10 +164,11 @@ test: system
toolchain:
@cd toolchain; ./toolchain-build.sh
ASM_OBJS = kernel/boot.o kernel/gdt.o kernel/idt.o kernel/irq.o kernel/isr.o kernel/task.o kernel/tss.o kernel/user.o
################
# Kernel #
################
toaruos-kernel: kernel/start.o kernel/link.ld kernel/main.o kernel/symbols.o ${KERNEL_OBJS}
toaruos-kernel: ${ASM_OBJS} kernel/link.ld kernel/main.o kernel/symbols.o ${KERNEL_OBJS}
@${BEG} "CC" "$<"
@${CC} -T kernel/link.ld ${CFLAGS} -nostdlib -o toaruos-kernel kernel/*.o ${KERNEL_OBJS} -lgcc ${ERRORS}
@${END} "CC" "$<"
@ -171,18 +176,13 @@ toaruos-kernel: kernel/start.o kernel/link.ld kernel/main.o kernel/symbols.o ${K
kernel/symbols.o: ${KERNEL_OBJS} util/generate_symbols.py
@-rm -f kernel/symbols.o
@${BEG} "nm" "Generating symbol list..."
@${BEG} "NM" "Generating symbol list..."
@${CC} -T kernel/link.ld ${CFLAGS} -nostdlib -o toaruos-kernel kernel/*.o ${KERNEL_OBJS} -lgcc ${ERRORS}
@${NM} toaruos-kernel -g | python2 util/generate_symbols.py > kernel/symbols.s
@${END} "nm" "Generated symbol list."
@${BEG} "yasm" "kernel/symbols.s"
@${YASM} -f elf -o $@ kernel/symbols.s ${ERRORS}
@${END} "yasm" "kernel/symbols.s"
kernel/start.o: kernel/start.s
@${BEG} "yasm" "$<"
@${YASM} -f elf -o $@ $< ${ERRORS}
@${END} "yasm" "$<"
@${NM} toaruos-kernel -g | python2 util/generate_symbols.py > kernel/symbols.S
@${END} "NM" "Generated symbol list."
@${BEG} "AS" "kernel/symbols.S"
@${AS} ${ASFLAGS} kernel/symbols.S -o $@ ${ERRORS}
@${END} "AS" "kernel/symbols.S"
kernel/sys/version.o: kernel/*/*.c kernel/*.c
@ -191,6 +191,11 @@ hdd/mod/%.ko: modules/%.c ${HEADERS}
@${CC} -T modules/link.ld -I./kernel/include -nostdlib ${CFLAGS} -c -o $@ $< ${ERRORS}
@${END} "CC" "$< [module]"
kernel/%.o: kernel/%.S
@${BEG} "AS" "$<"
@${AS} ${ASFLAGS} $< -o $@ ${ERRORS}
@${END} "AS" "$<"
kernel/%.o: kernel/%.c ${HEADERS}
@${BEG} "CC" "$<"
@${CC} ${CFLAGS} -nostdlib -g -I./kernel/include -c -o $@ $< ${ERRORS}

57
kernel/boot.S Normal file
View File

@ -0,0 +1,57 @@
.set MB_MAGIC, 0x1BADB002
.set MB_FLAG_PAGE_ALIGN, 1 << 0
.set MB_FLAG_MEMORY_INFO, 1 << 1
.set MB_FLAG_GRAPHICS, 1 << 2
.set MB_FLAGS, MB_FLAG_PAGE_ALIGN | MB_FLAG_MEMORY_INFO | MB_FLAG_GRAPHICS
.set MB_CHECKSUM, -(MB_MAGIC + MB_FLAGS)
.section .multiboot
.align 4
/* Multiboot section */
.long MB_MAGIC
.long MB_FLAGS
.long MB_CHECKSUM
.long 0x00000000 /* header_addr */
.long 0x00000000 /* load_addr */
.long 0x00000000 /* load_end_addr */
.long 0x00000000 /* bss_end_addr */
.long 0x00000000 /* entry_addr */
/* Request linear graphics mode */
.long 0x00000000
.byte 0
.byte 0
.byte 32
/* .stack resides in .bss */
.section .stack, "aw", @nobits
stack_bottom:
.skip 16384 /* 16KiB */
stack_top:
.section .text
.global start
.type start, @function
.extern kmain
.type kmain, @function
start:
/* Setup our stack */
mov $stack_top, %esp
pushl %esp
pushl %eax /* Multiboot header magic */
pushl %ebx /* Multiboot header pointer */
/* Disable interrupts and call kernel proper */
cli
call kmain
/* Clear interrupts and hang if we return from kmain */
cli
hang:
hlt
jmp hang

View File

@ -43,7 +43,7 @@ struct gdt_ptr gp;
* (ASM) gdt_flush
* Reloads the segment registers
*/
extern void gdt_flush(void);
extern void gdt_flush(unsigned int);
/**
* Set a GDT descriptor
@ -96,7 +96,7 @@ gdt_install(void) {
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
write_tss(5, 0x10, 0x0);
/* Go go go */
gdt_flush();
gdt_flush((unsigned int)&gp);
tss_flush();
}

View File

@ -31,7 +31,7 @@ struct idt_ptr {
struct idt_entry idt[256];
struct idt_ptr idtp;
extern void idt_load(void);
extern void idt_load(unsigned int);
/*
* idt_set_gate
@ -59,5 +59,5 @@ void idt_install(void) {
idtp.base = (uintptr_t)&idt;
memset(&idt, 0, sizeof(struct idt_entry) * 256);
idt_load();
idt_load((unsigned int)&idtp);
}

20
kernel/gdt.S Normal file
View File

@ -0,0 +1,20 @@
.section .text
.align 4
.global gdt_flush
.type gdt_flush, @function
gdt_flush:
/* Load GDT */
mov 4(%esp), %eax
lgdt (%eax)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %ss
ljmp $0x08, $.flush
.flush:
ret

10
kernel/idt.S Normal file
View File

@ -0,0 +1,10 @@
.section .text
.align 4
.global idt_load
.type idt_load, @function
idt_load:
mov 4(%esp), %eax
lidt (%eax)
ret

68
kernel/irq.S Normal file
View File

@ -0,0 +1,68 @@
.section .text
.align 4
.macro IRQ ident byte
.global _irq\ident
.type _irq\ident, @function
_irq\ident:
cli
push $0x00
push $\byte
jmp irq_common
.endm
/* Interrupt Requests */
IRQ 0, 32
IRQ 1, 33
IRQ 2, 34
IRQ 3, 35
IRQ 4, 36
IRQ 5, 37
IRQ 6, 38
IRQ 7, 39
IRQ 8, 40
IRQ 9, 41
IRQ 10, 42
IRQ 11, 43
IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47
.extern irq_handler
.type irq_handler, @function
irq_common:
/* Save all registers */
pusha
/* Save segment registers */
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
/* Call interrupt handler */
mov %esp, %eax
push %eax
mov $irq_handler, %eax
call *%eax
pop %eax
/* Restore segment registers */
pop %gs
pop %fs
pop %es
pop %ds
/* Restore all registers */
popa
/* Cleanup error code and IRQ # */
add $8, %esp
/* pop CS, EIP, EFLAGS, SS and ESP */
iret

92
kernel/isr.S Normal file
View File

@ -0,0 +1,92 @@
.section .text
.align 4
.macro ISR_NOERR index
.global _isr\index
_isr\index:
cli
push $0
push $\index
jmp isr_common
.endm
.macro ISR_ERR index
.global _isr\index
_isr\index:
cli
push $\index
jmp isr_common
.endm
/* Standard X86 interrupt service routines */
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_NOERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_NOERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31
ISR_NOERR 127
.extern fault_handler
.type fault_handler, @function
isr_common:
/* Push all registers */
pusha
/* Save segment registers */
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
/* Call fault handler */
mov %esp, %eax
push %eax
mov $fault_handler, %eax
call *%eax
pop %eax
/* Restore segment registers */
pop %gs
pop %fs
pop %es
pop %ds
/* Restore registers */
popa
/* Cleanup error code and ISR # */
add $8, %esp
/* pop CS, EIP, EFLAGS, SS and ESP */
iret

View File

@ -3,46 +3,43 @@
*/
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
/*
* Actual code
*/
.text phys : AT(phys) {
. = 1M;
phys = .;
.text BLOCK(4K) : ALIGN(4K)
{
code = .;
*(.multiboot*)
*(.text*)
*(.rodata*)
. = ALIGN(4096);
*(.multiboot)
*(.text)
}
/*
* Kernel data
*/
.data : AT(phys + (data - code))
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
.data BLOCK(4K) : ALIGN(4K)
{
data = .;
*(.data*)
*(.data)
*(.symbols)
PROVIDE(kernel_symbols_start = .);
PROVIDE(kernel_symbols_end = .);
. = ALIGN(4096);
}
/*
* Statically defined, uninitialized values
*/
.bss : AT(phys + (bss - code))
.bss BLOCK(4K) : ALIGN(4K)
{
bss = .;
*(.bss*)
. = ALIGN(4096);
*(COMMON)
*(.bss)
*(.stack)
}
/*
* End of kernel.
*/
end = .;
/*
* Get rid of unnecessary GCC bits.
*/
/DISCARD/ :
{
*(.comment)

View File

@ -1,271 +0,0 @@
; ToAruOS Start Up / Entry Point
;
; This file is part of ToaruOS and is released under the terms
; of the NCSA / University of Illinois License - see LICENSE.md
; Copyright (C) 2013-2014 Kevin Lange
;
BITS 32
ALIGN 4
SECTION .multiboot
mboot:
; Multiboot headers:
; Page aligned loading, please
MULTIBOOT_PAGE_ALIGN equ 1<<0
; We require memory information
MULTIBOOT_MEMORY_INFO equ 1<<1
; We would really, really like graphics...
MULTIBOOT_USE_GFX equ 1<<2
; We are multiboot compatible!
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
; Load up those flags.
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_USE_GFX
; Checksum the result
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
; Load the headers into the binary image.
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
dd 0x00000000 ; header_addr
dd 0x00000000 ; load_addr
dd 0x00000000 ; load_end_addr
dd 0x00000000 ; bss_end_addr
dd 0x00000000 ; entry_addr
; Graphics requests
dd 0x00000000 ; 0 = linear graphics
dd 0
dd 0
dd 32 ; Set me to 32 or else.
SECTION .text
; Some external references.
extern code, bss, end
; Main entrypoint
global start
start:
; Set up stack pointer.
mov esp, 0x7FFFF
push esp
; Push the incoming mulitboot headers
push eax ; Header magic
push ebx ; Header pointer
; Disable interrupts
cli
; Call the C entry
extern kmain
call kmain
jmp $
; Global Descriptor Table
global gdt_flush
extern gp
gdt_flush:
; Load the GDT
lgdt [gp]
; Flush the values to 0x10
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:flush2
flush2:
ret
; Interrupt Descriptor Table
global idt_load
extern idtp
idt_load:
lidt [idtp]
ret
; Return to Userspace (from thread creation)
global return_to_userspace
return_to_userspace:
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
; Interrupt Service Routines
%macro ISR_NOERR 1
global _isr%1
_isr%1:
cli
push byte 0
push byte %1
jmp isr_common_stub
%endmacro
%macro ISR_ERR 1
global _isr%1
_isr%1:
cli
push byte %1
jmp isr_common_stub
%endmacro
%macro IRQ_ENTRY 2
global _irq%1
_irq%1:
cli
push byte 0
push byte %2
jmp irq_common_stub
%endmacro
; Standard X86 interrupt service routines
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_NOERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_NOERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31
ISR_NOERR 127
; Interrupt Requests
IRQ_ENTRY 0, 32
IRQ_ENTRY 1, 33
IRQ_ENTRY 2, 34
IRQ_ENTRY 3, 35
IRQ_ENTRY 4, 36
IRQ_ENTRY 5, 37
IRQ_ENTRY 6, 38
IRQ_ENTRY 7, 39
IRQ_ENTRY 8, 40
IRQ_ENTRY 9, 41
IRQ_ENTRY 10, 42
IRQ_ENTRY 11, 43
IRQ_ENTRY 12, 44
IRQ_ENTRY 13, 45
IRQ_ENTRY 14, 46
IRQ_ENTRY 15, 47
; Interrupt handlers
extern fault_handler
isr_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
; Call the C kernel fault handler
mov eax, fault_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
extern irq_handler
irq_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
; Call the C kernel hardware interrupt handler
mov eax, irq_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
global read_eip
read_eip: ; Clever girl
pop eax
jmp eax
global copy_page_physical
copy_page_physical:
push ebx
pushf
cli
mov ebx, [esp+12]
mov ecx, [esp+16]
mov edx, cr0
and edx, 0x7FFFFFFF
mov cr0, edx
mov edx, 0x400
.page_loop:
mov eax, [ebx]
mov [ecx], eax
add ebx, 4
add ecx, 4
dec edx
jnz .page_loop
mov edx, cr0
or edx, 0x80000000
mov cr0, edx
popf
pop ebx
ret
global tss_flush
tss_flush:
mov ax, 0x2B
ltr ax
ret
; BSS Section
SECTION .bss
resb 8192 ; 8KB of memory reserved

54
kernel/task.S Normal file
View File

@ -0,0 +1,54 @@
.section .text
.align 4
.global copy_page_physical
.type copy_page_physical, @function
.set dp, 0x7FFFFFFF
.set ep, 0x80000000
copy_page_physical:
/* Preserve contents of EBX */
push %ebx
/* Preserve contents of EFLAGS */
pushf
cli
/* Load source and destination addresses */
mov 12(%esp), %ebx
mov 16(%esp), %ecx
/* Get control register and disable paging*/
mov %cr0, %edx
and $dp, %edx
mov %edx, %cr0
/* Copy 4096 bytes */
mov $0x400, %edx
.page_loop:
/* Get word at source address */
mov (%ebx), %eax
/* Store it at destination address */
mov %eax, (%ecx)
/* Increment source and destination addresses to next word */
add $4, %ebx
add $4, %ecx
/* One less word to copy */
dec %edx
jnz .page_loop
/* Get control register again and enable paging */
mov %cr0, %edx
or $ep, %edx
mov %edx, %cr0
/* Restore EFLAGS */
popf
/* Restore EBX */
pop %ebx
ret

10
kernel/tss.S Normal file
View File

@ -0,0 +1,10 @@
.section .text
.align 4
.global tss_flush
.type tss_flush, @function
tss_flush:
mov $0x2B, %ax
ltr %ax
ret

21
kernel/user.S Normal file
View File

@ -0,0 +1,21 @@
/* Return to Userspace (from thread creation) */
.global return_to_userspace
.type return_to_userspace, @function
return_to_userspace:
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
iret
/* Read EIP */
.global read_eip
.type read_eip, @function
read_eip:
mov (%esp), %eax
ret

View File

@ -4,32 +4,37 @@
Generate a symbol table from nm output.
"""
import fileinput
import sys
def formatLine(line):
_, _, name = line.strip().split(" ")
if name == "abs":
# abs is a keyword, so we'll just pretend we don't have that
return
if name == "kernel_symbols_start" or name == "kernel_symbols_end":
# we also don't want to include ourselves...
return
zeroes = ", 0" # * (1 + 4 - ((len(name) + 1) % 4))
print """
extern %s
dd %s
db '%s'%s""" % (name, name, name, zeroes)
# Write extern + type
def extern(name):
print ".extern %s" % (name)
print ".type %s, @function" % (name)
print ""
# Write an entry
def entry(name):
print ".long %s" % (name)
print ".asciz \"%s\"" % (name)
print ""
print "SECTION .symbols"
ignore = [ "abs", "kernel_symbols_start", "kernel_symbols_end" ]
lines = [ x.strip().split(" ")[2] for x in sys.stdin.readlines() if x not in ignore ]
print "global kernel_symbols_start"
# Generate the assembly
print ".section .symbols"
print ""
for name in lines:
extern(name)
print ".global kernel_symbols_start"
print "kernel_symbols_start:"
for line in fileinput.input():
formatLine(line)
print ""
for name in lines:
entry(name)
print "global kernel_symbols_end"
print "kernel_symbols_end: ;"
print ".global kernel_symbols_end"
print "kernel_symbols_end:"