Thanks! I will check these basic things again and go back to the program.
actually, I used ljmp $(0x8000>>4),$0x00 to jump here(I loaded the boot at 0x8000 by using int $0x13). I think it should be a physical address. Here is the sector boot code:
Code: Select all
/* This is the boot loader of nosdl (Network Operating System Developed by Ley);
* The boot starts at 0x7c00;
*/
#define STACKSEG 0x7bff /* Use 0x0000 - 0x7bff as our stack; 31k; */
#define BOOTSEG 0x7c00 /* Bios read boot here; 1k; */
#define KERNELSEG 0x8000 /* Kernel load here; */
#define TEMPSEG 0X9000 /* Store data temprary; */
#define DISK_SPC 0x12 /* Sectors per track; Since we use ext2; */
#define BLK_SIZE 0x400 /* ext2 default block size; */
#define GI_OFF 0x08 /* Offset of inode table bitmap in group block; */
#define IR_OFF 0x80 /* Root offset of inode; */
#define ID_OFF 0x28 /* Offset of data block in inode; */
#define DNS_OFF 0x06 /* Offset of length of filename in directory; */
#define DN_OFF 0x08 /* Offset of filename in diectory; */
/* Functions; */
.type __calchs,@function
.type __diskread,@function
.type __putstr,@function
.type __putchr,@function
/* #define putc(c) pushw %ax; pushw %bx; mov $c,%al; call __putchr; popw %bx; popw %bx */
#define puts(s,l) pushl %ebp; pushl %ecx; movl $s,%ebp; movl $l,%ecx; call __putstr; inc %dh; popl %ecx; popl %ebp
#define setcur(r,c) mov $r,%dh; mov $c,%dl
.text
.code16
.globl _start
jmp _start
nop
VERSION:.word 0x0001 /* Boot Loader version; */
SIGNATURE:.ascii "nosl" /* Signature of loader, must be 4 letters; */
SYSTEM_START:.4byte 0x00001000 /* The address where system start; */
_start:
jmp __main
__main:
/* Init stack; */
xorl %eax,%eax
movw %ax,%ss
movl $STACKSEG,%esp
movl %esp,%ebp
/* %dh - currenct row; %dl -current column;
* %dh will be increased automatically by calling puts;
*/
/* Reset cursor; */
setcur(0,0)
puts(banner,banner_size)
/* Read Group description block; */
xorl %eax,%eax
mov $0x04,%al
call __calchs
mov $0x01,%al
movw $KERNELSEG,%bx
call __diskread
jc __rderror
xorl %eax,%eax
movl (KERNELSEG+GI_OFF),%eax /* Inode bittmap; */
imul $0x02,%eax
/* Get directory; */
call __calchs
movw $TEMPSEG,%bx
mov $0x04,%al
call __diskread
jc __rderror
movl (TEMPSEG+IR_OFF+ID_OFF),%eax /* Root directory; */
imul $0x02,%eax
call __calchs
mov $0x01,%al
movw $KERNELSEG,%bx
call __diskread
jc __rderror
xorl %ecx,%ecx
movl $KERNELSEG,%ecx
__findboot:
xorl %eax,%eax
mov DNS_OFF(%ecx),%al
cmp $boot_fn_size,%al
jne __findgoon
__cmpname:
movl %ecx,%eax
addl $DN_OFF,%eax
movl $boot_file,%ebx
call __cmpstr
cmp $0x00,%al
je __found
xorl %eax,%eax
movl $boot_fn_size,%eax
__findgoon:
__extpn: /* Extend pointer until %al%4 is 0; */
pushl %eax
mov $0x04,%bl
div %bl
cmp $0x00,%ah
jne __extgoon
popl %eax
addl %eax,%ecx
addl $DN_OFF,%ecx
cmpl $(KERNELSEG+0x400),%ecx /* Find filename in 1k; */
jb __findboot
__notfound:
puts(boot_not_found,bn_size)
jmp __boot_failed
__extgoon:
popl %eax
inc %al
jmp __extpn
__found:
/* Save file inode offset; */
movl (%ecx),%eax
movl %eax,BOOT_OFF
/* Get file inode; */
xorl %ecx,%ecx
movl $TEMPSEG,%ecx
subl $0x01,%eax
imul $IR_OFF,%eax
addl %eax,%ecx
xorl %eax,%eax
movl ID_OFF(%ecx),%eax
imul $0x02,%eax
call __calchs
mov $0x10,%al
movw $KERNELSEG,%bx
call __diskread
jc __rderror
/* Load kernel;
* Real mode addressing;
*/
ljmp $(KERNELSEG>>4),$0x0000
jmp .
__rderror:
puts(rd_err,rd_err_size)
jmp __boot_failed
__boot_failed:
puts(fail_str,fail_size)
jmp .
/* Calculate CHS from %ax;
* This function prepared CHS for int 0x13, ah=0x02;
* It will modify %ax,%cx,%dx;
*/
__calchs:
pushl %ebx
xorl %ebx,%ebx
mov $DISK_SPC,%bl
div %bl
inc %ah
mov %ah,%cl
mov %al,%dh
and $0x01,%dh
shr $0x01,%al
mov %al,%ch
popl %ebx
ret
/* Load disk into memory;
*/
__diskread:
mov $0x00,%dl /* Floopy disk; */
mov $0x02,%ah
int $0x13
ret
/* Print string;
* %dh - row, %dl - column;
* when null return;
*/
__putstr:
movl $0x000f,%ebx
movl $0x1301,%eax
int $0x10
ret
/* Output a character
* from %al;
*/
/* __putchr:
xorw %bx,%bx
mov $0x0e,%ah
int $0x10
ret */
/* Compare string from %ax and %bx;
* return %al, 0: equal; >0: %ax is great than %bx; <0: %ax is less than %bx;
*/
__cmpstr:
pushl %edi
pushl %esi
movl %eax,%esi
movl %ebx,%edi
__cmpstart:
mov (%esi),%al
mov (%edi),%bl
cmp $0x00,%al
je __equal
cmp %al,%bl
jg __bigthan
jb __lessthan
incl %edi
incl %esi
jmp __cmpstart
__bigthan:
mov $0x01,%ax
jmp __cmpret
__lessthan:
mov $-1,%al
jmp __cmpret
__equal:
mov $0x00,%al
jmp __cmpret
__cmpret:
popl %edi
popl %esi
ret
BOOT_OFF:.4byte 0
banner_start:
banner:.ascii "boot>"
banner_end:
.set banner_size, banner_end-banner_start
fail_start:
fail_str:.ascii "Boot failed."
fail_end:
.set fail_size, fail_end-fail_start
rd_err_start:
rd_err:.ascii "Disk error."
rd_err_end:
.set rd_err_size, rd_err_end-rd_err_start
boot_file_start:
boot_file:.ascii "boot"
boot_file_end:
.set boot_fn_size, boot_file_end-boot_file_start
bn_start:
boot_not_found:.ascii "No kernel."
bn_end:
.set bn_size, bn_end-bn_start
.word 0xaa55