Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Trying to write an OS.. Help me a bit? 1

Status
Not open for further replies.

DevPortal

Programmer
Jul 8, 2005
40
US
I'm utilizing a bootloader I found online which I modified. It can load a COM file after booting, and supports minimal error handling. It is copyrighted, so if anyone has a bootloader which I can have that can load a .com file or any other file type that can be made in C or assembly, please tell me. Also: My current problem (while utilizing the bootloader i have) is that I am trying to write a kernel. I am trying to program for keyboard support so that the user can type things in, and then I can have the OS jump to different code based on what they type in. It will be a very simple setup, but this is what i'd like for now. Currently I have this: (i'm new to assembly, so there may well be errors, and the output of this SHOULD [but doesn't] allow the user to display one keypress at a time.)

inputloop:
int 9
in al, 60h
msg db, al
bios_print_string msg
jmp inputloop
 
I've realized two flaws in the code, one is that it is loading 10 sectors, so I have reduced that to 1 (my com's are 1kb each, which is minimum on a floppy). Also, this code is using JMP, i am going to try using CALL. ..will post results...
 
A sector is 512 bytes so if you programs are 1k then you will need to load two sectors.
 
Oh durr. That means that one is overwriting the other as well. I was thinking that sectors were 512K not 512 bytes... I'll try that then! >.^
 
Ok since I cannot seem to toubleshoot this myself, I'll give you all my code and tell you how/where it is written to my floppy.

First, I have this code, written in bin form using rawrite:

; NYAOS Boot Sector (C) Copyright Sean Tash 1998
; Serpent Boot Sector - DevPortal 2005 Modified from Above
; assemble with: nasm
bits 16
org 0x7C00

start: jmp short begin
nop
bsOEM db "Serpent1" ; OEM String
bsSectSize dw 512 ; Bytes per sector
bsClustSize db 1 ; Sectors per cluster
bsRessect dw 1 ; # of reserved sectors
bsFatCnt db 2 ; # of fat copies
bsRootSize dw 224 ; size of root directory
bsTotalSect dw 2880 ; total # of sectors if < 32 meg
bsMedia db 0xF0 ; Media Descriptor
bsFatSize dw 9 ; Size of each FAT
bsTrackSect dw 18 ; Sectors per track
bsHeadCnt dw 2 ; number of read-write heads
bsHidenSect dd 0 ; number of hidden sectors
bsHugeSect dd 0 ; if bsTotalSect is 0 this value is
; the number of sectors
bsBootDrv db 0 ; holds drive that the bs came from
bsReserv db 0 ; not used for anything
bsBootSign db 29h ; boot signature 29h
bsVolID dd 0 ; Disk volume ID also used for temp
; sector # / # sectors to load
bsVoLabel db "NO NAME " ; Volume Label
bsFSType db "FAT12 " ; File System type

begin: cli ; disable interrupts
mov [bsBootDrv],dl ; save drive number
mov ax,0x9000 ; put stack at 0x98000
mov ss,ax
mov sp,0x8000

mov cx,[bsTrackSect] ; update int 1E FDC param table
mov bx,0x0078
lds si,[ds:bx]
mov byte [si+4], cl
mov byte [si+9], 0x0F

sti ; enable interrupts
push ds
mov dl,[bsBootDrv] ; reset controller
xor ax,ax
int 0x13
pop ds
jc bootfail2 ; display error message
jmp _l1
bootfail2: jmp bootfail
_l1:
mov ax,0x0000
mov es,ax
mov ds,ax

mov si,MsgLoad ; display load message
call putstr

; find the root directory

xor ax,ax
mov al,[bsFatCnt]
mov bx,[bsFatSize]
mul bx
add ax,word [bsHidenSect]
adc ax,word [bsHidenSect+2]
add ax,word [bsRessect] ; ax holds root directory location
mov word [BootSig],ax

call checkroot

xor ax,ax
add ax,word [start]
add ax,word [bsVolID] ; sector number
add ax,word [BootSig]
sub ax,2 ; correction for a mis-calc
mov cx,word [bsVolID+2] ; number of sectors

mov bx,0x8000
mov es,bx


nextsector: push ax ; save registers
push cx
push dx
push es

xor bx,bx ; set zero offset
call readsect ; read a sector

mov si,MsgDot ; display a dot
call putstr

pop es ; restore registers
pop dx
pop cx
pop ax
mov bx,es
add bx,20h ; increment address 512 bytes
mov es,bx
inc ax ; read next sector
loopnz nextsector

mov ax,0x8000 ; set segment registers and jump
mov es,ax
mov ds,ax
push ax
mov ax,0
push ax
retf

checkroot:
push ax ; save registers
push bx
push cx
push dx
push si
push di

mov ax,0x8000 ; put root directory at 0x80000
mov es,ax
mov ax,32 ; AX = ((32*RootSize)/512) + 2
mul word [bsRootSize]
div word [bsSectSize]
mov cx,ax ; cx holds # of sectors in root
mov word [start],ax
mov ax,word [BootSig] ; get prev. saved loc. for root dir

r1: xor bx,bx
push cx ; save count
push ax ; save sector number
push es
push dx
call readsect
xor bx,bx
l_1: mov di,bx ; set address to check from
mov cx,11 ; check 11 bytes
mov si,FileName ; address of string to check with
repz cmpsb
je foundit
add bx,32 ; check next entry
cmp bx,[bsSectSize] ; end of sector?
je l_2
jmp l_1
l_2: pop dx ; restore registers
pop es
pop ax
pop cx
inc ax ; read next sector
loopnz r1
jmp bootfail
foundit: pop dx ; get these off the stack
pop es
pop ax
pop cx

mov di,0x1A ; get clustor #
add di,bx
push bx ; save bx for finding # of sectors
mov ax,[es:di]
xor bx,bx ; calculate sector #
mov bl,[bsClustSize]
mul bx ; ax holds sector #
mov word [bsVolID],ax

pop bx ; get location of directory entry
mov di,0x1C
add di,bx
mov ax,[es:di] ; put number of bytes in ax
xor dx,dx
mov bx,[bsClustSize] ; # of bytes / 512
div bx
inc ax
mov word [bsVolID+2],ax ; save number of sectors to load

pop di ; restore registers
pop si
pop dx
pop cx
pop bx
pop ax

ret ; return to caller

putstr: ; SI = address of string to display
lodsb
or al,al
jz short putstrd
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp putstr
putstrd: retn ; return to caller

bootfail: ; display failure message
mov si,MsgBad ; display error message
call putstr
xor ax,ax ; wait for keypress
int 0x16
int 0x19 ; reboot

readsect: ; ES:BX = Location ; AX = Sector
mov si,[bsTrackSect]
div si ; divide logical sect by track size
inc dl ; sector # begins at 1
mov [bsReserv],dl ; sector to read
xor dx,dx ; logical track left in ax
div word [bsHeadCnt] ; leaves head in dl, cyl in ax
mov dh, [bsBootDrv] ;
xchg dl,dh ; head to dh, drive to dl
mov cx,ax ; cyl to cx
xchg cl,ch ; low 8 bits of cyl to ch, hi 2 bits
shl cl,6 ; shifted to bits 6 and 7
or cl, byte [bsReserv] ; or with sector number
mov al,1 ; number of sectors
mov ah,2 ; use read function of int 0x13
int 0x13 ; read sector
jc bootfail ; display error message
ret ; return to caller

padding times 45 db 0
FileName db "OSLOADERCOM"
MsgBad db " OSLOADER.COM is missing.",13,10,0
MsgDot db ".",0
MsgLoad db "SerpentOS Loading...",0
BootSig db 0x55, 0xAA

For some reason it only shows "Serp." when it gets to MsgLoad, but that isn't my primary concern...

OSLOADER.COM is the following in assembly, and is copied to the disk by just copy-pasting:

MOV AH, 02h ; read function.
MOV AL, 2 ; sectors to read.
MOV CH, 0 ; cylinder.
MOV CL, 16 ; sector.
MOV DH, 0 ; head.
MOV BX, 0800h
MOV ES, BX
MOV BX, 0
INT 13h
CALL 0800h:0000h

I currently have it set up just to read the calculator program instead of presenting a menu, but it should test well enough.

The calculator (calc.com) is written at cyl 0, head 0, track 0, sector 16. Its code is unimportant, as I didn't write it, and I've tested it to see that it works.

Anyways, as I said, it shows the bootloader's "SerpentOS Loading..." message, but mangled to be "Serp.". It then hangs. Any errors or fixes or help? >.<

 
My assembler is very rusty and was based mainly on MASM - in that I would have used either:

LEA SI, MsgLoad
or MOV SI, Offset MsgLoad

I'm not sure what difference that would make if any.

 
Well, I tried LEA SI, MsgLoad and it didn't even compile properly.. Maybe you misread, but the bootloader says "Compile in NASM", you use MASM. Big difference in syntax across TASM/NASM/MASM... Also, in the second one: MOV SI, OFFSET MsgLoad, what do I put for offset? Would it be something like MOV SI, 8+MsgLoad??

[Again I still need help getting calc.com to run, this isn't my primary problem, I know that the bootloader works properly..]
 
I know that the problem lies in the OSLOADER.COM code, btw... The bootloader works fine, and the calculator works fine. It is possible that SecWrite is the problem, or how I'm using it, but it appears to write fine...
 
Another way I could take this OS is to pass control off to a C/C++ kernel.. I am better with high level languages, though I'm rusty on C. Anyhow, does anyone know how to load up a C file and pass control? (I think that this would require almost the exact same code, just the executing part would be different..)
 
Now that I recall (sorry for posting so much rapidly, but we don't have edit here...), C++ compiles to exe with the compiler that I have, so I'd have to know how to run exe from ASM... (which I'm aware is even more complex...)
 
Anyways, as I said, it shows the bootloader's "SerpentOS Loading..." message, but mangled to be "Serp.". It then hangs. Any errors or fixes or help?

If DS:SI are pointing to the correct address, INT 10h, function 0Eh displays the character in AL, your code tests AL for 0, which you use as you get out test, your message should display correctly - which is why I thought the problem must lie somewhere there.

I noticed that you are not using MASM, which is why I drew your attention to the fact that my experience was in MASM and that there may be syntactic differences - although its 8 to 10 years since I last did any serious assembler programming.

MOV SI, OFFSET MsgLoad is exactly what I would type for MASM, which would calculate the address. I'm surprised that LEA didn't work - I nearly always used it in these circumstances.
 
It said that LEA SI, MsgLoad didn't have the proper number of arguments. I will try MOV SI, OFFSET MsgLoad, and then if you haven't posted, check the reference I have for LEA's arguments.
 
MOV SI, OFFSET MsgLoad says comma or end of line expected upon attempts to compile, I am going to try

MOV SI, OFFSET, MsgLoad and see if that works...
 
It says that OFFSET is undefined, which I assume means that it was a MASM specific variable..
 
serpent.asm:57: invalid combination of opcode and operands

This is exactly what I get when I compile with LEA SI, MsgLoad
 
Try square brackets around MsgLoad ie LEA SI, [MsgLoad]

otherwise I'm afraid I'll have to leave you to someone else, as I said, my assembler skills are so rusty that I would probably be more of a hinderance than a help.
 
YES! Well, that one compiled! I'm going to go test it!
 
It works just as well as MOV did, but one less letter >.< I'm going to try another (probably more recent) version of NASM I have...
 
When compiling with the newer NASM it gave me Serpe. instead of Ser. or Serp.

It seems to always add that period at the end. I did not write that bootloader, so perhaps there was some message-specific coding, such as message size or something? The original message was "doors loading"... I am going to change ""SerpentOS Loading...",0" to "SerpentOS Loading...0
 
0 inside quotes has a value of 48 decimal and will not be picked up by OR AL, AL (your end of string test)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top