Problem with simple OS scheduler in Assembly under Bochs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Locked
nnn123
Posts: 3
Joined: Sun Dec 02, 2012 4:00 pm

Problem with simple OS scheduler in Assembly under Bochs

Post by nnn123 »

Hello everyone,
let me start by saying that i'm an assembly newbie,
i was given the task to write an round-robin scheduler for a simple OS running in BOCHS
but when i try to register the interrupt service routine to count the ticks
(interrupt 0x1C vector, address 0x0070)
bochs throws me the following error twice and my OS freezes
"[CPU0 ] LOCK prefix unallowed (op1=0x53, modrm=0x00)"

here is the code for the kernel
only the "_scheduleprogram", "_startRoundRobinScheduler" and everything after "_trapISRA" is written by me

i have no clue what is going wrong, please help [-o<

thanks.

P.S. the os runs in 16-bits, very DOS like and uses segmented memory model

Code: Select all


.global _interrupt
.global _loadbuffer
.global _scheduleprogram
.global _run
.global _registerTrapISR
.global _startRoundRobinScheduler
.global _setKernelMode
.global _exitKernelMode
.extern _trapISRC
;.extern _trapClockISRC

KCLOCKTICKS	equ	100		

_setKernelMode:	; we also need to save the BP and SP of the calling proc and restore the BP and SP of the kernel
	pop bx	;load the BX of the calling proc
	push ds	;segment of the calling proc
	push bx 
	mov ax,#0x1000
	mov ds,ax
	ret

;restores the data segment
_exitKernelMode:
	pop bx
	pop ds
	push bx
	ret


_interrupt:
	push bp
	mov bp,sp
	mov ax,[bp+4]	;get the interrupt number in AL
	push ds		;use self-modifying code to call the right interrupt
	mov bx,cs
	mov ds,bx
	mov si,#intr
	mov [si+1],al	;change the 00 below to the contents of AL
	pop ds
	mov ax,[bp+6]	;get the other parameters AX, BX, CX, and DX
	mov bx,[bp+8]
	mov cx,[bp+10]
	mov dx,[bp+12]

intr:	int #0x00	;call the interrupt (00 will be changed above)

	mov ah,#0	;we only want AL returned
	pop bp
	ret



;this loads a new program but doesn't start it running
;the scheduler will take care of that
;the program will be located at the beginning of the segment at [sp+2]
;the filebuffer is located in the current segment at [sp+4]
;the number of bytes is located at [sp+6]
_loadbuffer:
	;bx=new segment
	;cx=length
	;si=buffer
	;di=new location
	push bp
	push es
	;; xchg bx, bx ;; bochs magic breakpoint, commented out to disable
	mov bp, sp
	mov es, [bp+6] ;; es = new segment
	mov si, [bp+8] ;; si = buffer
	mov cx, [bp+10] ;; cx = length
	mov di, #0 ;; di = 0 (so you get ES:0000 to start with)
	xferloop:
	cmp cx, #0
	je xferdone
	movsb ;; ES:[DI++] = DS:[SI++], to mix C and assembly
	dec cx
	jmp xferloop
	xferdone:
	pop es
	pop bp
	ret


; parameters : the program number (0-7), the program segment address. both are WORD (2 bytes) size
_scheduleprogram:
	push bp
	push ax

	xchg bx, bx ;; bochs magic breakpoint, commented out to disable
	mov bp, sp
	mov si, [bp+6] ;; si = program number
	and si,7 ; (8-1), essentially performs mod 8
	shl si,1 ; multiplication by 2
	
	mov di,storedCS
	add di,si
	mov ax,[bp+8]
	mov [di],ax ; segment address
	mov di,storedIP
	add di,si
	mov ax,0
	mov [di],ax
	mov di,storedSP
	add di,si
	mov ax,#0xfff0
	mov [di],ax
	mov di,storedBP
	add di,si
	mov ax,#0xfff0
	mov [di],ax
	
	pop ax
	pop bp
	ret

;this launches a new program
;the number of bytes is located at [sp+6]
;the filebuffer is located in the current segment at [sp+4]
;the program will be located at the beginning of the segment at [sp+2]
_run:
	mov bp,sp
	mov bx,[bp+2]	;get the segment into bx

	mov ax,cs	;modify the jmp below to jump to our segment. Put the current instruction Code Segment (CS) into AX
	mov ds,ax	;this is self-modifying code
	mov si,#jump
	mov [si+3],bx	;change the first 0000 to the segment

	mov ds,bx	;set up the segment registers
	mov ss,bx
	mov es,bx

	mov sp,#0xfff0	;set up the stack pointer
	mov bp,#0xfff0

jump:	jmp #0x0000:0x0000	;and start running (the first 0000 is changed above)

_registerTrapISR:
	;get the address of the service routine
	mov dx,#_trapISRA
	push ds
	mov ax, #0	;interrupts are in lowest memory
	mov ds,ax
	mov si,#0x84	;interrupt 0x21 vector (21 * 4 = 84)
	mov ax,cs	;have interrupt go to the current segment
	mov [si+2],ax
	mov [si],dx	;set up our vector
	pop ds
	ret
	
_startRoundRobinScheduler:

	;xchg bx, bx ;; bochs magic breakpoint, commented out to disable

	;get the address of the service routine
	mov dx,#_trapClockTickISRA
	push ds
	mov ax, #0	;interrupts are in lowest memory
	mov ds,ax
	mov si,#0x70	;interrupt 0x1C vector (address 0x0070)
	mov ax,cs	;have interrupt go to the current segment
	mov [si+2],ax
	mov [si],dx	;set up our vector
	pop ds	
	ret

;this is called when interrupt 21 happens
;it will call your function:
;void handleInterrupt21 (int AX, int BX, int CX, int DX)
_trapISRA:
	push dx	; save dx, cx, bx, ax into the stack
	push cx
	push bx
	push ax
	call _trapISRC	; call the interrupt handler
	pop ax	; restore the ax, bx, cx, dx from the stack
	pop bx
	pop cx
	pop dx

	iret
	

;this is called when interrupt 1C happens
;it will call your function:
;void handleInterrupt21 (int AX, int BX, int CX, int DX)
_trapClockTickISRA:
	;push cx
	inc [clockCounter]
	mov si,KCLOCKTICKS
	push ax
	mov ah,0
	mov al,BYTE PTR [clockCounter]
	cmp ax,si
	pop ax
	
	jge	doSwitchTask 
	iret
	
doSwitchTask:
	
	push bp
	mov bp,sp
	push ax
	
	mov al,0
	mov BYTE PTR [clockCounter],al
	;mov [callerBP],bp
	;mov [callerSP],sp
	
	mov ah,0
	mov al,BYTE PTR [currentProg]
	mov si,ax
	shl si,1	; multiply by 2
	
	mov di,storedFlags
	add di,si
	mov ax,[bp+10]
	mov [di],ax
	mov di,storedCS
	add di,si
	mov ax,[bp+8]
	mov [di],ax
	mov di,storedIP
	add di,si
	mov ax,[bp+6]
	mov [di],ax
	mov di,storedSP
	add di,si
	mov ax,[bp+4]
	mov [di],ax
	mov di,storedBP
	add di,si
	mov ax,[bp+2]
	mov [di],ax
	mov di,storedAX
	add di,si
	mov ax,[bp]
	mov [di],ax
	mov di,storedBX
	add di,si
	mov [di],bx
	mov di,storedCX
	add di,si
	mov [di],cx	;[sp]	
	mov di,storedDX
	add di,si
	mov [di],dx
	
	schedLoop:	; loop until it finds a non-zero [storedCS] entry
	add si,2 ; 1*2
	and si,14 ; (8-1)*2. essentially performs a mod 8
	mov di,storedCS
	add di,si
	mov ax,0
	cmp [di],ax
	je schedLoop	;	continue loop, if the entry is zero

switchToProgram:
	mov ax,si
	mov BYTE PTR [currentProg],al
	
	pop ax 	; pop AX
	pop dx 	; pop BP
	pop dx	; pop the IP register
	pop dx	; pop the CS register
	popf	; pop the flags register
	
	mov di,storedCS
	add di,si
	mov ds,[di]	;set up the segment registers
	mov ss,[di]
	mov es,[di]

	mov di,storedSP
	add di,si
	mov sp,[di]	;set up the stack pointer
	mov di,storedBP
	add di,si
	mov bp,[di]
	
	mov di,storedAX
	add di,si
	mov ax,[di]	; restore the general purpose registers
	mov di,storedBX
	add di,si
	mov bx,[di]
	mov di,storedCX
	add di,si
	mov cx,[di]
	mov di,storedDX
	add di,si
	mov dx,[di]
	
	mov di,storedFlags
	add di,si
	push [di]	; push the correct parameter on stack for 'iret' to work
	mov di,storedCS
	add di,si
	push [di]
	mov di,storedIP
	add di,si
	push [di]
	iret
	
clockCounter: db 0
currentProg: db 0
storedAX: dw 0,0,0,0,0,0,0,0
storedBX: dw 0,0,0,0,0,0,0,0
storedCX: dw 0,0,0,0,0,0,0,0
storedDX: dw 0,0,0,0,0,0,0,0
storedSP:	dw 0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0
storedBP:	dw 0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0
storedCS:	dw 0,0,0,0,0,0,0,0
storedIP:	dw 0,0,0,0,0,0,0,0
storedFlags:	dw 0,0,0,0,0,0,0,0
kernelBP:	dw 0
kernelSP:	dw 0
callerBP:	dw 0xfff0
callerSP:	dw 0xfff0

User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: Problem with simple OS scheduler in Assembly under Bochs

Post by dozniak »

LOCK prefix unallowed (op1=0x53, modrm=0x00)
Looks like it jumps to address 0.
Learn to read.
nnn123
Posts: 3
Joined: Sun Dec 02, 2012 4:00 pm

Re: Problem with simple OS scheduler in Assembly under Bochs

Post by nnn123 »

how can i fix it?
i'm clueless here
any help will be greatly appreciated
thanks
nnn123
Posts: 3
Joined: Sun Dec 02, 2012 4:00 pm

Re: Problem with simple OS scheduler in Assembly under Bochs

Post by nnn123 »

please help
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Problem with simple OS scheduler in Assembly under Bochs

Post by xenos »

Have you tried single-stepping or actually debugging your code?
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Locked